]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/builtins.c
Remove trailing white spaces.
[thirdparty/gcc.git] / gcc / builtins.c
CommitLineData
28f4ec01 1/* Expand builtin functions.
03cd8aba 2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
5f26a230 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
455f14dd 4 Free Software Foundation, Inc.
28f4ec01 5
1322177d 6This file is part of GCC.
28f4ec01 7
1322177d
LB
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
9dcd6f09 10Software Foundation; either version 3, or (at your option) any later
1322177d 11version.
28f4ec01 12
1322177d
LB
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.
28f4ec01
BS
17
18You should have received a copy of the GNU General Public License
9dcd6f09
NC
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
28f4ec01
BS
21
22#include "config.h"
23#include "system.h"
4977bab6
ZW
24#include "coretypes.h"
25#include "tm.h"
28f4ec01 26#include "machmode.h"
11ad4784 27#include "real.h"
28f4ec01
BS
28#include "rtl.h"
29#include "tree.h"
726a989a 30#include "gimple.h"
28f4ec01
BS
31#include "flags.h"
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "except.h"
35#include "function.h"
28f4ec01
BS
36#include "insn-config.h"
37#include "expr.h"
e78d8e51
ZW
38#include "optabs.h"
39#include "libfuncs.h"
28f4ec01
BS
40#include "recog.h"
41#include "output.h"
42#include "typeclass.h"
28f4ec01 43#include "toplev.h"
5f2d6cfa 44#include "predict.h"
aa388f29 45#include "tm_p.h"
f6155fda 46#include "target.h"
ab393bf1 47#include "langhooks.h"
242229bb 48#include "basic-block.h"
faaaf610 49#include "tree-mudflap.h"
a1da787d 50#include "tree-flow.h"
079a182e 51#include "value-prof.h"
1d8381f1 52#include "diagnostic.h"
28f4ec01 53
81f5094d
JJ
54#ifndef SLOW_UNALIGNED_ACCESS
55#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56#endif
57
5e4f6244
CP
58#ifndef PAD_VARARGS_DOWN
59#define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60#endif
c128599a
KG
61#ifdef HAVE_mpc
62static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
63#endif
5e4f6244 64
9df2c88c 65/* Define the names of the builtin function types and codes. */
fd05eb80 66const char *const built_in_class_names[4]
9df2c88c
RK
67 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
c6a912da 69#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
7e7e470f 70const char * built_in_names[(int) END_BUILTINS] =
cb1072f4
KG
71{
72#include "builtins.def"
73};
74#undef DEF_BUILTIN
9df2c88c 75
3ff5f682
KG
76/* Setup an array of _DECL trees, make sure each element is
77 initialized to NULL_TREE. */
10841285 78tree built_in_decls[(int) END_BUILTINS];
272f51a3
JH
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
6de9cd9a 81 required to implement the function call in all cases). */
272f51a3 82tree implicit_built_in_decls[(int) END_BUILTINS];
3ff5f682 83
4682ae04
AJ
84static const char *c_getstr (tree);
85static rtx c_readstr (const char *, enum machine_mode);
86static int target_char_cast (tree, char *);
435bb2a1 87static rtx get_memory_rtx (tree, tree);
4682ae04
AJ
88static int apply_args_size (void);
89static int apply_result_size (void);
7bdb32b9 90#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
4682ae04 91static rtx result_vector (int, rtx);
7bdb32b9 92#endif
2b92e7f5 93static void expand_builtin_update_setjmp_buf (rtx);
4682ae04
AJ
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);
6c7cf1f0 104static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
eaee4464 105static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
403e54f0 106static rtx expand_builtin_sincos (tree);
75c7c595 107static rtx expand_builtin_cexpi (tree, rtx, rtx);
1856c8dc
JH
108static rtx expand_builtin_int_roundingfn (tree, rtx);
109static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
4682ae04 110static rtx expand_builtin_args_info (tree);
8870e212 111static rtx expand_builtin_next_arg (void);
4682ae04
AJ
112static rtx expand_builtin_va_start (tree);
113static rtx expand_builtin_va_end (tree);
114static rtx expand_builtin_va_copy (tree);
5039610b 115static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
44e10129 116static rtx expand_builtin_strcmp (tree, rtx);
4682ae04
AJ
117static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
118static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
44e10129 119static rtx expand_builtin_memcpy (tree, rtx);
5039610b 120static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
b8698a0f 121static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
5039610b 122 enum machine_mode, int);
44e10129
MM
123static rtx expand_builtin_strcpy (tree, rtx);
124static rtx expand_builtin_strcpy_args (tree, tree, rtx);
4682ae04 125static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
44e10129 126static rtx expand_builtin_strncpy (tree, rtx);
4682ae04 127static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
5039610b
SL
128static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
129static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
4682ae04
AJ
130static rtx expand_builtin_bzero (tree);
131static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
4682ae04
AJ
132static rtx expand_builtin_alloca (tree, rtx);
133static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
134static rtx expand_builtin_frame_address (tree, tree);
868b8cda
RS
135static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
8e0952f0 137static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
db3927fb 138static tree stabilize_va_list_loc (location_t, tree, int);
4682ae04
AJ
139static rtx expand_builtin_expect (tree, rtx);
140static tree fold_builtin_constant_p (tree);
db3927fb 141static tree fold_builtin_expect (location_t, tree, tree);
4682ae04 142static tree fold_builtin_classify_type (tree);
db3927fb
AH
143static tree fold_builtin_strlen (location_t, tree);
144static tree fold_builtin_inf (location_t, tree, int);
4682ae04 145static tree fold_builtin_nan (tree, tree, int);
db3927fb 146static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
fa233e34 147static bool validate_arg (const_tree, enum tree_code code);
0a9530a9 148static bool integer_valued_real_p (tree);
db3927fb 149static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
4682ae04
AJ
150static bool readonly_data_expr (tree);
151static rtx expand_builtin_fabs (tree, rtx, rtx);
ef79730c 152static rtx expand_builtin_signbit (tree, rtx);
db3927fb
AH
153static tree fold_builtin_sqrt (location_t, tree, tree);
154static tree fold_builtin_cbrt (location_t, tree, tree);
155static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
156static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
157static tree fold_builtin_cos (location_t, tree, tree, tree);
158static tree fold_builtin_cosh (location_t, tree, tree, tree);
1f3f1f68 159static tree fold_builtin_tan (tree, tree);
db3927fb
AH
160static tree fold_builtin_trunc (location_t, tree, tree);
161static tree fold_builtin_floor (location_t, tree, tree);
162static tree fold_builtin_ceil (location_t, tree, tree);
163static tree fold_builtin_round (location_t, tree, tree);
164static tree fold_builtin_int_roundingfn (location_t, tree, tree);
61f0284e 165static tree fold_builtin_bitop (tree, tree);
db3927fb
AH
166static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
167static tree fold_builtin_strchr (location_t, tree, tree, tree);
168static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
169static tree fold_builtin_memcmp (location_t, tree, tree, tree);
170static tree fold_builtin_strcmp (location_t, tree, tree);
171static tree fold_builtin_strncmp (location_t, tree, tree, tree);
172static tree fold_builtin_signbit (location_t, tree, tree);
173static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
174static tree fold_builtin_isascii (location_t, tree);
175static tree fold_builtin_toascii (location_t, tree);
176static tree fold_builtin_isdigit (location_t, tree);
177static tree fold_builtin_fabs (location_t, tree, tree);
178static tree fold_builtin_abs (location_t, tree, tree);
179static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
a35da91f 180 enum tree_code);
db3927fb
AH
181static tree fold_builtin_n (location_t, tree, tree *, int, bool);
182static tree fold_builtin_0 (location_t, tree, bool);
183static tree fold_builtin_1 (location_t, tree, tree, bool);
184static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
185static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
186static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
187static tree fold_builtin_varargs (location_t, tree, tree, bool);
188
189static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
190static tree fold_builtin_strstr (location_t, tree, tree, tree);
191static tree fold_builtin_strrchr (location_t, tree, tree, tree);
192static tree fold_builtin_strcat (location_t, tree, tree);
193static tree fold_builtin_strncat (location_t, tree, tree, tree);
194static tree fold_builtin_strspn (location_t, tree, tree);
195static tree fold_builtin_strcspn (location_t, tree, tree);
196static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
6de9cd9a 197
10a0d495
JJ
198static rtx expand_builtin_object_size (tree);
199static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
200 enum built_in_function);
201static void maybe_emit_chk_warning (tree, enum built_in_function);
202static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
f9555f40 203static void maybe_emit_free_warning (tree);
5039610b 204static tree fold_builtin_object_size (tree, tree);
db3927fb
AH
205static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
206static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
207static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
208static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
209static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
5039610b 210 enum built_in_function);
000ba23d
KG
211static bool init_target_chars (void);
212
213static unsigned HOST_WIDE_INT target_newline;
214static unsigned HOST_WIDE_INT target_percent;
215static unsigned HOST_WIDE_INT target_c;
216static unsigned HOST_WIDE_INT target_s;
217static char target_percent_c[3];
218static char target_percent_s[3];
219static char target_percent_s_newline[4];
b53fed56
KG
220static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
221 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
4413d881
KG
222static tree do_mpfr_arg2 (tree, tree, tree,
223 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
e61e5ddc
KG
224static tree do_mpfr_arg3 (tree, tree, tree, tree,
225 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
b68bcfff 226static tree do_mpfr_sincos (tree, tree, tree);
550b3187
KG
227static tree do_mpfr_bessel_n (tree, tree, tree,
228 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
229 const REAL_VALUE_TYPE *, bool);
ea91f957 230static tree do_mpfr_remquo (tree, tree, tree);
752b7d38 231static tree do_mpfr_lgamma_r (tree, tree, tree);
10a0d495 232
d7f09764
DN
233/* Return true if NAME starts with __builtin_ or __sync_. */
234
bbf7ce11
RAE
235bool
236is_builtin_name (const char *name)
48ae6c13 237{
48ae6c13
RH
238 if (strncmp (name, "__builtin_", 10) == 0)
239 return true;
240 if (strncmp (name, "__sync_", 7) == 0)
241 return true;
242 return false;
243}
6de9cd9a 244
d7f09764
DN
245
246/* Return true if DECL is a function symbol representing a built-in. */
247
248bool
249is_builtin_fn (tree decl)
250{
251 return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
252}
253
254
bbf7ce11
RAE
255/* Return true if NODE should be considered for inline expansion regardless
256 of the optimization level. This means whenever a function is invoked with
257 its "internal" name, which normally contains the prefix "__builtin". */
258
259static bool
260called_as_built_in (tree node)
261{
262 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
263 we want the name used to call the function, not the name it
264 will have. */
265 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
266 return is_builtin_name (name);
267}
268
df96b059
JJ
269/* Return the alignment in bits of EXP, an object.
270 Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
271 guessed alignment e.g. from type alignment. */
272
273int
274get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
275{
276 unsigned int inner;
277
278 inner = max_align;
279 if (handled_component_p (exp))
280 {
281 HOST_WIDE_INT bitsize, bitpos;
282 tree offset;
b8698a0f 283 enum machine_mode mode;
df96b059
JJ
284 int unsignedp, volatilep;
285
286 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
287 &mode, &unsignedp, &volatilep, true);
288 if (bitpos)
289 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
290 while (offset)
291 {
292 tree next_offset;
293
294 if (TREE_CODE (offset) == PLUS_EXPR)
295 {
296 next_offset = TREE_OPERAND (offset, 0);
297 offset = TREE_OPERAND (offset, 1);
298 }
299 else
300 next_offset = NULL;
301 if (host_integerp (offset, 1))
302 {
303 /* Any overflow in calculating offset_bits won't change
304 the alignment. */
305 unsigned offset_bits
306 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
307
308 if (offset_bits)
309 inner = MIN (inner, (offset_bits & -offset_bits));
310 }
311 else if (TREE_CODE (offset) == MULT_EXPR
312 && host_integerp (TREE_OPERAND (offset, 1), 1))
313 {
314 /* Any overflow in calculating offset_factor won't change
315 the alignment. */
316 unsigned offset_factor
317 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
318 * BITS_PER_UNIT);
319
320 if (offset_factor)
321 inner = MIN (inner, (offset_factor & -offset_factor));
322 }
323 else
324 {
325 inner = MIN (inner, BITS_PER_UNIT);
326 break;
327 }
328 offset = next_offset;
329 }
330 }
331 if (DECL_P (exp))
332 align = MIN (inner, DECL_ALIGN (exp));
333#ifdef CONSTANT_ALIGNMENT
334 else if (CONSTANT_CLASS_P (exp))
335 align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
336#endif
337 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
338 || TREE_CODE (exp) == INDIRECT_REF)
339 align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
340 else
341 align = MIN (align, inner);
342 return MIN (align, max_align);
343}
344
b35c8160
JM
345/* Returns true iff we can trust that alignment information has been
346 calculated properly. */
347
348bool
349can_trust_pointer_alignment (void)
350{
351 /* We rely on TER to compute accurate alignment information. */
352 return (optimize && flag_tree_ter);
353}
354
28f4ec01
BS
355/* Return the alignment in bits of EXP, a pointer valued expression.
356 But don't return more than MAX_ALIGN no matter what.
357 The alignment returned is, by default, the alignment of the thing that
5197bd50 358 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
28f4ec01
BS
359
360 Otherwise, look at the expression to see if we can do better, i.e., if the
361 expression is actually pointing at an object whose alignment is tighter. */
362
34d85166 363int
4682ae04 364get_pointer_alignment (tree exp, unsigned int max_align)
28f4ec01 365{
5197bd50 366 unsigned int align, inner;
28f4ec01 367
b35c8160 368 if (!can_trust_pointer_alignment ())
af4a46a9
EB
369 return 0;
370
6026b73e
EB
371 if (!POINTER_TYPE_P (TREE_TYPE (exp)))
372 return 0;
373
28f4ec01
BS
374 align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
375 align = MIN (align, max_align);
376
377 while (1)
378 {
379 switch (TREE_CODE (exp))
380 {
1043771b 381 CASE_CONVERT:
28f4ec01 382 exp = TREE_OPERAND (exp, 0);
7b922122 383 if (! POINTER_TYPE_P (TREE_TYPE (exp)))
28f4ec01 384 return align;
19caa751 385
28f4ec01
BS
386 inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
387 align = MIN (inner, max_align);
388 break;
389
5be014d5 390 case POINTER_PLUS_EXPR:
28f4ec01
BS
391 /* If sum of pointer + int, restrict our maximum alignment to that
392 imposed by the integer. If not, we can't do any better than
393 ALIGN. */
19caa751 394 if (! host_integerp (TREE_OPERAND (exp, 1), 1))
28f4ec01
BS
395 return align;
396
0c237688
LB
397 while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
398 & (max_align / BITS_PER_UNIT - 1))
28f4ec01
BS
399 != 0)
400 max_align >>= 1;
401
402 exp = TREE_OPERAND (exp, 0);
403 break;
404
405 case ADDR_EXPR:
406 /* See what we are pointing at and look at its alignment. */
df96b059 407 return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
28f4ec01
BS
408
409 default:
410 return align;
411 }
412 }
413}
414
415/* Compute the length of a C string. TREE_STRING_LENGTH is not the right
416 way, because it could contain a zero byte in the middle.
417 TREE_STRING_LENGTH is the size of the character array, not the string.
418
f1ba665b 419 ONLY_VALUE should be nonzero if the result is not going to be emitted
88373ed0 420 into the instruction stream and zero if it is going to be expanded.
f1ba665b 421 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
ae808627
JJ
422 is returned, otherwise NULL, since
423 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
424 evaluate the side-effects.
425
fed3cef0
RK
426 The value returned is of type `ssizetype'.
427
28f4ec01
BS
428 Unfortunately, string_constant can't access the values of const char
429 arrays with initializers, so neither can we do so here. */
430
6de9cd9a 431tree
ae808627 432c_strlen (tree src, int only_value)
28f4ec01
BS
433{
434 tree offset_node;
5197bd50
RK
435 HOST_WIDE_INT offset;
436 int max;
520a57c8 437 const char *ptr;
28f4ec01 438
ae808627
JJ
439 STRIP_NOPS (src);
440 if (TREE_CODE (src) == COND_EXPR
441 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
442 {
443 tree len1, len2;
444
445 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
446 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
33521f7d 447 if (tree_int_cst_equal (len1, len2))
ae808627
JJ
448 return len1;
449 }
450
451 if (TREE_CODE (src) == COMPOUND_EXPR
452 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
453 return c_strlen (TREE_OPERAND (src, 1), only_value);
454
28f4ec01
BS
455 src = string_constant (src, &offset_node);
456 if (src == 0)
5039610b 457 return NULL_TREE;
fed3cef0 458
2dee4af1 459 max = TREE_STRING_LENGTH (src) - 1;
28f4ec01 460 ptr = TREE_STRING_POINTER (src);
fed3cef0 461
28f4ec01
BS
462 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
463 {
464 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
465 compute the offset to the following null if we don't know where to
466 start searching for it. */
467 int i;
fed3cef0 468
28f4ec01
BS
469 for (i = 0; i < max; i++)
470 if (ptr[i] == 0)
5039610b 471 return NULL_TREE;
fed3cef0 472
28f4ec01
BS
473 /* We don't know the starting offset, but we do know that the string
474 has no internal zero bytes. We can assume that the offset falls
475 within the bounds of the string; otherwise, the programmer deserves
476 what he gets. Subtract the offset from the length of the string,
fed3cef0
RK
477 and return that. This would perhaps not be valid if we were dealing
478 with named arrays in addition to literal string constants. */
479
db3927fb 480 return size_diffop_loc (input_location, size_int (max), offset_node);
28f4ec01
BS
481 }
482
483 /* We have a known offset into the string. Start searching there for
5197bd50 484 a null character if we can represent it as a single HOST_WIDE_INT. */
1de3d877 485 if (offset_node == 0)
28f4ec01 486 offset = 0;
1de3d877
MK
487 else if (! host_integerp (offset_node, 0))
488 offset = -1;
28f4ec01 489 else
5197bd50 490 offset = tree_low_cst (offset_node, 0);
fed3cef0 491
b2ed71b6
BE
492 /* If the offset is known to be out of bounds, warn, and call strlen at
493 runtime. */
28f4ec01
BS
494 if (offset < 0 || offset > max)
495 {
b2ed71b6
BE
496 /* Suppress multiple warnings for propagated constant strings. */
497 if (! TREE_NO_WARNING (src))
498 {
499 warning (0, "offset outside bounds of constant string");
500 TREE_NO_WARNING (src) = 1;
501 }
5039610b 502 return NULL_TREE;
28f4ec01 503 }
fed3cef0 504
28f4ec01
BS
505 /* Use strlen to search for the first zero byte. Since any strings
506 constructed with build_string will have nulls appended, we win even
507 if we get handed something like (char[4])"abcd".
508
509 Since OFFSET is our starting index into the string, no further
510 calculation is needed. */
fed3cef0 511 return ssize_int (strlen (ptr + offset));
28f4ec01
BS
512}
513
2dee4af1
JJ
514/* Return a char pointer for a C string if it is a string constant
515 or sum of string constant and integer constant. */
516
517static const char *
4682ae04 518c_getstr (tree src)
2dee4af1
JJ
519{
520 tree offset_node;
2dee4af1
JJ
521
522 src = string_constant (src, &offset_node);
523 if (src == 0)
524 return 0;
525
bf06b5d8
RK
526 if (offset_node == 0)
527 return TREE_STRING_POINTER (src);
528 else if (!host_integerp (offset_node, 1)
529 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
2dee4af1 530 return 0;
2dee4af1 531
bf06b5d8 532 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
2dee4af1
JJ
533}
534
bf06b5d8
RK
535/* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
536 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
ab937357 537
57814e5e 538static rtx
4682ae04 539c_readstr (const char *str, enum machine_mode mode)
57814e5e
JJ
540{
541 HOST_WIDE_INT c[2];
542 HOST_WIDE_INT ch;
543 unsigned int i, j;
544
298e6adc 545 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
5906d013 546
57814e5e
JJ
547 c[0] = 0;
548 c[1] = 0;
549 ch = 1;
550 for (i = 0; i < GET_MODE_SIZE (mode); i++)
551 {
552 j = i;
553 if (WORDS_BIG_ENDIAN)
554 j = GET_MODE_SIZE (mode) - i - 1;
555 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
556 && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
557 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
558 j *= BITS_PER_UNIT;
298e6adc 559 gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
5906d013 560
57814e5e
JJ
561 if (ch)
562 ch = (unsigned char) str[i];
563 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
564 }
565 return immed_double_const (c[0], c[1], mode);
566}
567
ab937357 568/* Cast a target constant CST to target CHAR and if that value fits into
206048bd 569 host char type, return zero and put that value into variable pointed to by
ab937357
JJ
570 P. */
571
572static int
4682ae04 573target_char_cast (tree cst, char *p)
ab937357
JJ
574{
575 unsigned HOST_WIDE_INT val, hostval;
576
5197bd50 577 if (!host_integerp (cst, 1)
ab937357
JJ
578 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
579 return 1;
580
5197bd50 581 val = tree_low_cst (cst, 1);
ab937357
JJ
582 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
583 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
584
585 hostval = val;
586 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
587 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
588
589 if (val != hostval)
590 return 1;
591
592 *p = hostval;
593 return 0;
594}
595
6de9cd9a
DN
596/* Similar to save_expr, but assumes that arbitrary code is not executed
597 in between the multiple evaluations. In particular, we assume that a
598 non-addressable local variable will not be modified. */
599
600static tree
601builtin_save_expr (tree exp)
602{
603 if (TREE_ADDRESSABLE (exp) == 0
604 && (TREE_CODE (exp) == PARM_DECL
605 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
606 return exp;
607
608 return save_expr (exp);
609}
610
28f4ec01
BS
611/* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
612 times to get the address of either a higher stack frame, or a return
613 address located within it (depending on FNDECL_CODE). */
fed3cef0 614
54e62799 615static rtx
c6d01079 616expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
28f4ec01
BS
617{
618 int i;
619
c6d01079
AK
620#ifdef INITIAL_FRAME_ADDRESS_RTX
621 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
622#else
c8f27794
JW
623 rtx tem;
624
dda69cbf
MS
625 /* For a zero count with __builtin_return_address, we don't care what
626 frame address we return, because target-specific definitions will
627 override us. Therefore frame pointer elimination is OK, and using
628 the soft frame pointer is OK.
629
2f8e468b 630 For a nonzero count, or a zero count with __builtin_frame_address,
dda69cbf
MS
631 we require a stable offset from the current frame pointer to the
632 previous one, so we must use the hard frame pointer, and
c8f27794 633 we must disable frame pointer elimination. */
dda69cbf 634 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
c8f27794 635 tem = frame_pointer_rtx;
c22cacf3 636 else
c8f27794
JW
637 {
638 tem = hard_frame_pointer_rtx;
639
640 /* Tell reload not to eliminate the frame pointer. */
e3b5732b 641 crtl->accesses_prior_frames = 1;
c8f27794 642 }
c6d01079
AK
643#endif
644
28f4ec01 645 /* Some machines need special handling before we can access
224869d9 646 arbitrary frames. For example, on the SPARC, we must first flush
28f4ec01
BS
647 all register windows to the stack. */
648#ifdef SETUP_FRAME_ADDRESSES
649 if (count > 0)
650 SETUP_FRAME_ADDRESSES ();
651#endif
652
224869d9 653 /* On the SPARC, the return address is not in the frame, it is in a
28f4ec01
BS
654 register. There is no way to access it off of the current frame
655 pointer, but it can be accessed off the previous frame pointer by
656 reading the value from the register window save area. */
657#ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
658 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
659 count--;
660#endif
661
662 /* Scan back COUNT frames to the specified frame. */
663 for (i = 0; i < count; i++)
664 {
665 /* Assume the dynamic chain pointer is in the word that the
666 frame address points to, unless otherwise specified. */
667#ifdef DYNAMIC_CHAIN_ADDRESS
668 tem = DYNAMIC_CHAIN_ADDRESS (tem);
669#endif
670 tem = memory_address (Pmode, tem);
bf877a76 671 tem = gen_frame_mem (Pmode, tem);
432fd734 672 tem = copy_to_reg (tem);
28f4ec01
BS
673 }
674
224869d9
EB
675 /* For __builtin_frame_address, return what we've got. But, on
676 the SPARC for example, we may have to add a bias. */
28f4ec01 677 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
224869d9
EB
678#ifdef FRAME_ADDR_RTX
679 return FRAME_ADDR_RTX (tem);
680#else
28f4ec01 681 return tem;
224869d9 682#endif
28f4ec01 683
224869d9 684 /* For __builtin_return_address, get the return address from that frame. */
28f4ec01
BS
685#ifdef RETURN_ADDR_RTX
686 tem = RETURN_ADDR_RTX (count, tem);
687#else
688 tem = memory_address (Pmode,
689 plus_constant (tem, GET_MODE_SIZE (Pmode)));
bf877a76 690 tem = gen_frame_mem (Pmode, tem);
28f4ec01
BS
691#endif
692 return tem;
693}
694
3bdf5ad1 695/* Alias set used for setjmp buffer. */
4862826d 696static alias_set_type setjmp_alias_set = -1;
3bdf5ad1 697
250d07b6 698/* Construct the leading half of a __builtin_setjmp call. Control will
4f6c2131
EB
699 return to RECEIVER_LABEL. This is also called directly by the SJLJ
700 exception handling code. */
28f4ec01 701
250d07b6 702void
4682ae04 703expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
28f4ec01 704{
28f4ec01 705 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
28f4ec01 706 rtx stack_save;
3bdf5ad1 707 rtx mem;
28f4ec01 708
3bdf5ad1
RK
709 if (setjmp_alias_set == -1)
710 setjmp_alias_set = new_alias_set ();
711
5ae6cd0d 712 buf_addr = convert_memory_address (Pmode, buf_addr);
28f4ec01 713
7d505b82 714 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
28f4ec01 715
250d07b6
RH
716 /* We store the frame pointer and the address of receiver_label in
717 the buffer and use the rest of it for the stack save area, which
718 is machine-dependent. */
28f4ec01 719
3bdf5ad1 720 mem = gen_rtx_MEM (Pmode, buf_addr);
ba4828e0 721 set_mem_alias_set (mem, setjmp_alias_set);
d6da68b9 722 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
3bdf5ad1
RK
723
724 mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
ba4828e0 725 set_mem_alias_set (mem, setjmp_alias_set);
3bdf5ad1
RK
726
727 emit_move_insn (validize_mem (mem),
250d07b6 728 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
28f4ec01
BS
729
730 stack_save = gen_rtx_MEM (sa_mode,
731 plus_constant (buf_addr,
732 2 * GET_MODE_SIZE (Pmode)));
ba4828e0 733 set_mem_alias_set (stack_save, setjmp_alias_set);
28f4ec01
BS
734 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
735
736 /* If there is further processing to do, do it. */
737#ifdef HAVE_builtin_setjmp_setup
738 if (HAVE_builtin_setjmp_setup)
739 emit_insn (gen_builtin_setjmp_setup (buf_addr));
740#endif
741
250d07b6
RH
742 /* Tell optimize_save_area_alloca that extra work is going to
743 need to go on during alloca. */
e3b5732b 744 cfun->calls_setjmp = 1;
dfb2c798 745
ecaebb9e 746 /* We have a nonlocal label. */
e3b5732b 747 cfun->has_nonlocal_label = 1;
250d07b6 748}
28f4ec01 749
4f6c2131
EB
750/* Construct the trailing part of a __builtin_setjmp call. This is
751 also called directly by the SJLJ exception handling code. */
250d07b6
RH
752
753void
4682ae04 754expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
250d07b6 755{
531ca746
RH
756 rtx chain;
757
28f4ec01
BS
758 /* Clobber the FP when we get here, so we have to make sure it's
759 marked as used by this function. */
c41c1387 760 emit_use (hard_frame_pointer_rtx);
28f4ec01
BS
761
762 /* Mark the static chain as clobbered here so life information
763 doesn't get messed up for it. */
531ca746
RH
764 chain = targetm.calls.static_chain (current_function_decl, true);
765 if (chain && REG_P (chain))
766 emit_clobber (chain);
28f4ec01
BS
767
768 /* Now put in the code to restore the frame pointer, and argument
caf93cb0 769 pointer, if needed. */
28f4ec01
BS
770#ifdef HAVE_nonlocal_goto
771 if (! HAVE_nonlocal_goto)
772#endif
f0119413
JM
773 {
774 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
775 /* This might change the hard frame pointer in ways that aren't
776 apparent to early optimization passes, so force a clobber. */
c41c1387 777 emit_clobber (hard_frame_pointer_rtx);
f0119413 778 }
28f4ec01
BS
779
780#if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
781 if (fixed_regs[ARG_POINTER_REGNUM])
782 {
783#ifdef ELIMINABLE_REGS
784 size_t i;
8b60264b 785 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
28f4ec01 786
b6a1cbae 787 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
28f4ec01
BS
788 if (elim_regs[i].from == ARG_POINTER_REGNUM
789 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
790 break;
791
b6a1cbae 792 if (i == ARRAY_SIZE (elim_regs))
28f4ec01
BS
793#endif
794 {
795 /* Now restore our arg pointer from the address at which it
278ed218 796 was saved in our stack frame. */
2e3f842f 797 emit_move_insn (crtl->args.internal_arg_pointer,
bd60bab2 798 copy_to_reg (get_arg_pointer_save_area ()));
28f4ec01
BS
799 }
800 }
801#endif
802
803#ifdef HAVE_builtin_setjmp_receiver
804 if (HAVE_builtin_setjmp_receiver)
250d07b6 805 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
28f4ec01
BS
806 else
807#endif
808#ifdef HAVE_nonlocal_goto_receiver
809 if (HAVE_nonlocal_goto_receiver)
810 emit_insn (gen_nonlocal_goto_receiver ());
811 else
812#endif
250d07b6 813 { /* Nothing */ }
bcd7edfe 814
6fb5fa3c
DB
815 /* We must not allow the code we just generated to be reordered by
816 scheduling. Specifically, the update of the frame pointer must
817 happen immediately, not later. */
818 emit_insn (gen_blockage ());
250d07b6 819}
28f4ec01 820
28f4ec01
BS
821/* __builtin_longjmp is passed a pointer to an array of five words (not
822 all will be used on all machines). It operates similarly to the C
823 library function of the same name, but is more efficient. Much of
4f6c2131 824 the code below is copied from the handling of non-local gotos. */
28f4ec01 825
54e62799 826static void
4682ae04 827expand_builtin_longjmp (rtx buf_addr, rtx value)
28f4ec01 828{
d337d653 829 rtx fp, lab, stack, insn, last;
28f4ec01
BS
830 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
831
b8698a0f 832 /* DRAP is needed for stack realign if longjmp is expanded to current
2e3f842f
L
833 function */
834 if (SUPPORTS_STACK_ALIGNMENT)
835 crtl->need_drap = true;
836
3bdf5ad1
RK
837 if (setjmp_alias_set == -1)
838 setjmp_alias_set = new_alias_set ();
839
5ae6cd0d 840 buf_addr = convert_memory_address (Pmode, buf_addr);
4b6c1672 841
28f4ec01
BS
842 buf_addr = force_reg (Pmode, buf_addr);
843
531ca746
RH
844 /* We require that the user must pass a second argument of 1, because
845 that is what builtin_setjmp will return. */
298e6adc 846 gcc_assert (value == const1_rtx);
28f4ec01 847
d337d653 848 last = get_last_insn ();
28f4ec01
BS
849#ifdef HAVE_builtin_longjmp
850 if (HAVE_builtin_longjmp)
851 emit_insn (gen_builtin_longjmp (buf_addr));
852 else
853#endif
854 {
855 fp = gen_rtx_MEM (Pmode, buf_addr);
856 lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
857 GET_MODE_SIZE (Pmode)));
858
859 stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
860 2 * GET_MODE_SIZE (Pmode)));
ba4828e0
RK
861 set_mem_alias_set (fp, setjmp_alias_set);
862 set_mem_alias_set (lab, setjmp_alias_set);
863 set_mem_alias_set (stack, setjmp_alias_set);
28f4ec01
BS
864
865 /* Pick up FP, label, and SP from the block and jump. This code is
866 from expand_goto in stmt.c; see there for detailed comments. */
3425c35f 867#ifdef HAVE_nonlocal_goto
28f4ec01
BS
868 if (HAVE_nonlocal_goto)
869 /* We have to pass a value to the nonlocal_goto pattern that will
870 get copied into the static_chain pointer, but it does not matter
871 what that value is, because builtin_setjmp does not use it. */
7c2b017c 872 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
28f4ec01
BS
873 else
874#endif
875 {
876 lab = copy_to_reg (lab);
877
c41c1387
RS
878 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
879 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
41439bf6 880
28f4ec01
BS
881 emit_move_insn (hard_frame_pointer_rtx, fp);
882 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
883
c41c1387
RS
884 emit_use (hard_frame_pointer_rtx);
885 emit_use (stack_pointer_rtx);
28f4ec01
BS
886 emit_indirect_jump (lab);
887 }
888 }
4b01bd16
RH
889
890 /* Search backwards and mark the jump insn as a non-local goto.
891 Note that this precludes the use of __builtin_longjmp to a
892 __builtin_setjmp target in the same function. However, we've
893 already cautioned the user that these functions are for
894 internal exception handling use only. */
8206fc89
AM
895 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
896 {
298e6adc 897 gcc_assert (insn != last);
5906d013 898
4b4bf941 899 if (JUMP_P (insn))
8206fc89 900 {
65c5f2a6 901 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
8206fc89
AM
902 break;
903 }
4b4bf941 904 else if (CALL_P (insn))
ca7fd9cd 905 break;
8206fc89 906 }
28f4ec01
BS
907}
908
6de9cd9a
DN
909/* Expand a call to __builtin_nonlocal_goto. We're passed the target label
910 and the address of the save area. */
911
912static rtx
5039610b 913expand_builtin_nonlocal_goto (tree exp)
6de9cd9a
DN
914{
915 tree t_label, t_save_area;
916 rtx r_label, r_save_area, r_fp, r_sp, insn;
917
5039610b 918 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6de9cd9a
DN
919 return NULL_RTX;
920
5039610b
SL
921 t_label = CALL_EXPR_ARG (exp, 0);
922 t_save_area = CALL_EXPR_ARG (exp, 1);
6de9cd9a 923
84217346 924 r_label = expand_normal (t_label);
5e89a381 925 r_label = convert_memory_address (Pmode, r_label);
84217346 926 r_save_area = expand_normal (t_save_area);
5e89a381 927 r_save_area = convert_memory_address (Pmode, r_save_area);
cba2d79f
AP
928 /* Copy the address of the save location to a register just in case it was based
929 on the frame pointer. */
930 r_save_area = copy_to_reg (r_save_area);
6de9cd9a
DN
931 r_fp = gen_rtx_MEM (Pmode, r_save_area);
932 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
933 plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
934
e3b5732b 935 crtl->has_nonlocal_goto = 1;
6de9cd9a 936
3425c35f 937#ifdef HAVE_nonlocal_goto
6de9cd9a
DN
938 /* ??? We no longer need to pass the static chain value, afaik. */
939 if (HAVE_nonlocal_goto)
940 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
941 else
942#endif
943 {
944 r_label = copy_to_reg (r_label);
945
c41c1387
RS
946 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
947 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
caf93cb0 948
6de9cd9a
DN
949 /* Restore frame pointer for containing function.
950 This sets the actual hard register used for the frame pointer
951 to the location of the function's incoming static chain info.
952 The non-local goto handler will then adjust it to contain the
953 proper value and reload the argument pointer, if needed. */
954 emit_move_insn (hard_frame_pointer_rtx, r_fp);
955 emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
caf93cb0 956
6de9cd9a
DN
957 /* USE of hard_frame_pointer_rtx added for consistency;
958 not clear if really needed. */
c41c1387
RS
959 emit_use (hard_frame_pointer_rtx);
960 emit_use (stack_pointer_rtx);
eae645b6
RS
961
962 /* If the architecture is using a GP register, we must
963 conservatively assume that the target function makes use of it.
964 The prologue of functions with nonlocal gotos must therefore
965 initialize the GP register to the appropriate value, and we
966 must then make sure that this value is live at the point
967 of the jump. (Note that this doesn't necessarily apply
968 to targets with a nonlocal_goto pattern; they are free
969 to implement it in their own way. Note also that this is
970 a no-op if the GP register is a global invariant.) */
971 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
972 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
c41c1387 973 emit_use (pic_offset_table_rtx);
eae645b6 974
6de9cd9a
DN
975 emit_indirect_jump (r_label);
976 }
caf93cb0 977
6de9cd9a
DN
978 /* Search backwards to the jump insn and mark it as a
979 non-local goto. */
980 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
981 {
4b4bf941 982 if (JUMP_P (insn))
6de9cd9a 983 {
65c5f2a6 984 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
6de9cd9a
DN
985 break;
986 }
4b4bf941 987 else if (CALL_P (insn))
6de9cd9a
DN
988 break;
989 }
990
991 return const0_rtx;
992}
993
2b92e7f5
RK
994/* __builtin_update_setjmp_buf is passed a pointer to an array of five words
995 (not all will be used on all machines) that was passed to __builtin_setjmp.
996 It updates the stack pointer in that block to correspond to the current
997 stack pointer. */
998
999static void
1000expand_builtin_update_setjmp_buf (rtx buf_addr)
1001{
1002 enum machine_mode sa_mode = Pmode;
1003 rtx stack_save;
1004
1005
1006#ifdef HAVE_save_stack_nonlocal
1007 if (HAVE_save_stack_nonlocal)
1008 sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
1009#endif
1010#ifdef STACK_SAVEAREA_MODE
1011 sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1012#endif
1013
1014 stack_save
1015 = gen_rtx_MEM (sa_mode,
1016 memory_address
1017 (sa_mode,
1018 plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1019
1020#ifdef HAVE_setjmp
1021 if (HAVE_setjmp)
1022 emit_insn (gen_setjmp ());
1023#endif
1024
1025 emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1026}
1027
a9ccbb60
JJ
1028/* Expand a call to __builtin_prefetch. For a target that does not support
1029 data prefetch, evaluate the memory address argument in case it has side
1030 effects. */
1031
1032static void
5039610b 1033expand_builtin_prefetch (tree exp)
a9ccbb60
JJ
1034{
1035 tree arg0, arg1, arg2;
5039610b 1036 int nargs;
a9ccbb60
JJ
1037 rtx op0, op1, op2;
1038
5039610b 1039 if (!validate_arglist (exp, POINTER_TYPE, 0))
e83d297b
JJ
1040 return;
1041
5039610b
SL
1042 arg0 = CALL_EXPR_ARG (exp, 0);
1043
e83d297b
JJ
1044 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1045 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1046 locality). */
5039610b
SL
1047 nargs = call_expr_nargs (exp);
1048 if (nargs > 1)
1049 arg1 = CALL_EXPR_ARG (exp, 1);
e83d297b 1050 else
5039610b
SL
1051 arg1 = integer_zero_node;
1052 if (nargs > 2)
1053 arg2 = CALL_EXPR_ARG (exp, 2);
1054 else
1055 arg2 = build_int_cst (NULL_TREE, 3);
a9ccbb60
JJ
1056
1057 /* Argument 0 is an address. */
1058 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1059
1060 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1061 if (TREE_CODE (arg1) != INTEGER_CST)
1062 {
40b97a2e 1063 error ("second argument to %<__builtin_prefetch%> must be a constant");
ca7fd9cd 1064 arg1 = integer_zero_node;
a9ccbb60 1065 }
84217346 1066 op1 = expand_normal (arg1);
a9ccbb60
JJ
1067 /* Argument 1 must be either zero or one. */
1068 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1069 {
d4ee4d25 1070 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
40b97a2e 1071 " using zero");
a9ccbb60
JJ
1072 op1 = const0_rtx;
1073 }
1074
1075 /* Argument 2 (locality) must be a compile-time constant int. */
1076 if (TREE_CODE (arg2) != INTEGER_CST)
1077 {
40b97a2e 1078 error ("third argument to %<__builtin_prefetch%> must be a constant");
a9ccbb60
JJ
1079 arg2 = integer_zero_node;
1080 }
84217346 1081 op2 = expand_normal (arg2);
a9ccbb60
JJ
1082 /* Argument 2 must be 0, 1, 2, or 3. */
1083 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1084 {
d4ee4d25 1085 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
a9ccbb60
JJ
1086 op2 = const0_rtx;
1087 }
1088
1089#ifdef HAVE_prefetch
1090 if (HAVE_prefetch)
1091 {
5ab2f7b7 1092 if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1e533e4b 1093 (op0,
5ab2f7b7 1094 insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
868b8cda 1095 || (GET_MODE (op0) != Pmode))
ca7fd9cd 1096 {
5ae6cd0d 1097 op0 = convert_memory_address (Pmode, op0);
ca7fd9cd
KH
1098 op0 = force_reg (Pmode, op0);
1099 }
a9ccbb60
JJ
1100 emit_insn (gen_prefetch (op0, op1, op2));
1101 }
a9ccbb60 1102#endif
ad76cef8 1103
5ab2f7b7
KH
1104 /* Don't do anything with direct references to volatile memory, but
1105 generate code to handle other side effects. */
3c0cb5de 1106 if (!MEM_P (op0) && side_effects_p (op0))
5ab2f7b7 1107 emit_insn (op0);
a9ccbb60
JJ
1108}
1109
3bdf5ad1 1110/* Get a MEM rtx for expression EXP which is the address of an operand
435bb2a1
JJ
1111 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1112 the maximum length of the block of memory that might be accessed or
1113 NULL if unknown. */
3bdf5ad1 1114
28f4ec01 1115static rtx
435bb2a1 1116get_memory_rtx (tree exp, tree len)
28f4ec01 1117{
805903b5
JJ
1118 tree orig_exp = exp;
1119 rtx addr, mem;
1120 HOST_WIDE_INT off;
1121
1122 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1123 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1124 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1125 exp = TREE_OPERAND (exp, 0);
1126
1127 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1128 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
8ac61af7 1129
3bdf5ad1
RK
1130 /* Get an expression we can use to find the attributes to assign to MEM.
1131 If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if
1132 we can. First remove any nops. */
1043771b 1133 while (CONVERT_EXPR_P (exp)
3bdf5ad1
RK
1134 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1135 exp = TREE_OPERAND (exp, 0);
1136
805903b5
JJ
1137 off = 0;
1138 if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1139 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1140 && host_integerp (TREE_OPERAND (exp, 1), 0)
1141 && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1142 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1143 else if (TREE_CODE (exp) == ADDR_EXPR)
931e6c29 1144 exp = TREE_OPERAND (exp, 0);
3bdf5ad1 1145 else if (POINTER_TYPE_P (TREE_TYPE (exp)))
931e6c29
UW
1146 exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1147 else
1148 exp = NULL;
1149
1150 /* Honor attributes derived from exp, except for the alias set
1151 (as builtin stringops may alias with anything) and the size
1152 (as stringops may access multiple array elements). */
1153 if (exp)
343fb412 1154 {
931e6c29 1155 set_mem_attributes (mem, exp, 0);
435bb2a1 1156
805903b5
JJ
1157 if (off)
1158 mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1159
435bb2a1
JJ
1160 /* Allow the string and memory builtins to overflow from one
1161 field into another, see http://gcc.gnu.org/PR23561.
1162 Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1163 memory accessed by the string or memory builtin will fit
1164 within the field. */
1165 if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1166 {
1167 tree mem_expr = MEM_EXPR (mem);
1168 HOST_WIDE_INT offset = -1, length = -1;
1169 tree inner = exp;
1170
1171 while (TREE_CODE (inner) == ARRAY_REF
1043771b 1172 || CONVERT_EXPR_P (inner)
435bb2a1
JJ
1173 || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1174 || TREE_CODE (inner) == SAVE_EXPR)
1175 inner = TREE_OPERAND (inner, 0);
1176
1177 gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1178
1179 if (MEM_OFFSET (mem)
481683e1 1180 && CONST_INT_P (MEM_OFFSET (mem)))
435bb2a1
JJ
1181 offset = INTVAL (MEM_OFFSET (mem));
1182
1183 if (offset >= 0 && len && host_integerp (len, 0))
1184 length = tree_low_cst (len, 0);
1185
1186 while (TREE_CODE (inner) == COMPONENT_REF)
1187 {
1188 tree field = TREE_OPERAND (inner, 1);
435bb2a1
JJ
1189 gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1190 gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1191
056c8fae
EB
1192 /* Bitfields are generally not byte-addressable. */
1193 gcc_assert (!DECL_BIT_FIELD (field)
1194 || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1195 % BITS_PER_UNIT) == 0
1196 && host_integerp (DECL_SIZE (field), 0)
1197 && (TREE_INT_CST_LOW (DECL_SIZE (field))
1198 % BITS_PER_UNIT) == 0));
1199
9133c85e
EB
1200 /* If we can prove that the memory starting at XEXP (mem, 0) and
1201 ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1202 can keep the COMPONENT_REF in MEM_EXPR. But be careful with
1203 fields without DECL_SIZE_UNIT like flexible array members. */
435bb2a1 1204 if (length >= 0
9133c85e 1205 && DECL_SIZE_UNIT (field)
056c8fae 1206 && host_integerp (DECL_SIZE_UNIT (field), 0))
435bb2a1
JJ
1207 {
1208 HOST_WIDE_INT size
056c8fae 1209 = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
435bb2a1
JJ
1210 if (offset <= size
1211 && length <= size
1212 && offset + length <= size)
1213 break;
1214 }
1215
1216 if (offset >= 0
1217 && host_integerp (DECL_FIELD_OFFSET (field), 0))
056c8fae 1218 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
435bb2a1
JJ
1219 + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1220 / BITS_PER_UNIT;
1221 else
1222 {
1223 offset = -1;
1224 length = -1;
1225 }
1226
1227 mem_expr = TREE_OPERAND (mem_expr, 0);
1228 inner = TREE_OPERAND (inner, 0);
435bb2a1
JJ
1229 }
1230
1231 if (mem_expr == NULL)
1232 offset = -1;
1233 if (mem_expr != MEM_EXPR (mem))
1234 {
1235 set_mem_expr (mem, mem_expr);
1236 set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1237 }
1238 }
343fb412 1239 set_mem_alias_set (mem, 0);
931e6c29 1240 set_mem_size (mem, NULL_RTX);
343fb412 1241 }
28f4ec01 1242
28f4ec01
BS
1243 return mem;
1244}
1245\f
1246/* Built-in functions to perform an untyped call and return. */
1247
1248/* For each register that may be used for calling a function, this
1249 gives a mode used to copy the register's value. VOIDmode indicates
1250 the register is not used for calling a function. If the machine
1251 has register windows, this gives only the outbound registers.
1252 INCOMING_REGNO gives the corresponding inbound register. */
1253static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1254
1255/* For each register that may be used for returning values, this gives
1256 a mode used to copy the register's value. VOIDmode indicates the
1257 register is not used for returning values. If the machine has
1258 register windows, this gives only the outbound registers.
1259 INCOMING_REGNO gives the corresponding inbound register. */
1260static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1261
28f4ec01
BS
1262/* Return the size required for the block returned by __builtin_apply_args,
1263 and initialize apply_args_mode. */
1264
1265static int
4682ae04 1266apply_args_size (void)
28f4ec01
BS
1267{
1268 static int size = -1;
cbf5468f
AH
1269 int align;
1270 unsigned int regno;
28f4ec01
BS
1271 enum machine_mode mode;
1272
1273 /* The values computed by this function never change. */
1274 if (size < 0)
1275 {
1276 /* The first value is the incoming arg-pointer. */
1277 size = GET_MODE_SIZE (Pmode);
1278
1279 /* The second value is the structure value address unless this is
1280 passed as an "invisible" first argument. */
92f6864c 1281 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
28f4ec01
BS
1282 size += GET_MODE_SIZE (Pmode);
1283
1284 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1285 if (FUNCTION_ARG_REGNO_P (regno))
1286 {
33521f7d
EC
1287 mode = reg_raw_mode[regno];
1288
298e6adc 1289 gcc_assert (mode != VOIDmode);
28f4ec01
BS
1290
1291 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1292 if (size % align != 0)
1293 size = CEIL (size, align) * align;
28f4ec01
BS
1294 size += GET_MODE_SIZE (mode);
1295 apply_args_mode[regno] = mode;
1296 }
1297 else
1298 {
1299 apply_args_mode[regno] = VOIDmode;
28f4ec01
BS
1300 }
1301 }
1302 return size;
1303}
1304
1305/* Return the size required for the block returned by __builtin_apply,
1306 and initialize apply_result_mode. */
1307
1308static int
4682ae04 1309apply_result_size (void)
28f4ec01
BS
1310{
1311 static int size = -1;
1312 int align, regno;
1313 enum machine_mode mode;
1314
1315 /* The values computed by this function never change. */
1316 if (size < 0)
1317 {
1318 size = 0;
1319
1320 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1321 if (FUNCTION_VALUE_REGNO_P (regno))
1322 {
33521f7d
EC
1323 mode = reg_raw_mode[regno];
1324
298e6adc 1325 gcc_assert (mode != VOIDmode);
28f4ec01
BS
1326
1327 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1328 if (size % align != 0)
1329 size = CEIL (size, align) * align;
1330 size += GET_MODE_SIZE (mode);
1331 apply_result_mode[regno] = mode;
1332 }
1333 else
1334 apply_result_mode[regno] = VOIDmode;
1335
1336 /* Allow targets that use untyped_call and untyped_return to override
1337 the size so that machine-specific information can be stored here. */
1338#ifdef APPLY_RESULT_SIZE
1339 size = APPLY_RESULT_SIZE;
1340#endif
1341 }
1342 return size;
1343}
1344
1345#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1346/* Create a vector describing the result block RESULT. If SAVEP is true,
1347 the result block is used to save the values; otherwise it is used to
1348 restore the values. */
1349
1350static rtx
4682ae04 1351result_vector (int savep, rtx result)
28f4ec01
BS
1352{
1353 int regno, size, align, nelts;
1354 enum machine_mode mode;
1355 rtx reg, mem;
f883e0a7 1356 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
8d51ecf8 1357
28f4ec01
BS
1358 size = nelts = 0;
1359 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1360 if ((mode = apply_result_mode[regno]) != VOIDmode)
1361 {
1362 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1363 if (size % align != 0)
1364 size = CEIL (size, align) * align;
1365 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
f4ef873c 1366 mem = adjust_address (result, mode, size);
28f4ec01
BS
1367 savevec[nelts++] = (savep
1368 ? gen_rtx_SET (VOIDmode, mem, reg)
1369 : gen_rtx_SET (VOIDmode, reg, mem));
1370 size += GET_MODE_SIZE (mode);
1371 }
1372 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1373}
1374#endif /* HAVE_untyped_call or HAVE_untyped_return */
1375
1376/* Save the state required to perform an untyped call with the same
1377 arguments as were passed to the current function. */
1378
1379static rtx
4682ae04 1380expand_builtin_apply_args_1 (void)
28f4ec01 1381{
88e541e1 1382 rtx registers, tem;
28f4ec01
BS
1383 int size, align, regno;
1384 enum machine_mode mode;
92f6864c 1385 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
28f4ec01
BS
1386
1387 /* Create a block where the arg-pointer, structure value address,
1388 and argument registers can be saved. */
1389 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1390
1391 /* Walk past the arg-pointer and structure value address. */
1392 size = GET_MODE_SIZE (Pmode);
92f6864c 1393 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
28f4ec01
BS
1394 size += GET_MODE_SIZE (Pmode);
1395
1396 /* Save each register used in calling a function to the block. */
1397 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1398 if ((mode = apply_args_mode[regno]) != VOIDmode)
1399 {
28f4ec01
BS
1400 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1401 if (size % align != 0)
1402 size = CEIL (size, align) * align;
1403
1404 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1405
f4ef873c 1406 emit_move_insn (adjust_address (registers, mode, size), tem);
28f4ec01
BS
1407 size += GET_MODE_SIZE (mode);
1408 }
1409
1410 /* Save the arg pointer to the block. */
2e3f842f 1411 tem = copy_to_reg (crtl->args.internal_arg_pointer);
96bd6f3b 1412#ifdef STACK_GROWS_DOWNWARD
88e541e1 1413 /* We need the pointer as the caller actually passed them to us, not
ac3f5df7
HPN
1414 as we might have pretended they were passed. Make sure it's a valid
1415 operand, as emit_move_insn isn't expected to handle a PLUS. */
1416 tem
38173d38 1417 = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
ac3f5df7 1418 NULL_RTX);
88e541e1
NS
1419#endif
1420 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
33521f7d 1421
28f4ec01
BS
1422 size = GET_MODE_SIZE (Pmode);
1423
1424 /* Save the structure value address unless this is passed as an
1425 "invisible" first argument. */
61f71b34 1426 if (struct_incoming_value)
28f4ec01 1427 {
f4ef873c 1428 emit_move_insn (adjust_address (registers, Pmode, size),
61f71b34 1429 copy_to_reg (struct_incoming_value));
28f4ec01
BS
1430 size += GET_MODE_SIZE (Pmode);
1431 }
1432
1433 /* Return the address of the block. */
1434 return copy_addr_to_reg (XEXP (registers, 0));
1435}
1436
1437/* __builtin_apply_args returns block of memory allocated on
1438 the stack into which is stored the arg pointer, structure
1439 value address, static chain, and all the registers that might
1440 possibly be used in performing a function call. The code is
1441 moved to the start of the function so the incoming values are
1442 saved. */
5197bd50 1443
28f4ec01 1444static rtx
4682ae04 1445expand_builtin_apply_args (void)
28f4ec01
BS
1446{
1447 /* Don't do __builtin_apply_args more than once in a function.
1448 Save the result of the first call and reuse it. */
1449 if (apply_args_value != 0)
1450 return apply_args_value;
1451 {
1452 /* When this function is called, it means that registers must be
1453 saved on entry to this function. So we migrate the
1454 call to the first insn of this function. */
1455 rtx temp;
1456 rtx seq;
1457
1458 start_sequence ();
1459 temp = expand_builtin_apply_args_1 ();
1460 seq = get_insns ();
1461 end_sequence ();
1462
1463 apply_args_value = temp;
1464
2f937369
DM
1465 /* Put the insns after the NOTE that starts the function.
1466 If this is inside a start_sequence, make the outer-level insn
28f4ec01 1467 chain current, so the code is placed at the start of the
1f21b6f4
JJ
1468 function. If internal_arg_pointer is a non-virtual pseudo,
1469 it needs to be placed after the function that initializes
1470 that pseudo. */
28f4ec01 1471 push_topmost_sequence ();
1f21b6f4
JJ
1472 if (REG_P (crtl->args.internal_arg_pointer)
1473 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1474 emit_insn_before (seq, parm_birth_insn);
1475 else
1476 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
28f4ec01
BS
1477 pop_topmost_sequence ();
1478 return temp;
1479 }
1480}
1481
1482/* Perform an untyped call and save the state required to perform an
1483 untyped return of whatever value was returned by the given function. */
1484
1485static rtx
4682ae04 1486expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
28f4ec01
BS
1487{
1488 int size, align, regno;
1489 enum machine_mode mode;
8ac61af7 1490 rtx incoming_args, result, reg, dest, src, call_insn;
28f4ec01
BS
1491 rtx old_stack_level = 0;
1492 rtx call_fusage = 0;
92f6864c 1493 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
28f4ec01 1494
5ae6cd0d 1495 arguments = convert_memory_address (Pmode, arguments);
ce2d32cd 1496
28f4ec01
BS
1497 /* Create a block where the return registers can be saved. */
1498 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1499
28f4ec01
BS
1500 /* Fetch the arg pointer from the ARGUMENTS block. */
1501 incoming_args = gen_reg_rtx (Pmode);
ce2d32cd 1502 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
28f4ec01 1503#ifndef STACK_GROWS_DOWNWARD
ef89d648
ZW
1504 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1505 incoming_args, 0, OPTAB_LIB_WIDEN);
28f4ec01
BS
1506#endif
1507
9d53e585
JM
1508 /* Push a new argument block and copy the arguments. Do not allow
1509 the (potential) memcpy call below to interfere with our stack
1510 manipulations. */
28f4ec01 1511 do_pending_stack_adjust ();
9d53e585 1512 NO_DEFER_POP;
28f4ec01 1513
f9da5064 1514 /* Save the stack with nonlocal if available. */
28f4ec01
BS
1515#ifdef HAVE_save_stack_nonlocal
1516 if (HAVE_save_stack_nonlocal)
1517 emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1518 else
1519#endif
1520 emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1521
316d0b19
EB
1522 /* Allocate a block of memory onto the stack and copy the memory
1523 arguments to the outgoing arguments address. */
1524 allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
2e3f842f
L
1525
1526 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1527 may have already set current_function_calls_alloca to true.
1528 current_function_calls_alloca won't be set if argsize is zero,
1529 so we have to guarantee need_drap is true here. */
1530 if (SUPPORTS_STACK_ALIGNMENT)
1531 crtl->need_drap = true;
1532
316d0b19
EB
1533 dest = virtual_outgoing_args_rtx;
1534#ifndef STACK_GROWS_DOWNWARD
481683e1 1535 if (CONST_INT_P (argsize))
316d0b19
EB
1536 dest = plus_constant (dest, -INTVAL (argsize));
1537 else
1538 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1539#endif
8ac61af7
RK
1540 dest = gen_rtx_MEM (BLKmode, dest);
1541 set_mem_align (dest, PARM_BOUNDARY);
1542 src = gen_rtx_MEM (BLKmode, incoming_args);
1543 set_mem_align (src, PARM_BOUNDARY);
44bb111a 1544 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
28f4ec01
BS
1545
1546 /* Refer to the argument block. */
1547 apply_args_size ();
1548 arguments = gen_rtx_MEM (BLKmode, arguments);
8ac61af7 1549 set_mem_align (arguments, PARM_BOUNDARY);
28f4ec01
BS
1550
1551 /* Walk past the arg-pointer and structure value address. */
1552 size = GET_MODE_SIZE (Pmode);
61f71b34 1553 if (struct_value)
28f4ec01
BS
1554 size += GET_MODE_SIZE (Pmode);
1555
1556 /* Restore each of the registers previously saved. Make USE insns
1557 for each of these registers for use in making the call. */
1558 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1559 if ((mode = apply_args_mode[regno]) != VOIDmode)
1560 {
1561 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1562 if (size % align != 0)
1563 size = CEIL (size, align) * align;
1564 reg = gen_rtx_REG (mode, regno);
f4ef873c 1565 emit_move_insn (reg, adjust_address (arguments, mode, size));
28f4ec01
BS
1566 use_reg (&call_fusage, reg);
1567 size += GET_MODE_SIZE (mode);
1568 }
1569
1570 /* Restore the structure value address unless this is passed as an
1571 "invisible" first argument. */
1572 size = GET_MODE_SIZE (Pmode);
61f71b34 1573 if (struct_value)
28f4ec01
BS
1574 {
1575 rtx value = gen_reg_rtx (Pmode);
f4ef873c 1576 emit_move_insn (value, adjust_address (arguments, Pmode, size));
61f71b34 1577 emit_move_insn (struct_value, value);
f8cfc6aa 1578 if (REG_P (struct_value))
61f71b34 1579 use_reg (&call_fusage, struct_value);
28f4ec01
BS
1580 size += GET_MODE_SIZE (Pmode);
1581 }
1582
1583 /* All arguments and registers used for the call are set up by now! */
531ca746 1584 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
28f4ec01
BS
1585
1586 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1587 and we don't want to load it into a register as an optimization,
1588 because prepare_call_address already did it if it should be done. */
1589 if (GET_CODE (function) != SYMBOL_REF)
1590 function = memory_address (FUNCTION_MODE, function);
1591
1592 /* Generate the actual call instruction and save the return value. */
1593#ifdef HAVE_untyped_call
1594 if (HAVE_untyped_call)
1595 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1596 result, result_vector (1, result)));
1597 else
1598#endif
1599#ifdef HAVE_call_value
1600 if (HAVE_call_value)
1601 {
1602 rtx valreg = 0;
1603
1604 /* Locate the unique return register. It is not possible to
1605 express a call that sets more than one return register using
1606 call_value; use untyped_call for that. In fact, untyped_call
1607 only needs to save the return registers in the given block. */
1608 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1609 if ((mode = apply_result_mode[regno]) != VOIDmode)
1610 {
298e6adc 1611 gcc_assert (!valreg); /* HAVE_untyped_call required. */
5906d013 1612
28f4ec01
BS
1613 valreg = gen_rtx_REG (mode, regno);
1614 }
1615
f45c9d95 1616 emit_call_insn (GEN_CALL_VALUE (valreg,
28f4ec01
BS
1617 gen_rtx_MEM (FUNCTION_MODE, function),
1618 const0_rtx, NULL_RTX, const0_rtx));
1619
f4ef873c 1620 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
28f4ec01
BS
1621 }
1622 else
1623#endif
298e6adc 1624 gcc_unreachable ();
28f4ec01 1625
ee960939
OH
1626 /* Find the CALL insn we just emitted, and attach the register usage
1627 information. */
1628 call_insn = last_call_insn ();
1629 add_function_usage_to (call_insn, call_fusage);
28f4ec01
BS
1630
1631 /* Restore the stack. */
1632#ifdef HAVE_save_stack_nonlocal
1633 if (HAVE_save_stack_nonlocal)
1634 emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1635 else
1636#endif
1637 emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1638
9d53e585
JM
1639 OK_DEFER_POP;
1640
28f4ec01 1641 /* Return the address of the result block. */
5ae6cd0d
MM
1642 result = copy_addr_to_reg (XEXP (result, 0));
1643 return convert_memory_address (ptr_mode, result);
28f4ec01
BS
1644}
1645
1646/* Perform an untyped return. */
1647
1648static void
4682ae04 1649expand_builtin_return (rtx result)
28f4ec01
BS
1650{
1651 int size, align, regno;
1652 enum machine_mode mode;
1653 rtx reg;
1654 rtx call_fusage = 0;
1655
5ae6cd0d 1656 result = convert_memory_address (Pmode, result);
ce2d32cd 1657
28f4ec01
BS
1658 apply_result_size ();
1659 result = gen_rtx_MEM (BLKmode, result);
1660
1661#ifdef HAVE_untyped_return
1662 if (HAVE_untyped_return)
1663 {
1664 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1665 emit_barrier ();
1666 return;
1667 }
1668#endif
1669
1670 /* Restore the return value and note that each value is used. */
1671 size = 0;
1672 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1673 if ((mode = apply_result_mode[regno]) != VOIDmode)
1674 {
1675 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1676 if (size % align != 0)
1677 size = CEIL (size, align) * align;
1678 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
f4ef873c 1679 emit_move_insn (reg, adjust_address (result, mode, size));
28f4ec01
BS
1680
1681 push_to_sequence (call_fusage);
c41c1387 1682 emit_use (reg);
28f4ec01
BS
1683 call_fusage = get_insns ();
1684 end_sequence ();
1685 size += GET_MODE_SIZE (mode);
1686 }
1687
1688 /* Put the USE insns before the return. */
2f937369 1689 emit_insn (call_fusage);
28f4ec01
BS
1690
1691 /* Return whatever values was restored by jumping directly to the end
1692 of the function. */
6e3077c6 1693 expand_naked_return ();
28f4ec01
BS
1694}
1695
ad82abb8 1696/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
5197bd50 1697
ad82abb8 1698static enum type_class
4682ae04 1699type_to_class (tree type)
ad82abb8
ZW
1700{
1701 switch (TREE_CODE (type))
1702 {
1703 case VOID_TYPE: return void_type_class;
1704 case INTEGER_TYPE: return integer_type_class;
ad82abb8
ZW
1705 case ENUMERAL_TYPE: return enumeral_type_class;
1706 case BOOLEAN_TYPE: return boolean_type_class;
1707 case POINTER_TYPE: return pointer_type_class;
1708 case REFERENCE_TYPE: return reference_type_class;
1709 case OFFSET_TYPE: return offset_type_class;
1710 case REAL_TYPE: return real_type_class;
1711 case COMPLEX_TYPE: return complex_type_class;
1712 case FUNCTION_TYPE: return function_type_class;
1713 case METHOD_TYPE: return method_type_class;
1714 case RECORD_TYPE: return record_type_class;
1715 case UNION_TYPE:
1716 case QUAL_UNION_TYPE: return union_type_class;
1717 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1718 ? string_type_class : array_type_class);
ad82abb8
ZW
1719 case LANG_TYPE: return lang_type_class;
1720 default: return no_type_class;
1721 }
1722}
8d51ecf8 1723
5039610b 1724/* Expand a call EXP to __builtin_classify_type. */
5197bd50 1725
28f4ec01 1726static rtx
5039610b 1727expand_builtin_classify_type (tree exp)
28f4ec01 1728{
5039610b
SL
1729 if (call_expr_nargs (exp))
1730 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
28f4ec01
BS
1731 return GEN_INT (no_type_class);
1732}
1733
daa027cc
KG
1734/* This helper macro, meant to be used in mathfn_built_in below,
1735 determines which among a set of three builtin math functions is
1736 appropriate for a given type mode. The `F' and `L' cases are
1737 automatically generated from the `double' case. */
1738#define CASE_MATHFN(BUILT_IN_MATHFN) \
1739 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1740 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1741 fcodel = BUILT_IN_MATHFN##L ; break;
bf460eec
KG
1742/* Similar to above, but appends _R after any F/L suffix. */
1743#define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1744 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1745 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1746 fcodel = BUILT_IN_MATHFN##L_R ; break;
daa027cc
KG
1747
1748/* Return mathematic function equivalent to FN but operating directly
05f41289
KG
1749 on TYPE, if available. If IMPLICIT is true find the function in
1750 implicit_built_in_decls[], otherwise use built_in_decls[]. If we
1751 can't do the conversion, return zero. */
1752
1753static tree
1754mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
272f51a3 1755{
05f41289
KG
1756 tree const *const fn_arr
1757 = implicit ? implicit_built_in_decls : built_in_decls;
daa027cc
KG
1758 enum built_in_function fcode, fcodef, fcodel;
1759
1760 switch (fn)
1761 {
d119e83e
KG
1762 CASE_MATHFN (BUILT_IN_ACOS)
1763 CASE_MATHFN (BUILT_IN_ACOSH)
1764 CASE_MATHFN (BUILT_IN_ASIN)
1765 CASE_MATHFN (BUILT_IN_ASINH)
daa027cc 1766 CASE_MATHFN (BUILT_IN_ATAN)
d119e83e
KG
1767 CASE_MATHFN (BUILT_IN_ATAN2)
1768 CASE_MATHFN (BUILT_IN_ATANH)
1769 CASE_MATHFN (BUILT_IN_CBRT)
daa027cc 1770 CASE_MATHFN (BUILT_IN_CEIL)
75c7c595 1771 CASE_MATHFN (BUILT_IN_CEXPI)
d119e83e 1772 CASE_MATHFN (BUILT_IN_COPYSIGN)
daa027cc 1773 CASE_MATHFN (BUILT_IN_COS)
d119e83e
KG
1774 CASE_MATHFN (BUILT_IN_COSH)
1775 CASE_MATHFN (BUILT_IN_DREM)
1776 CASE_MATHFN (BUILT_IN_ERF)
1777 CASE_MATHFN (BUILT_IN_ERFC)
daa027cc 1778 CASE_MATHFN (BUILT_IN_EXP)
d119e83e
KG
1779 CASE_MATHFN (BUILT_IN_EXP10)
1780 CASE_MATHFN (BUILT_IN_EXP2)
1781 CASE_MATHFN (BUILT_IN_EXPM1)
1782 CASE_MATHFN (BUILT_IN_FABS)
1783 CASE_MATHFN (BUILT_IN_FDIM)
daa027cc 1784 CASE_MATHFN (BUILT_IN_FLOOR)
d119e83e
KG
1785 CASE_MATHFN (BUILT_IN_FMA)
1786 CASE_MATHFN (BUILT_IN_FMAX)
1787 CASE_MATHFN (BUILT_IN_FMIN)
1788 CASE_MATHFN (BUILT_IN_FMOD)
1789 CASE_MATHFN (BUILT_IN_FREXP)
1790 CASE_MATHFN (BUILT_IN_GAMMA)
bf460eec 1791 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
d119e83e
KG
1792 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1793 CASE_MATHFN (BUILT_IN_HYPOT)
1794 CASE_MATHFN (BUILT_IN_ILOGB)
1795 CASE_MATHFN (BUILT_IN_INF)
9ed4207f 1796 CASE_MATHFN (BUILT_IN_ISINF)
d119e83e
KG
1797 CASE_MATHFN (BUILT_IN_J0)
1798 CASE_MATHFN (BUILT_IN_J1)
1799 CASE_MATHFN (BUILT_IN_JN)
f94b1661 1800 CASE_MATHFN (BUILT_IN_LCEIL)
d119e83e 1801 CASE_MATHFN (BUILT_IN_LDEXP)
d8b42d06 1802 CASE_MATHFN (BUILT_IN_LFLOOR)
d119e83e 1803 CASE_MATHFN (BUILT_IN_LGAMMA)
bf460eec 1804 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
f94b1661 1805 CASE_MATHFN (BUILT_IN_LLCEIL)
d8b42d06 1806 CASE_MATHFN (BUILT_IN_LLFLOOR)
d119e83e
KG
1807 CASE_MATHFN (BUILT_IN_LLRINT)
1808 CASE_MATHFN (BUILT_IN_LLROUND)
daa027cc 1809 CASE_MATHFN (BUILT_IN_LOG)
d119e83e
KG
1810 CASE_MATHFN (BUILT_IN_LOG10)
1811 CASE_MATHFN (BUILT_IN_LOG1P)
1812 CASE_MATHFN (BUILT_IN_LOG2)
1813 CASE_MATHFN (BUILT_IN_LOGB)
1814 CASE_MATHFN (BUILT_IN_LRINT)
1815 CASE_MATHFN (BUILT_IN_LROUND)
1816 CASE_MATHFN (BUILT_IN_MODF)
1817 CASE_MATHFN (BUILT_IN_NAN)
1818 CASE_MATHFN (BUILT_IN_NANS)
daa027cc 1819 CASE_MATHFN (BUILT_IN_NEARBYINT)
d119e83e
KG
1820 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1821 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1822 CASE_MATHFN (BUILT_IN_POW)
17684d46 1823 CASE_MATHFN (BUILT_IN_POWI)
d119e83e
KG
1824 CASE_MATHFN (BUILT_IN_POW10)
1825 CASE_MATHFN (BUILT_IN_REMAINDER)
1826 CASE_MATHFN (BUILT_IN_REMQUO)
1827 CASE_MATHFN (BUILT_IN_RINT)
daa027cc 1828 CASE_MATHFN (BUILT_IN_ROUND)
d119e83e
KG
1829 CASE_MATHFN (BUILT_IN_SCALB)
1830 CASE_MATHFN (BUILT_IN_SCALBLN)
1831 CASE_MATHFN (BUILT_IN_SCALBN)
05f41289 1832 CASE_MATHFN (BUILT_IN_SIGNBIT)
d119e83e 1833 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
daa027cc 1834 CASE_MATHFN (BUILT_IN_SIN)
d119e83e
KG
1835 CASE_MATHFN (BUILT_IN_SINCOS)
1836 CASE_MATHFN (BUILT_IN_SINH)
daa027cc
KG
1837 CASE_MATHFN (BUILT_IN_SQRT)
1838 CASE_MATHFN (BUILT_IN_TAN)
d119e83e
KG
1839 CASE_MATHFN (BUILT_IN_TANH)
1840 CASE_MATHFN (BUILT_IN_TGAMMA)
daa027cc 1841 CASE_MATHFN (BUILT_IN_TRUNC)
d119e83e
KG
1842 CASE_MATHFN (BUILT_IN_Y0)
1843 CASE_MATHFN (BUILT_IN_Y1)
1844 CASE_MATHFN (BUILT_IN_YN)
daa027cc 1845
272f51a3 1846 default:
5039610b 1847 return NULL_TREE;
272f51a3 1848 }
daa027cc 1849
ce58118c 1850 if (TYPE_MAIN_VARIANT (type) == double_type_node)
05f41289 1851 return fn_arr[fcode];
ce58118c 1852 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
05f41289 1853 return fn_arr[fcodef];
ce58118c 1854 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
05f41289 1855 return fn_arr[fcodel];
daa027cc 1856 else
5039610b 1857 return NULL_TREE;
272f51a3
JH
1858}
1859
05f41289
KG
1860/* Like mathfn_built_in_1(), but always use the implicit array. */
1861
1862tree
1863mathfn_built_in (tree type, enum built_in_function fn)
1864{
1865 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1866}
1867
b5e01d4b
RS
1868/* If errno must be maintained, expand the RTL to check if the result,
1869 TARGET, of a built-in function call, EXP, is NaN, and if so set
1870 errno to EDOM. */
1871
1872static void
4682ae04 1873expand_errno_check (tree exp, rtx target)
b5e01d4b 1874{
6dab8d4c 1875 rtx lab = gen_label_rtx ();
b5e01d4b 1876
6dab8d4c
RS
1877 /* Test the result; if it is NaN, set errno=EDOM because
1878 the argument was not in the domain. */
337e5d98
PB
1879 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1880 NULL_RTX, NULL_RTX, lab);
b5e01d4b
RS
1881
1882#ifdef TARGET_EDOM
6dab8d4c 1883 /* If this built-in doesn't throw an exception, set errno directly. */
5039610b 1884 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
6dab8d4c 1885 {
b5e01d4b 1886#ifdef GEN_ERRNO_RTX
6dab8d4c 1887 rtx errno_rtx = GEN_ERRNO_RTX;
b5e01d4b 1888#else
6dab8d4c 1889 rtx errno_rtx
b5e01d4b
RS
1890 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1891#endif
6dab8d4c 1892 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
b5e01d4b 1893 emit_label (lab);
6dab8d4c 1894 return;
b5e01d4b 1895 }
6dab8d4c
RS
1896#endif
1897
63cb92c1
JJ
1898 /* Make sure the library call isn't expanded as a tail call. */
1899 CALL_EXPR_TAILCALL (exp) = 0;
1900
6dab8d4c
RS
1901 /* We can't set errno=EDOM directly; let the library call do it.
1902 Pop the arguments right away in case the call gets deleted. */
1903 NO_DEFER_POP;
1904 expand_call (exp, target, 0);
1905 OK_DEFER_POP;
1906 emit_label (lab);
b5e01d4b
RS
1907}
1908
6c7cf1f0 1909/* Expand a call to one of the builtin math functions (sqrt, exp, or log).
5039610b
SL
1910 Return NULL_RTX if a normal call should be emitted rather than expanding
1911 the function in-line. EXP is the expression that is a call to the builtin
28f4ec01
BS
1912 function; if convenient, the result should be placed in TARGET.
1913 SUBTARGET may be used as the target for computing one of EXP's operands. */
5197bd50 1914
28f4ec01 1915static rtx
4682ae04 1916expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
28f4ec01 1917{
8d51ecf8 1918 optab builtin_optab;
451409e4 1919 rtx op0, insns;
2f503025 1920 tree fndecl = get_callee_fndecl (exp);
6dab8d4c 1921 enum machine_mode mode;
82d397c7 1922 bool errno_set = false;
5799f732 1923 tree arg;
28f4ec01 1924
5039610b
SL
1925 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1926 return NULL_RTX;
28f4ec01 1927
5039610b 1928 arg = CALL_EXPR_ARG (exp, 0);
28f4ec01
BS
1929
1930 switch (DECL_FUNCTION_CODE (fndecl))
1931 {
ea6a6627 1932 CASE_FLT_FN (BUILT_IN_SQRT):
6dab8d4c
RS
1933 errno_set = ! tree_expr_nonnegative_p (arg);
1934 builtin_optab = sqrt_optab;
1935 break;
ea6a6627 1936 CASE_FLT_FN (BUILT_IN_EXP):
82d397c7 1937 errno_set = true; builtin_optab = exp_optab; break;
ea6a6627
VR
1938 CASE_FLT_FN (BUILT_IN_EXP10):
1939 CASE_FLT_FN (BUILT_IN_POW10):
a251102e 1940 errno_set = true; builtin_optab = exp10_optab; break;
ea6a6627 1941 CASE_FLT_FN (BUILT_IN_EXP2):
a251102e 1942 errno_set = true; builtin_optab = exp2_optab; break;
ea6a6627 1943 CASE_FLT_FN (BUILT_IN_EXPM1):
7a8e07c7 1944 errno_set = true; builtin_optab = expm1_optab; break;
ea6a6627 1945 CASE_FLT_FN (BUILT_IN_LOGB):
88b28a31 1946 errno_set = true; builtin_optab = logb_optab; break;
ea6a6627 1947 CASE_FLT_FN (BUILT_IN_LOG):
82d397c7 1948 errno_set = true; builtin_optab = log_optab; break;
ea6a6627 1949 CASE_FLT_FN (BUILT_IN_LOG10):
3b8e0c91 1950 errno_set = true; builtin_optab = log10_optab; break;
ea6a6627 1951 CASE_FLT_FN (BUILT_IN_LOG2):
3b8e0c91 1952 errno_set = true; builtin_optab = log2_optab; break;
ea6a6627 1953 CASE_FLT_FN (BUILT_IN_LOG1P):
c2fcfa4f 1954 errno_set = true; builtin_optab = log1p_optab; break;
ea6a6627 1955 CASE_FLT_FN (BUILT_IN_ASIN):
c56122d8 1956 builtin_optab = asin_optab; break;
ea6a6627 1957 CASE_FLT_FN (BUILT_IN_ACOS):
c56122d8 1958 builtin_optab = acos_optab; break;
ea6a6627 1959 CASE_FLT_FN (BUILT_IN_TAN):
82d397c7 1960 builtin_optab = tan_optab; break;
ea6a6627 1961 CASE_FLT_FN (BUILT_IN_ATAN):
82d397c7 1962 builtin_optab = atan_optab; break;
ea6a6627 1963 CASE_FLT_FN (BUILT_IN_FLOOR):
82d397c7 1964 builtin_optab = floor_optab; break;
ea6a6627 1965 CASE_FLT_FN (BUILT_IN_CEIL):
82d397c7 1966 builtin_optab = ceil_optab; break;
ea6a6627 1967 CASE_FLT_FN (BUILT_IN_TRUNC):
85363ca0 1968 builtin_optab = btrunc_optab; break;
ea6a6627 1969 CASE_FLT_FN (BUILT_IN_ROUND):
82d397c7 1970 builtin_optab = round_optab; break;
ea6a6627 1971 CASE_FLT_FN (BUILT_IN_NEARBYINT):
c7d32ff6
RG
1972 builtin_optab = nearbyint_optab;
1973 if (flag_trapping_math)
1974 break;
1975 /* Else fallthrough and expand as rint. */
ea6a6627 1976 CASE_FLT_FN (BUILT_IN_RINT):
edeacc14 1977 builtin_optab = rint_optab; break;
dc6707b8
UB
1978 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1979 builtin_optab = significand_optab; break;
e7b489c8 1980 default:
298e6adc 1981 gcc_unreachable ();
28f4ec01
BS
1982 }
1983
6dab8d4c
RS
1984 /* Make a suitable register to place result in. */
1985 mode = TYPE_MODE (TREE_TYPE (exp));
64e97443 1986
6dab8d4c
RS
1987 if (! flag_errno_math || ! HONOR_NANS (mode))
1988 errno_set = false;
1989
8634629b 1990 /* Before working hard, check whether the instruction is available. */
166cdb08 1991 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
f5416098 1992 {
8634629b 1993 target = gen_reg_rtx (mode);
6dab8d4c 1994
8634629b
RS
1995 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1996 need to expand the argument again. This way, we will not perform
1997 side-effects more the once. */
5799f732 1998 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6dab8d4c 1999
49452c07 2000 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6dab8d4c 2001
8634629b 2002 start_sequence ();
28f4ec01 2003
8634629b
RS
2004 /* Compute into TARGET.
2005 Set TARGET to wherever the result comes back. */
2006 target = expand_unop (mode, builtin_optab, op0, target, 0);
2007
2008 if (target != 0)
2009 {
2010 if (errno_set)
2011 expand_errno_check (exp, target);
2012
2013 /* Output the entire sequence. */
2014 insns = get_insns ();
2015 end_sequence ();
2016 emit_insn (insns);
2017 return target;
2018 }
2019
2020 /* If we were unable to expand via the builtin, stop the sequence
2021 (without outputting the insns) and call to the library function
2022 with the stabilized argument list. */
28f4ec01 2023 end_sequence ();
28f4ec01
BS
2024 }
2025
4a8cae83 2026 return expand_call (exp, target, target == const0_rtx);
b5e01d4b
RS
2027}
2028
2029/* Expand a call to the builtin binary math functions (pow and atan2).
5039610b 2030 Return NULL_RTX if a normal call should be emitted rather than expanding the
b5e01d4b
RS
2031 function in-line. EXP is the expression that is a call to the builtin
2032 function; if convenient, the result should be placed in TARGET.
2033 SUBTARGET may be used as the target for computing one of EXP's
2034 operands. */
2035
2036static rtx
4682ae04 2037expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
b5e01d4b
RS
2038{
2039 optab builtin_optab;
2040 rtx op0, op1, insns;
c94a75af 2041 int op1_type = REAL_TYPE;
2f503025 2042 tree fndecl = get_callee_fndecl (exp);
5799f732 2043 tree arg0, arg1;
6dab8d4c 2044 enum machine_mode mode;
b5e01d4b 2045 bool errno_set = true;
b5e01d4b 2046
0c0d910d
KG
2047 switch (DECL_FUNCTION_CODE (fndecl))
2048 {
2049 CASE_FLT_FN (BUILT_IN_SCALBN):
2050 CASE_FLT_FN (BUILT_IN_SCALBLN):
2051 CASE_FLT_FN (BUILT_IN_LDEXP):
2052 op1_type = INTEGER_TYPE;
2053 default:
2054 break;
2055 }
c94a75af 2056
5039610b
SL
2057 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2058 return NULL_RTX;
b5e01d4b 2059
5039610b
SL
2060 arg0 = CALL_EXPR_ARG (exp, 0);
2061 arg1 = CALL_EXPR_ARG (exp, 1);
b5e01d4b 2062
b5e01d4b
RS
2063 switch (DECL_FUNCTION_CODE (fndecl))
2064 {
ea6a6627 2065 CASE_FLT_FN (BUILT_IN_POW):
b5e01d4b 2066 builtin_optab = pow_optab; break;
ea6a6627 2067 CASE_FLT_FN (BUILT_IN_ATAN2):
b5e01d4b 2068 builtin_optab = atan2_optab; break;
0c0d910d
KG
2069 CASE_FLT_FN (BUILT_IN_SCALB):
2070 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2071 return 0;
2072 builtin_optab = scalb_optab; break;
2073 CASE_FLT_FN (BUILT_IN_SCALBN):
2074 CASE_FLT_FN (BUILT_IN_SCALBLN):
2075 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2076 return 0;
2077 /* Fall through... */
ea6a6627 2078 CASE_FLT_FN (BUILT_IN_LDEXP):
c94a75af 2079 builtin_optab = ldexp_optab; break;
ea6a6627 2080 CASE_FLT_FN (BUILT_IN_FMOD):
5ae27cfa 2081 builtin_optab = fmod_optab; break;
17b98269 2082 CASE_FLT_FN (BUILT_IN_REMAINDER):
ea6a6627 2083 CASE_FLT_FN (BUILT_IN_DREM):
17b98269 2084 builtin_optab = remainder_optab; break;
b5e01d4b 2085 default:
298e6adc 2086 gcc_unreachable ();
b5e01d4b
RS
2087 }
2088
6dab8d4c
RS
2089 /* Make a suitable register to place result in. */
2090 mode = TYPE_MODE (TREE_TYPE (exp));
64e97443
JH
2091
2092 /* Before working hard, check whether the instruction is available. */
166cdb08 2093 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
5039610b 2094 return NULL_RTX;
64e97443 2095
6dab8d4c
RS
2096 target = gen_reg_rtx (mode);
2097
2098 if (! flag_errno_math || ! HONOR_NANS (mode))
2099 errno_set = false;
2100
6de9cd9a 2101 /* Always stabilize the argument list. */
5799f732
RG
2102 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2103 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
6dab8d4c 2104
84217346
MD
2105 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2106 op1 = expand_normal (arg1);
6dab8d4c 2107
6dab8d4c
RS
2108 start_sequence ();
2109
b5e01d4b
RS
2110 /* Compute into TARGET.
2111 Set TARGET to wherever the result comes back. */
6dab8d4c 2112 target = expand_binop (mode, builtin_optab, op0, op1,
b5e01d4b 2113 target, 0, OPTAB_DIRECT);
28f4ec01 2114
f5416098
RS
2115 /* If we were unable to expand via the builtin, stop the sequence
2116 (without outputting the insns) and call to the library function
2117 with the stabilized argument list. */
b5e01d4b
RS
2118 if (target == 0)
2119 {
2120 end_sequence ();
f5416098 2121 return expand_call (exp, target, target == const0_rtx);
28f4ec01
BS
2122 }
2123
da52a069
RS
2124 if (errno_set)
2125 expand_errno_check (exp, target);
b5e01d4b 2126
28f4ec01
BS
2127 /* Output the entire sequence. */
2128 insns = get_insns ();
2129 end_sequence ();
2f937369 2130 emit_insn (insns);
8d51ecf8 2131
28f4ec01
BS
2132 return target;
2133}
2134
6c7cf1f0 2135/* Expand a call to the builtin sin and cos math functions.
5039610b 2136 Return NULL_RTX if a normal call should be emitted rather than expanding the
6c7cf1f0
UB
2137 function in-line. EXP is the expression that is a call to the builtin
2138 function; if convenient, the result should be placed in TARGET.
2139 SUBTARGET may be used as the target for computing one of EXP's
2140 operands. */
2141
2142static rtx
2143expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2144{
2145 optab builtin_optab;
b475548e 2146 rtx op0, insns;
6c7cf1f0 2147 tree fndecl = get_callee_fndecl (exp);
6c7cf1f0 2148 enum machine_mode mode;
5799f732 2149 tree arg;
6c7cf1f0 2150
5039610b
SL
2151 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2152 return NULL_RTX;
6c7cf1f0 2153
5039610b 2154 arg = CALL_EXPR_ARG (exp, 0);
6c7cf1f0
UB
2155
2156 switch (DECL_FUNCTION_CODE (fndecl))
2157 {
ea6a6627
VR
2158 CASE_FLT_FN (BUILT_IN_SIN):
2159 CASE_FLT_FN (BUILT_IN_COS):
6c7cf1f0
UB
2160 builtin_optab = sincos_optab; break;
2161 default:
298e6adc 2162 gcc_unreachable ();
6c7cf1f0
UB
2163 }
2164
2165 /* Make a suitable register to place result in. */
2166 mode = TYPE_MODE (TREE_TYPE (exp));
2167
6c7cf1f0 2168 /* Check if sincos insn is available, otherwise fallback
9cf737f8 2169 to sin or cos insn. */
166cdb08 2170 if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
6c7cf1f0
UB
2171 switch (DECL_FUNCTION_CODE (fndecl))
2172 {
ea6a6627 2173 CASE_FLT_FN (BUILT_IN_SIN):
6c7cf1f0 2174 builtin_optab = sin_optab; break;
ea6a6627 2175 CASE_FLT_FN (BUILT_IN_COS):
6c7cf1f0
UB
2176 builtin_optab = cos_optab; break;
2177 default:
298e6adc 2178 gcc_unreachable ();
6c7cf1f0 2179 }
6c7cf1f0
UB
2180
2181 /* Before working hard, check whether the instruction is available. */
166cdb08 2182 if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
6c7cf1f0
UB
2183 {
2184 target = gen_reg_rtx (mode);
2185
2186 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2187 need to expand the argument again. This way, we will not perform
2188 side-effects more the once. */
5799f732 2189 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
6c7cf1f0 2190
49452c07 2191 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
6c7cf1f0 2192
6c7cf1f0
UB
2193 start_sequence ();
2194
2195 /* Compute into TARGET.
2196 Set TARGET to wherever the result comes back. */
2197 if (builtin_optab == sincos_optab)
2198 {
298e6adc 2199 int result;
5906d013 2200
6c7cf1f0
UB
2201 switch (DECL_FUNCTION_CODE (fndecl))
2202 {
ea6a6627 2203 CASE_FLT_FN (BUILT_IN_SIN):
298e6adc 2204 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
6c7cf1f0 2205 break;
ea6a6627 2206 CASE_FLT_FN (BUILT_IN_COS):
298e6adc 2207 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
6c7cf1f0
UB
2208 break;
2209 default:
298e6adc 2210 gcc_unreachable ();
6c7cf1f0 2211 }
298e6adc 2212 gcc_assert (result);
6c7cf1f0
UB
2213 }
2214 else
2215 {
2216 target = expand_unop (mode, builtin_optab, op0, target, 0);
2217 }
2218
2219 if (target != 0)
2220 {
6c7cf1f0
UB
2221 /* Output the entire sequence. */
2222 insns = get_insns ();
2223 end_sequence ();
2224 emit_insn (insns);
2225 return target;
2226 }
2227
2228 /* If we were unable to expand via the builtin, stop the sequence
2229 (without outputting the insns) and call to the library function
2230 with the stabilized argument list. */
2231 end_sequence ();
2232 }
2233
6c7cf1f0
UB
2234 target = expand_call (exp, target, target == const0_rtx);
2235
2236 return target;
2237}
2238
44e10129
MM
2239/* Given an interclass math builtin decl FNDECL and it's argument ARG
2240 return an RTL instruction code that implements the functionality.
2241 If that isn't possible or available return CODE_FOR_nothing. */
eaee4464 2242
44e10129
MM
2243static enum insn_code
2244interclass_mathfn_icode (tree arg, tree fndecl)
eaee4464 2245{
44e10129 2246 bool errno_set = false;
0c8d3c2b 2247 optab builtin_optab = 0;
eaee4464 2248 enum machine_mode mode;
eaee4464
UB
2249
2250 switch (DECL_FUNCTION_CODE (fndecl))
2251 {
2252 CASE_FLT_FN (BUILT_IN_ILOGB):
2253 errno_set = true; builtin_optab = ilogb_optab; break;
9ed4207f
UB
2254 CASE_FLT_FN (BUILT_IN_ISINF):
2255 builtin_optab = isinf_optab; break;
8a91c45b 2256 case BUILT_IN_ISNORMAL:
0c8d3c2b
KG
2257 case BUILT_IN_ISFINITE:
2258 CASE_FLT_FN (BUILT_IN_FINITE):
44e10129
MM
2259 case BUILT_IN_FINITED32:
2260 case BUILT_IN_FINITED64:
2261 case BUILT_IN_FINITED128:
2262 case BUILT_IN_ISINFD32:
2263 case BUILT_IN_ISINFD64:
2264 case BUILT_IN_ISINFD128:
0c8d3c2b
KG
2265 /* These builtins have no optabs (yet). */
2266 break;
eaee4464
UB
2267 default:
2268 gcc_unreachable ();
2269 }
2270
2271 /* There's no easy way to detect the case we need to set EDOM. */
2272 if (flag_errno_math && errno_set)
44e10129 2273 return CODE_FOR_nothing;
eaee4464
UB
2274
2275 /* Optab mode depends on the mode of the input argument. */
2276 mode = TYPE_MODE (TREE_TYPE (arg));
2277
0c8d3c2b 2278 if (builtin_optab)
44e10129
MM
2279 return optab_handler (builtin_optab, mode)->insn_code;
2280 return CODE_FOR_nothing;
2281}
2282
2283/* Expand a call to one of the builtin math functions that operate on
2284 floating point argument and output an integer result (ilogb, isinf,
2285 isnan, etc).
2286 Return 0 if a normal call should be emitted rather than expanding the
2287 function in-line. EXP is the expression that is a call to the builtin
2288 function; if convenient, the result should be placed in TARGET.
2289 SUBTARGET may be used as the target for computing one of EXP's operands. */
2290
2291static rtx
2292expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2293{
2294 enum insn_code icode = CODE_FOR_nothing;
2295 rtx op0;
2296 tree fndecl = get_callee_fndecl (exp);
2297 enum machine_mode mode;
2298 tree arg;
2299
2300 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2301 return NULL_RTX;
2302
2303 arg = CALL_EXPR_ARG (exp, 0);
2304 icode = interclass_mathfn_icode (arg, fndecl);
2305 mode = TYPE_MODE (TREE_TYPE (arg));
2306
eaee4464
UB
2307 if (icode != CODE_FOR_nothing)
2308 {
2309 /* Make a suitable register to place result in. */
2310 if (!target
2311 || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2312 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2313
2314 gcc_assert (insn_data[icode].operand[0].predicate
2315 (target, GET_MODE (target)));
2316
2317 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2318 need to expand the argument again. This way, we will not perform
2319 side-effects more the once. */
5799f732 2320 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
eaee4464 2321
49452c07 2322 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
eaee4464
UB
2323
2324 if (mode != GET_MODE (op0))
2325 op0 = convert_to_mode (mode, op0, 0);
2326
2327 /* Compute into TARGET.
2328 Set TARGET to wherever the result comes back. */
2329 emit_unop_insn (icode, target, op0, UNKNOWN);
2330 return target;
2331 }
2332
44e10129 2333 return NULL_RTX;
eaee4464
UB
2334}
2335
403e54f0 2336/* Expand a call to the builtin sincos math function.
5039610b 2337 Return NULL_RTX if a normal call should be emitted rather than expanding the
403e54f0
RG
2338 function in-line. EXP is the expression that is a call to the builtin
2339 function. */
2340
2341static rtx
2342expand_builtin_sincos (tree exp)
2343{
2344 rtx op0, op1, op2, target1, target2;
403e54f0
RG
2345 enum machine_mode mode;
2346 tree arg, sinp, cosp;
2347 int result;
db3927fb 2348 location_t loc = EXPR_LOCATION (exp);
403e54f0 2349
5039610b
SL
2350 if (!validate_arglist (exp, REAL_TYPE,
2351 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2352 return NULL_RTX;
403e54f0 2353
5039610b
SL
2354 arg = CALL_EXPR_ARG (exp, 0);
2355 sinp = CALL_EXPR_ARG (exp, 1);
2356 cosp = CALL_EXPR_ARG (exp, 2);
403e54f0
RG
2357
2358 /* Make a suitable register to place result in. */
2359 mode = TYPE_MODE (TREE_TYPE (arg));
2360
2361 /* Check if sincos insn is available, otherwise emit the call. */
166cdb08 2362 if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
403e54f0
RG
2363 return NULL_RTX;
2364
2365 target1 = gen_reg_rtx (mode);
2366 target2 = gen_reg_rtx (mode);
2367
84217346 2368 op0 = expand_normal (arg);
db3927fb
AH
2369 op1 = expand_normal (build_fold_indirect_ref_loc (loc, sinp));
2370 op2 = expand_normal (build_fold_indirect_ref_loc (loc, cosp));
403e54f0
RG
2371
2372 /* Compute into target1 and target2.
2373 Set TARGET to wherever the result comes back. */
2374 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2375 gcc_assert (result);
2376
2377 /* Move target1 and target2 to the memory locations indicated
2378 by op1 and op2. */
2379 emit_move_insn (op1, target1);
2380 emit_move_insn (op2, target2);
2381
2382 return const0_rtx;
2383}
2384
75c7c595
RG
2385/* Expand a call to the internal cexpi builtin to the sincos math function.
2386 EXP is the expression that is a call to the builtin function; if convenient,
2387 the result should be placed in TARGET. SUBTARGET may be used as the target
2388 for computing one of EXP's operands. */
2389
2390static rtx
2391expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2392{
2393 tree fndecl = get_callee_fndecl (exp);
75c7c595 2394 tree arg, type;
5039610b 2395 enum machine_mode mode;
75c7c595 2396 rtx op0, op1, op2;
db3927fb 2397 location_t loc = EXPR_LOCATION (exp);
75c7c595 2398
5039610b
SL
2399 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2400 return NULL_RTX;
75c7c595 2401
5039610b 2402 arg = CALL_EXPR_ARG (exp, 0);
75c7c595
RG
2403 type = TREE_TYPE (arg);
2404 mode = TYPE_MODE (TREE_TYPE (arg));
2405
2406 /* Try expanding via a sincos optab, fall back to emitting a libcall
b54c5497
RG
2407 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2408 is only generated from sincos, cexp or if we have either of them. */
166cdb08 2409 if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
75c7c595
RG
2410 {
2411 op1 = gen_reg_rtx (mode);
2412 op2 = gen_reg_rtx (mode);
2413
49452c07 2414 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
75c7c595
RG
2415
2416 /* Compute into op1 and op2. */
2417 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2418 }
b54c5497 2419 else if (TARGET_HAS_SINCOS)
75c7c595 2420 {
5039610b 2421 tree call, fn = NULL_TREE;
75c7c595
RG
2422 tree top1, top2;
2423 rtx op1a, op2a;
2424
2425 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2426 fn = built_in_decls[BUILT_IN_SINCOSF];
2427 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2428 fn = built_in_decls[BUILT_IN_SINCOS];
2429 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2430 fn = built_in_decls[BUILT_IN_SINCOSL];
5039610b
SL
2431 else
2432 gcc_unreachable ();
b8698a0f 2433
75c7c595
RG
2434 op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2435 op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2436 op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2437 op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2438 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2439 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2440
75c7c595
RG
2441 /* Make sure not to fold the sincos call again. */
2442 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
5039610b
SL
2443 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2444 call, 3, arg, top1, top2));
75c7c595 2445 }
b54c5497
RG
2446 else
2447 {
9d972b2d 2448 tree call, fn = NULL_TREE, narg;
b54c5497
RG
2449 tree ctype = build_complex_type (type);
2450
9d972b2d
RG
2451 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2452 fn = built_in_decls[BUILT_IN_CEXPF];
2453 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2454 fn = built_in_decls[BUILT_IN_CEXP];
2455 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2456 fn = built_in_decls[BUILT_IN_CEXPL];
5039610b
SL
2457 else
2458 gcc_unreachable ();
34a24c11
RG
2459
2460 /* If we don't have a decl for cexp create one. This is the
2461 friendliest fallback if the user calls __builtin_cexpi
2462 without full target C99 function support. */
2463 if (fn == NULL_TREE)
2464 {
2465 tree fntype;
2466 const char *name = NULL;
2467
2468 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2469 name = "cexpf";
2470 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2471 name = "cexp";
2472 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2473 name = "cexpl";
2474
2475 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2476 fn = build_fn_decl (name, fntype);
2477 }
2478
db3927fb 2479 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
b54c5497
RG
2480 build_real (type, dconst0), arg);
2481
2482 /* Make sure not to fold the cexp call again. */
2483 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
b8698a0f 2484 return expand_expr (build_call_nary (ctype, call, 1, narg),
49452c07 2485 target, VOIDmode, EXPAND_NORMAL);
b54c5497 2486 }
75c7c595
RG
2487
2488 /* Now build the proper return type. */
2489 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2490 make_tree (TREE_TYPE (arg), op2),
2491 make_tree (TREE_TYPE (arg), op1)),
49452c07 2492 target, VOIDmode, EXPAND_NORMAL);
75c7c595
RG
2493}
2494
44e10129
MM
2495/* Conveniently construct a function call expression. FNDECL names the
2496 function to be called, N is the number of arguments, and the "..."
2497 parameters are the argument expressions. Unlike build_call_exr
2498 this doesn't fold the call, hence it will always return a CALL_EXPR. */
2499
2500static tree
2501build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2502{
2503 va_list ap;
2504 tree fntype = TREE_TYPE (fndecl);
2505 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2506
2507 va_start (ap, n);
2508 fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2509 va_end (ap);
2510 SET_EXPR_LOCATION (fn, loc);
2511 return fn;
2512}
2513#define build_call_nofold(...) \
2514 build_call_nofold_loc (UNKNOWN_LOCATION, __VA_ARGS__)
2515
0bfa1541
RG
2516/* Expand a call to one of the builtin rounding functions gcc defines
2517 as an extension (lfloor and lceil). As these are gcc extensions we
2518 do not need to worry about setting errno to EDOM.
d8b42d06
UB
2519 If expanding via optab fails, lower expression to (int)(floor(x)).
2520 EXP is the expression that is a call to the builtin function;
1856c8dc 2521 if convenient, the result should be placed in TARGET. */
d8b42d06
UB
2522
2523static rtx
1856c8dc 2524expand_builtin_int_roundingfn (tree exp, rtx target)
d8b42d06 2525{
c3a4177f 2526 convert_optab builtin_optab;
d8b42d06
UB
2527 rtx op0, insns, tmp;
2528 tree fndecl = get_callee_fndecl (exp);
d8b42d06
UB
2529 enum built_in_function fallback_fn;
2530 tree fallback_fndecl;
2531 enum machine_mode mode;
968fc3b6 2532 tree arg;
d8b42d06 2533
5039610b 2534 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
d8b42d06
UB
2535 gcc_unreachable ();
2536
5039610b 2537 arg = CALL_EXPR_ARG (exp, 0);
d8b42d06
UB
2538
2539 switch (DECL_FUNCTION_CODE (fndecl))
2540 {
ea6a6627
VR
2541 CASE_FLT_FN (BUILT_IN_LCEIL):
2542 CASE_FLT_FN (BUILT_IN_LLCEIL):
f94b1661
UB
2543 builtin_optab = lceil_optab;
2544 fallback_fn = BUILT_IN_CEIL;
2545 break;
2546
ea6a6627
VR
2547 CASE_FLT_FN (BUILT_IN_LFLOOR):
2548 CASE_FLT_FN (BUILT_IN_LLFLOOR):
d8b42d06
UB
2549 builtin_optab = lfloor_optab;
2550 fallback_fn = BUILT_IN_FLOOR;
2551 break;
2552
2553 default:
2554 gcc_unreachable ();
2555 }
2556
2557 /* Make a suitable register to place result in. */
2558 mode = TYPE_MODE (TREE_TYPE (exp));
2559
c3a4177f 2560 target = gen_reg_rtx (mode);
d8b42d06 2561
c3a4177f
RG
2562 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2563 need to expand the argument again. This way, we will not perform
2564 side-effects more the once. */
5799f732 2565 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
d8b42d06 2566
1856c8dc 2567 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
d8b42d06 2568
c3a4177f 2569 start_sequence ();
d8b42d06 2570
c3a4177f
RG
2571 /* Compute into TARGET. */
2572 if (expand_sfix_optab (target, op0, builtin_optab))
2573 {
2574 /* Output the entire sequence. */
2575 insns = get_insns ();
d8b42d06 2576 end_sequence ();
c3a4177f
RG
2577 emit_insn (insns);
2578 return target;
d8b42d06
UB
2579 }
2580
c3a4177f
RG
2581 /* If we were unable to expand via the builtin, stop the sequence
2582 (without outputting the insns). */
2583 end_sequence ();
2584
d8b42d06
UB
2585 /* Fall back to floating point rounding optab. */
2586 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
34a24c11
RG
2587
2588 /* For non-C99 targets we may end up without a fallback fndecl here
2589 if the user called __builtin_lfloor directly. In this case emit
2590 a call to the floor/ceil variants nevertheless. This should result
2591 in the best user experience for not full C99 targets. */
2592 if (fallback_fndecl == NULL_TREE)
2593 {
2594 tree fntype;
2595 const char *name = NULL;
2596
2597 switch (DECL_FUNCTION_CODE (fndecl))
2598 {
2599 case BUILT_IN_LCEIL:
2600 case BUILT_IN_LLCEIL:
2601 name = "ceil";
2602 break;
2603 case BUILT_IN_LCEILF:
2604 case BUILT_IN_LLCEILF:
2605 name = "ceilf";
2606 break;
2607 case BUILT_IN_LCEILL:
2608 case BUILT_IN_LLCEILL:
2609 name = "ceill";
2610 break;
2611 case BUILT_IN_LFLOOR:
2612 case BUILT_IN_LLFLOOR:
2613 name = "floor";
2614 break;
2615 case BUILT_IN_LFLOORF:
2616 case BUILT_IN_LLFLOORF:
2617 name = "floorf";
2618 break;
2619 case BUILT_IN_LFLOORL:
2620 case BUILT_IN_LLFLOORL:
2621 name = "floorl";
2622 break;
2623 default:
2624 gcc_unreachable ();
2625 }
2626
2627 fntype = build_function_type_list (TREE_TYPE (arg),
2628 TREE_TYPE (arg), NULL_TREE);
2629 fallback_fndecl = build_fn_decl (name, fntype);
2630 }
2631
44e10129 2632 exp = build_call_nofold (fallback_fndecl, 1, arg);
d8b42d06 2633
39b1ec97 2634 tmp = expand_normal (exp);
d8b42d06
UB
2635
2636 /* Truncate the result of floating point optab to integer
2637 via expand_fix (). */
2638 target = gen_reg_rtx (mode);
2639 expand_fix (target, tmp, 0);
2640
2641 return target;
2642}
2643
0bfa1541
RG
2644/* Expand a call to one of the builtin math functions doing integer
2645 conversion (lrint).
2646 Return 0 if a normal call should be emitted rather than expanding the
2647 function in-line. EXP is the expression that is a call to the builtin
1856c8dc 2648 function; if convenient, the result should be placed in TARGET. */
0bfa1541
RG
2649
2650static rtx
1856c8dc 2651expand_builtin_int_roundingfn_2 (tree exp, rtx target)
0bfa1541 2652{
bb7f0423 2653 convert_optab builtin_optab;
0bfa1541
RG
2654 rtx op0, insns;
2655 tree fndecl = get_callee_fndecl (exp);
968fc3b6 2656 tree arg;
5039610b 2657 enum machine_mode mode;
0bfa1541
RG
2658
2659 /* There's no easy way to detect the case we need to set EDOM. */
2660 if (flag_errno_math)
2661 return NULL_RTX;
2662
5039610b
SL
2663 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2664 gcc_unreachable ();
b8698a0f 2665
5039610b 2666 arg = CALL_EXPR_ARG (exp, 0);
0bfa1541
RG
2667
2668 switch (DECL_FUNCTION_CODE (fndecl))
2669 {
2670 CASE_FLT_FN (BUILT_IN_LRINT):
2671 CASE_FLT_FN (BUILT_IN_LLRINT):
2672 builtin_optab = lrint_optab; break;
4d81bf84
RG
2673 CASE_FLT_FN (BUILT_IN_LROUND):
2674 CASE_FLT_FN (BUILT_IN_LLROUND):
2675 builtin_optab = lround_optab; break;
0bfa1541
RG
2676 default:
2677 gcc_unreachable ();
2678 }
2679
2680 /* Make a suitable register to place result in. */
2681 mode = TYPE_MODE (TREE_TYPE (exp));
2682
bb7f0423 2683 target = gen_reg_rtx (mode);
0bfa1541 2684
bb7f0423
RG
2685 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2686 need to expand the argument again. This way, we will not perform
2687 side-effects more the once. */
5799f732 2688 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
0bfa1541 2689
1856c8dc 2690 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
0bfa1541 2691
bb7f0423 2692 start_sequence ();
0bfa1541 2693
bb7f0423
RG
2694 if (expand_sfix_optab (target, op0, builtin_optab))
2695 {
2696 /* Output the entire sequence. */
2697 insns = get_insns ();
0bfa1541 2698 end_sequence ();
bb7f0423
RG
2699 emit_insn (insns);
2700 return target;
0bfa1541
RG
2701 }
2702
bb7f0423
RG
2703 /* If we were unable to expand via the builtin, stop the sequence
2704 (without outputting the insns) and call to the library function
2705 with the stabilized argument list. */
2706 end_sequence ();
2707
0bfa1541
RG
2708 target = expand_call (exp, target, target == const0_rtx);
2709
2710 return target;
2711}
2712
2082e02f
RS
2713/* To evaluate powi(x,n), the floating point value x raised to the
2714 constant integer exponent n, we use a hybrid algorithm that
2715 combines the "window method" with look-up tables. For an
2716 introduction to exponentiation algorithms and "addition chains",
2717 see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2718 "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2719 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2720 Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
2721
2722/* Provide a default value for POWI_MAX_MULTS, the maximum number of
2723 multiplications to inline before calling the system library's pow
2724 function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2725 so this default never requires calling pow, powf or powl. */
33521f7d 2726
2082e02f
RS
2727#ifndef POWI_MAX_MULTS
2728#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
2729#endif
2730
2731/* The size of the "optimal power tree" lookup table. All
2732 exponents less than this value are simply looked up in the
2733 powi_table below. This threshold is also used to size the
2734 cache of pseudo registers that hold intermediate results. */
2735#define POWI_TABLE_SIZE 256
2736
2737/* The size, in bits of the window, used in the "window method"
2738 exponentiation algorithm. This is equivalent to a radix of
2739 (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
2740#define POWI_WINDOW_SIZE 3
2741
2742/* The following table is an efficient representation of an
2743 "optimal power tree". For each value, i, the corresponding
2744 value, j, in the table states than an optimal evaluation
2745 sequence for calculating pow(x,i) can be found by evaluating
2746 pow(x,j)*pow(x,i-j). An optimal power tree for the first
2747 100 integers is given in Knuth's "Seminumerical algorithms". */
2748
2749static const unsigned char powi_table[POWI_TABLE_SIZE] =
2750 {
2751 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
2752 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
2753 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
2754 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
2755 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
2756 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
2757 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
2758 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
2759 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
2760 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
2761 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
2762 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
2763 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
2764 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
2765 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
2766 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
2767 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
2768 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
2769 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
2770 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
2771 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
2772 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
2773 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
2774 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
2775 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
2776 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
2777 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
2778 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
2779 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
2780 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
2781 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
2782 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
2783 };
2784
2785
2786/* Return the number of multiplications required to calculate
2787 powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
2788 subroutine of powi_cost. CACHE is an array indicating
2789 which exponents have already been calculated. */
2790
2791static int
2792powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2793{
2794 /* If we've already calculated this exponent, then this evaluation
2795 doesn't require any additional multiplications. */
2796 if (cache[n])
2797 return 0;
2798
2799 cache[n] = true;
2800 return powi_lookup_cost (n - powi_table[n], cache)
2801 + powi_lookup_cost (powi_table[n], cache) + 1;
2802}
2803
2804/* Return the number of multiplications required to calculate
2805 powi(x,n) for an arbitrary x, given the exponent N. This
2806 function needs to be kept in sync with expand_powi below. */
2807
2808static int
2809powi_cost (HOST_WIDE_INT n)
2810{
2811 bool cache[POWI_TABLE_SIZE];
2812 unsigned HOST_WIDE_INT digit;
2813 unsigned HOST_WIDE_INT val;
2814 int result;
2815
2816 if (n == 0)
2817 return 0;
2818
2819 /* Ignore the reciprocal when calculating the cost. */
2820 val = (n < 0) ? -n : n;
2821
2822 /* Initialize the exponent cache. */
2823 memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2824 cache[1] = true;
2825
2826 result = 0;
2827
2828 while (val >= POWI_TABLE_SIZE)
2829 {
2830 if (val & 1)
2831 {
2832 digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2833 result += powi_lookup_cost (digit, cache)
2834 + POWI_WINDOW_SIZE + 1;
2835 val >>= POWI_WINDOW_SIZE;
2836 }
2837 else
2838 {
2839 val >>= 1;
2840 result++;
2841 }
2842 }
33521f7d 2843
b9ba01a1 2844 return result + powi_lookup_cost (val, cache);
2082e02f
RS
2845}
2846
2847/* Recursive subroutine of expand_powi. This function takes the array,
2848 CACHE, of already calculated exponents and an exponent N and returns
2849 an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
2850
2851static rtx
2852expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2853{
2854 unsigned HOST_WIDE_INT digit;
2855 rtx target, result;
2856 rtx op0, op1;
2857
2858 if (n < POWI_TABLE_SIZE)
2859 {
2860 if (cache[n])
c22cacf3 2861 return cache[n];
2082e02f
RS
2862
2863 target = gen_reg_rtx (mode);
2864 cache[n] = target;
2865
2866 op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2867 op1 = expand_powi_1 (mode, powi_table[n], cache);
2868 }
2869 else if (n & 1)
2870 {
2871 target = gen_reg_rtx (mode);
2872 digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2873 op0 = expand_powi_1 (mode, n - digit, cache);
2874 op1 = expand_powi_1 (mode, digit, cache);
2875 }
2876 else
2877 {
2878 target = gen_reg_rtx (mode);
2879 op0 = expand_powi_1 (mode, n >> 1, cache);
2880 op1 = op0;
2881 }
2882
2883 result = expand_mult (mode, op0, op1, target, 0);
2884 if (result != target)
2885 emit_move_insn (target, result);
2886 return target;
2887}
2888
2889/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
2890 floating point operand in mode MODE, and N is the exponent. This
2891 function needs to be kept in sync with powi_cost above. */
33521f7d 2892
2082e02f
RS
2893static rtx
2894expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2895{
2082e02f
RS
2896 rtx cache[POWI_TABLE_SIZE];
2897 rtx result;
2898
2899 if (n == 0)
2900 return CONST1_RTX (mode);
2901
868b8cda 2902 memset (cache, 0, sizeof (cache));
2082e02f
RS
2903 cache[1] = x;
2904
2905 result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2906
2907 /* If the original exponent was negative, reciprocate the result. */
2908 if (n < 0)
2909 result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2910 result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2911
2912 return result;
2913}
2914
5039610b 2915/* Expand a call to the pow built-in mathematical function. Return NULL_RTX if
2082e02f
RS
2916 a normal call should be emitted rather than expanding the function
2917 in-line. EXP is the expression that is a call to the builtin
2918 function; if convenient, the result should be placed in TARGET. */
2919
2920static rtx
2921expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2922{
5039610b
SL
2923 tree arg0, arg1;
2924 tree fn, narg0;
9fca6f97
RG
2925 tree type = TREE_TYPE (exp);
2926 REAL_VALUE_TYPE cint, c, c2;
2927 HOST_WIDE_INT n;
2928 rtx op, op2;
2929 enum machine_mode mode = TYPE_MODE (type);
2082e02f 2930
5039610b
SL
2931 if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2932 return NULL_RTX;
2082e02f 2933
5039610b
SL
2934 arg0 = CALL_EXPR_ARG (exp, 0);
2935 arg1 = CALL_EXPR_ARG (exp, 1);
2082e02f 2936
9fca6f97 2937 if (TREE_CODE (arg1) != REAL_CST
455f14dd 2938 || TREE_OVERFLOW (arg1))
9fca6f97
RG
2939 return expand_builtin_mathfn_2 (exp, target, subtarget);
2940
2941 /* Handle constant exponents. */
2942
2943 /* For integer valued exponents we can expand to an optimal multiplication
2944 sequence using expand_powi. */
2945 c = TREE_REAL_CST (arg1);
2946 n = real_to_integer (&c);
2947 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2948 if (real_identical (&c, &cint)
2949 && ((n >= -1 && n <= 2)
2950 || (flag_unsafe_math_optimizations
22660666 2951 && optimize_insn_for_speed_p ()
9fca6f97 2952 && powi_cost (n) <= POWI_MAX_MULTS)))
2082e02f 2953 {
49452c07 2954 op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
9fca6f97
RG
2955 if (n != 1)
2956 {
2957 op = force_reg (mode, op);
2958 op = expand_powi (op, mode, n);
2959 }
2960 return op;
2961 }
2962
2963 narg0 = builtin_save_expr (arg0);
2082e02f 2964
9fca6f97
RG
2965 /* If the exponent is not integer valued, check if it is half of an integer.
2966 In this case we can expand to sqrt (x) * x**(n/2). */
2967 fn = mathfn_built_in (type, BUILT_IN_SQRT);
2968 if (fn != NULL_TREE)
2969 {
2970 real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2971 n = real_to_integer (&c2);
2082e02f 2972 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
9fca6f97
RG
2973 if (real_identical (&c2, &cint)
2974 && ((flag_unsafe_math_optimizations
22660666 2975 && optimize_insn_for_speed_p ()
9fca6f97
RG
2976 && powi_cost (n/2) <= POWI_MAX_MULTS)
2977 || n == 1))
2082e02f 2978 {
44e10129 2979 tree call_expr = build_call_nofold (fn, 1, narg0);
5e043dc9
RG
2980 /* Use expand_expr in case the newly built call expression
2981 was folded to a non-call. */
2982 op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
9fca6f97 2983 if (n != 1)
2598550f 2984 {
49452c07 2985 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
9fca6f97
RG
2986 op2 = force_reg (mode, op2);
2987 op2 = expand_powi (op2, mode, abs (n / 2));
2988 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2989 0, OPTAB_LIB_WIDEN);
2990 /* If the original exponent was negative, reciprocate the
2991 result. */
2992 if (n < 0)
2993 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2994 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2598550f 2995 }
9fca6f97 2996 return op;
2082e02f
RS
2997 }
2998 }
13b59849 2999
9fca6f97 3000 /* Try if the exponent is a third of an integer. In this case
5eab7e7a
RG
3001 we can expand to x**(n/3) * cbrt(x)**(n%3). As cbrt (x) is
3002 different from pow (x, 1./3.) due to rounding and behavior
3003 with negative x we need to constrain this transformation to
3004 unsafe math and positive x or finite math. */
9fca6f97 3005 fn = mathfn_built_in (type, BUILT_IN_CBRT);
5eab7e7a
RG
3006 if (fn != NULL_TREE
3007 && flag_unsafe_math_optimizations
3008 && (tree_expr_nonnegative_p (arg0)
3009 || !HONOR_NANS (mode)))
9fca6f97 3010 {
aefa9d43
KG
3011 REAL_VALUE_TYPE dconst3;
3012 real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
9fca6f97
RG
3013 real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3014 real_round (&c2, mode, &c2);
3015 n = real_to_integer (&c2);
3016 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3017 real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3018 real_convert (&c2, mode, &c2);
3019 if (real_identical (&c2, &c)
22660666 3020 && ((optimize_insn_for_speed_p ()
9fca6f97
RG
3021 && powi_cost (n/3) <= POWI_MAX_MULTS)
3022 || n == 1))
3023 {
44e10129 3024 tree call_expr = build_call_nofold (fn, 1,narg0);
9fca6f97
RG
3025 op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3026 if (abs (n) % 3 == 2)
3027 op = expand_simple_binop (mode, MULT, op, op, op,
3028 0, OPTAB_LIB_WIDEN);
3029 if (n != 1)
3030 {
49452c07 3031 op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
9fca6f97
RG
3032 op2 = force_reg (mode, op2);
3033 op2 = expand_powi (op2, mode, abs (n / 3));
3034 op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3035 0, OPTAB_LIB_WIDEN);
3036 /* If the original exponent was negative, reciprocate the
3037 result. */
3038 if (n < 0)
3039 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3040 op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3041 }
3042 return op;
3043 }
3044 }
3045
3046 /* Fall back to optab expansion. */
13b59849 3047 return expand_builtin_mathfn_2 (exp, target, subtarget);
2082e02f
RS
3048}
3049
5039610b 3050/* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
17684d46
RG
3051 a normal call should be emitted rather than expanding the function
3052 in-line. EXP is the expression that is a call to the builtin
3053 function; if convenient, the result should be placed in TARGET. */
3054
3055static rtx
3056expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3057{
17684d46
RG
3058 tree arg0, arg1;
3059 rtx op0, op1;
3060 enum machine_mode mode;
0b8495ae 3061 enum machine_mode mode2;
17684d46 3062
5039610b
SL
3063 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3064 return NULL_RTX;
17684d46 3065
5039610b
SL
3066 arg0 = CALL_EXPR_ARG (exp, 0);
3067 arg1 = CALL_EXPR_ARG (exp, 1);
17684d46
RG
3068 mode = TYPE_MODE (TREE_TYPE (exp));
3069
3070 /* Handle constant power. */
3071
3072 if (TREE_CODE (arg1) == INTEGER_CST
455f14dd 3073 && !TREE_OVERFLOW (arg1))
17684d46
RG
3074 {
3075 HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3076
3077 /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3078 Otherwise, check the number of multiplications required. */
3079 if ((TREE_INT_CST_HIGH (arg1) == 0
3080 || TREE_INT_CST_HIGH (arg1) == -1)
3081 && ((n >= -1 && n <= 2)
22660666 3082 || (optimize_insn_for_speed_p ()
17684d46
RG
3083 && powi_cost (n) <= POWI_MAX_MULTS)))
3084 {
49452c07 3085 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
17684d46
RG
3086 op0 = force_reg (mode, op0);
3087 return expand_powi (op0, mode, n);
3088 }
3089 }
3090
3091 /* Emit a libcall to libgcc. */
3092
5039610b 3093 /* Mode of the 2nd argument must match that of an int. */
0b8495ae
FJ
3094 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3095
17684d46
RG
3096 if (target == NULL_RTX)
3097 target = gen_reg_rtx (mode);
3098
49452c07 3099 op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
17684d46
RG
3100 if (GET_MODE (op0) != mode)
3101 op0 = convert_to_mode (mode, op0, 0);
49452c07 3102 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
0b8495ae
FJ
3103 if (GET_MODE (op1) != mode2)
3104 op1 = convert_to_mode (mode2, op1, 0);
17684d46 3105
8a33f100 3106 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
84b8030f 3107 target, LCT_CONST, mode, 2,
0b8495ae 3108 op0, mode, op1, mode2);
17684d46
RG
3109
3110 return target;
3111}
3112
b8698a0f 3113/* Expand expression EXP which is a call to the strlen builtin. Return
5039610b 3114 NULL_RTX if we failed the caller should emit a normal call, otherwise
0e9295cf 3115 try to get the result in TARGET, if convenient. */
3bdf5ad1 3116
28f4ec01 3117static rtx
5039610b 3118expand_builtin_strlen (tree exp, rtx target,
4682ae04 3119 enum machine_mode target_mode)
28f4ec01 3120{
5039610b
SL
3121 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3122 return NULL_RTX;
28f4ec01
BS
3123 else
3124 {
dd05e4fa 3125 rtx pat;
5039610b
SL
3126 tree len;
3127 tree src = CALL_EXPR_ARG (exp, 0);
dd05e4fa 3128 rtx result, src_reg, char_rtx, before_strlen;
8c9b38d7 3129 enum machine_mode insn_mode = target_mode, char_mode;
a544cfd2 3130 enum insn_code icode = CODE_FOR_nothing;
712b7a05
RS
3131 int align;
3132
3133 /* If the length can be computed at compile-time, return it. */
ae808627 3134 len = c_strlen (src, 0);
712b7a05 3135 if (len)
8c9b38d7 3136 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
712b7a05 3137
ae808627
JJ
3138 /* If the length can be computed at compile-time and is constant
3139 integer, but there are side-effects in src, evaluate
3140 src for side-effects, then return len.
3141 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3142 can be optimized into: i++; x = 3; */
3143 len = c_strlen (src, 1);
3144 if (len && TREE_CODE (len) == INTEGER_CST)
3145 {
3146 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3147 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3148 }
3149
712b7a05 3150 align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
28f4ec01 3151
28f4ec01
BS
3152 /* If SRC is not a pointer type, don't do this operation inline. */
3153 if (align == 0)
5039610b 3154 return NULL_RTX;
28f4ec01 3155
dd05e4fa 3156 /* Bail out if we can't compute strlen in the right mode. */
28f4ec01
BS
3157 while (insn_mode != VOIDmode)
3158 {
166cdb08 3159 icode = optab_handler (strlen_optab, insn_mode)->insn_code;
28f4ec01 3160 if (icode != CODE_FOR_nothing)
54e43c67 3161 break;
28f4ec01
BS
3162
3163 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3164 }
3165 if (insn_mode == VOIDmode)
5039610b 3166 return NULL_RTX;
28f4ec01
BS
3167
3168 /* Make a place to write the result of the instruction. */
3169 result = target;
3170 if (! (result != 0
f8cfc6aa 3171 && REG_P (result)
28f4ec01
BS
3172 && GET_MODE (result) == insn_mode
3173 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3174 result = gen_reg_rtx (insn_mode);
3175
dd05e4fa
RH
3176 /* Make a place to hold the source address. We will not expand
3177 the actual source until we are sure that the expansion will
3178 not fail -- there are trees that cannot be expanded twice. */
3179 src_reg = gen_reg_rtx (Pmode);
28f4ec01 3180
dd05e4fa
RH
3181 /* Mark the beginning of the strlen sequence so we can emit the
3182 source operand later. */
5ab2f7b7 3183 before_strlen = get_last_insn ();
28f4ec01 3184
28f4ec01 3185 char_rtx = const0_rtx;
3bdf5ad1
RK
3186 char_mode = insn_data[(int) icode].operand[2].mode;
3187 if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3188 char_mode))
28f4ec01
BS
3189 char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3190
dd05e4fa
RH
3191 pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3192 char_rtx, GEN_INT (align));
3193 if (! pat)
5039610b 3194 return NULL_RTX;
dd05e4fa
RH
3195 emit_insn (pat);
3196
3197 /* Now that we are assured of success, expand the source. */
3198 start_sequence ();
7ce3fc8f 3199 pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
dd05e4fa
RH
3200 if (pat != src_reg)
3201 emit_move_insn (src_reg, pat);
2f937369 3202 pat = get_insns ();
dd05e4fa 3203 end_sequence ();
fca9f642
RH
3204
3205 if (before_strlen)
3206 emit_insn_after (pat, before_strlen);
3207 else
3208 emit_insn_before (pat, get_insns ());
28f4ec01
BS
3209
3210 /* Return the value in the proper mode for this function. */
8c9b38d7 3211 if (GET_MODE (result) == target_mode)
dd05e4fa 3212 target = result;
28f4ec01 3213 else if (target != 0)
dd05e4fa 3214 convert_move (target, result, 0);
28f4ec01 3215 else
8c9b38d7 3216 target = convert_to_mode (target_mode, result, 0);
dd05e4fa
RH
3217
3218 return target;
28f4ec01
BS
3219 }
3220}
3221
57814e5e
JJ
3222/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3223 bytes from constant string DATA + OFFSET and return it as target
3224 constant. */
3225
3226static rtx
4682ae04
AJ
3227builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3228 enum machine_mode mode)
57814e5e
JJ
3229{
3230 const char *str = (const char *) data;
3231
298e6adc
NS
3232 gcc_assert (offset >= 0
3233 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3234 <= strlen (str) + 1));
57814e5e
JJ
3235
3236 return c_readstr (str + offset, mode);
3237}
3238
5039610b
SL
3239/* Expand a call EXP to the memcpy builtin.
3240 Return NULL_RTX if we failed, the caller should emit a normal call,
9cb65f92 3241 otherwise try to get the result in TARGET, if convenient (and in
8fd3cf4e 3242 mode MODE if that's convenient). */
5039610b 3243
28f4ec01 3244static rtx
44e10129 3245expand_builtin_memcpy (tree exp, rtx target)
28f4ec01 3246{
5039610b
SL
3247 if (!validate_arglist (exp,
3248 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3249 return NULL_RTX;
28f4ec01
BS
3250 else
3251 {
5039610b
SL
3252 tree dest = CALL_EXPR_ARG (exp, 0);
3253 tree src = CALL_EXPR_ARG (exp, 1);
3254 tree len = CALL_EXPR_ARG (exp, 2);
57814e5e 3255 const char *src_str;
5197bd50
RK
3256 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3257 unsigned int dest_align
3258 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
28f4ec01 3259 rtx dest_mem, src_mem, dest_addr, len_rtx;
079a182e
JH
3260 HOST_WIDE_INT expected_size = -1;
3261 unsigned int expected_align = 0;
ef7eaebf 3262
c2bd38e8
RS
3263 /* If DEST is not a pointer type, call the normal function. */
3264 if (dest_align == 0)
5039610b 3265 return NULL_RTX;
c2bd38e8 3266
c2bd38e8 3267 /* If either SRC is not a pointer type, don't do this
c22cacf3 3268 operation in-line. */
c2bd38e8 3269 if (src_align == 0)
5039610b 3270 return NULL_RTX;
b8698a0f 3271
a5883ba0
MM
3272 if (currently_expanding_gimple_stmt)
3273 stringop_block_profile (currently_expanding_gimple_stmt,
3274 &expected_align, &expected_size);
726a989a 3275
079a182e
JH
3276 if (expected_align < dest_align)
3277 expected_align = dest_align;
435bb2a1 3278 dest_mem = get_memory_rtx (dest, len);
8ac61af7 3279 set_mem_align (dest_mem, dest_align);
84217346 3280 len_rtx = expand_normal (len);
57814e5e
JJ
3281 src_str = c_getstr (src);
3282
3283 /* If SRC is a string constant and block move would be done
3284 by pieces, we can avoid loading the string from memory
3285 and only stored the computed constants. */
3286 if (src_str
481683e1 3287 && CONST_INT_P (len_rtx)
57814e5e
JJ
3288 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3289 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
f883e0a7
KG
3290 CONST_CAST (char *, src_str),
3291 dest_align, false))
57814e5e 3292 {
8fd3cf4e
JJ
3293 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3294 builtin_memcpy_read_str,
f883e0a7
KG
3295 CONST_CAST (char *, src_str),
3296 dest_align, false, 0);
44e10129 3297 dest_mem = force_operand (XEXP (dest_mem, 0), target);
5ae6cd0d 3298 dest_mem = convert_memory_address (ptr_mode, dest_mem);
8fd3cf4e 3299 return dest_mem;
57814e5e
JJ
3300 }
3301
435bb2a1 3302 src_mem = get_memory_rtx (src, len);
8ac61af7 3303 set_mem_align (src_mem, src_align);
28f4ec01 3304
28f4ec01 3305 /* Copy word part most expediently. */
079a182e
JH
3306 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3307 CALL_EXPR_TAILCALL (exp)
3308 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3309 expected_align, expected_size);
28f4ec01
BS
3310
3311 if (dest_addr == 0)
aa0f70e6 3312 {
44e10129 3313 dest_addr = force_operand (XEXP (dest_mem, 0), target);
5ae6cd0d 3314 dest_addr = convert_memory_address (ptr_mode, dest_addr);
aa0f70e6 3315 }
8fd3cf4e 3316 return dest_addr;
28f4ec01
BS
3317 }
3318}
3319
5039610b
SL
3320/* Expand a call EXP to the mempcpy builtin.
3321 Return NULL_RTX if we failed; the caller should emit a normal call,
e3e9f108 3322 otherwise try to get the result in TARGET, if convenient (and in
8fd3cf4e
JJ
3323 mode MODE if that's convenient). If ENDP is 0 return the
3324 destination pointer, if ENDP is 1 return the end pointer ala
3325 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3326 stpcpy. */
e3e9f108
JJ
3327
3328static rtx
0d2a6e08 3329expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
e3e9f108 3330{
5039610b
SL
3331 if (!validate_arglist (exp,
3332 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3333 return NULL_RTX;
3334 else
3335 {
3336 tree dest = CALL_EXPR_ARG (exp, 0);
3337 tree src = CALL_EXPR_ARG (exp, 1);
3338 tree len = CALL_EXPR_ARG (exp, 2);
3339 return expand_builtin_mempcpy_args (dest, src, len,
5039610b
SL
3340 target, mode, /*endp=*/ 1);
3341 }
3342}
3343
3344/* Helper function to do the actual work for expand_builtin_mempcpy. The
3345 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3346 so that this can also be called without constructing an actual CALL_EXPR.
44e10129
MM
3347 The other arguments and return value are the same as for
3348 expand_builtin_mempcpy. */
5039610b
SL
3349
3350static rtx
44e10129 3351expand_builtin_mempcpy_args (tree dest, tree src, tree len,
5039610b
SL
3352 rtx target, enum machine_mode mode, int endp)
3353{
3354 /* If return value is ignored, transform mempcpy into memcpy. */
0d2a6e08 3355 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
8fd3cf4e
JJ
3356 {
3357 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
44e10129 3358 tree result = build_call_nofold (fn, 3, dest, src, len);
0d2a6e08 3359 return expand_expr (result, target, mode, EXPAND_NORMAL);
8fd3cf4e 3360 }
e3e9f108
JJ
3361 else
3362 {
8fd3cf4e
JJ
3363 const char *src_str;
3364 unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3365 unsigned int dest_align
3366 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3367 rtx dest_mem, src_mem, len_rtx;
c22cacf3 3368
4d9ef6a9 3369 /* If either SRC or DEST is not a pointer type, don't do this
c22cacf3 3370 operation in-line. */
4d9ef6a9 3371 if (dest_align == 0 || src_align == 0)
5039610b 3372 return NULL_RTX;
8fd3cf4e 3373
ea82015c
RS
3374 /* If LEN is not constant, call the normal function. */
3375 if (! host_integerp (len, 1))
5039610b 3376 return NULL_RTX;
33521f7d 3377
84217346 3378 len_rtx = expand_normal (len);
8fd3cf4e 3379 src_str = c_getstr (src);
e3e9f108 3380
8fd3cf4e
JJ
3381 /* If SRC is a string constant and block move would be done
3382 by pieces, we can avoid loading the string from memory
3383 and only stored the computed constants. */
3384 if (src_str
481683e1 3385 && CONST_INT_P (len_rtx)
8fd3cf4e
JJ
3386 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3387 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
f883e0a7
KG
3388 CONST_CAST (char *, src_str),
3389 dest_align, false))
8fd3cf4e 3390 {
435bb2a1 3391 dest_mem = get_memory_rtx (dest, len);
8fd3cf4e
JJ
3392 set_mem_align (dest_mem, dest_align);
3393 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3394 builtin_memcpy_read_str,
f883e0a7
KG
3395 CONST_CAST (char *, src_str),
3396 dest_align, false, endp);
8fd3cf4e 3397 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
5ae6cd0d 3398 dest_mem = convert_memory_address (ptr_mode, dest_mem);
8fd3cf4e 3399 return dest_mem;
e3e9f108
JJ
3400 }
3401
481683e1 3402 if (CONST_INT_P (len_rtx)
8fd3cf4e
JJ
3403 && can_move_by_pieces (INTVAL (len_rtx),
3404 MIN (dest_align, src_align)))
3405 {
435bb2a1 3406 dest_mem = get_memory_rtx (dest, len);
8fd3cf4e 3407 set_mem_align (dest_mem, dest_align);
435bb2a1 3408 src_mem = get_memory_rtx (src, len);
8fd3cf4e
JJ
3409 set_mem_align (src_mem, src_align);
3410 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3411 MIN (dest_align, src_align), endp);
3412 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
5ae6cd0d 3413 dest_mem = convert_memory_address (ptr_mode, dest_mem);
8fd3cf4e
JJ
3414 return dest_mem;
3415 }
3416
5039610b 3417 return NULL_RTX;
e3e9f108
JJ
3418 }
3419}
3420
beed8fc0
AO
3421#ifndef HAVE_movstr
3422# define HAVE_movstr 0
3423# define CODE_FOR_movstr CODE_FOR_nothing
3424#endif
3425
5039610b 3426/* Expand into a movstr instruction, if one is available. Return NULL_RTX if
beed8fc0
AO
3427 we failed, the caller should emit a normal call, otherwise try to
3428 get the result in TARGET, if convenient. If ENDP is 0 return the
3429 destination pointer, if ENDP is 1 return the end pointer ala
3430 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3431 stpcpy. */
3432
3433static rtx
3434expand_movstr (tree dest, tree src, rtx target, int endp)
3435{
3436 rtx end;
3437 rtx dest_mem;
3438 rtx src_mem;
3439 rtx insn;
3440 const struct insn_data * data;
3441
3442 if (!HAVE_movstr)
5039610b 3443 return NULL_RTX;
beed8fc0 3444
435bb2a1
JJ
3445 dest_mem = get_memory_rtx (dest, NULL);
3446 src_mem = get_memory_rtx (src, NULL);
beed8fc0
AO
3447 if (!endp)
3448 {
3449 target = force_reg (Pmode, XEXP (dest_mem, 0));
3450 dest_mem = replace_equiv_address (dest_mem, target);
3451 end = gen_reg_rtx (Pmode);
3452 }
3453 else
3454 {
3455 if (target == 0 || target == const0_rtx)
3456 {
3457 end = gen_reg_rtx (Pmode);
3458 if (target == 0)
3459 target = end;
3460 }
3461 else
3462 end = target;
3463 }
3464
3465 data = insn_data + CODE_FOR_movstr;
3466
3467 if (data->operand[0].mode != VOIDmode)
3468 end = gen_lowpart (data->operand[0].mode, end);
3469
3470 insn = data->genfun (end, dest_mem, src_mem);
3471
298e6adc 3472 gcc_assert (insn);
beed8fc0
AO
3473
3474 emit_insn (insn);
3475
3476 /* movstr is supposed to set end to the address of the NUL
3477 terminator. If the caller requested a mempcpy-like return value,
3478 adjust it. */
3479 if (endp == 1 && target != const0_rtx)
7ce3fc8f
UW
3480 {
3481 rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3482 emit_move_insn (target, force_operand (tem, NULL_RTX));
3483 }
beed8fc0
AO
3484
3485 return target;
3486}
3487
b8698a0f
L
3488/* Expand expression EXP, which is a call to the strcpy builtin. Return
3489 NULL_RTX if we failed the caller should emit a normal call, otherwise
5039610b 3490 try to get the result in TARGET, if convenient (and in mode MODE if that's
c2bd38e8 3491 convenient). */
fed3cef0 3492
28f4ec01 3493static rtx
44e10129 3494expand_builtin_strcpy (tree exp, rtx target)
28f4ec01 3495{
5039610b
SL
3496 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3497 {
3498 tree dest = CALL_EXPR_ARG (exp, 0);
3499 tree src = CALL_EXPR_ARG (exp, 1);
44e10129 3500 return expand_builtin_strcpy_args (dest, src, target);
5039610b
SL
3501 }
3502 return NULL_RTX;
3503}
3504
3505/* Helper function to do the actual work for expand_builtin_strcpy. The
3506 arguments to the builtin_strcpy call DEST and SRC are broken out
3507 so that this can also be called without constructing an actual CALL_EXPR.
3508 The other arguments and return value are the same as for
3509 expand_builtin_strcpy. */
3510
3511static rtx
44e10129 3512expand_builtin_strcpy_args (tree dest, tree src, rtx target)
5039610b 3513{
5039610b 3514 return expand_movstr (dest, src, target, /*endp=*/0);
28f4ec01
BS
3515}
3516
5039610b
SL
3517/* Expand a call EXP to the stpcpy builtin.
3518 Return NULL_RTX if we failed the caller should emit a normal call,
9cb65f92
KG
3519 otherwise try to get the result in TARGET, if convenient (and in
3520 mode MODE if that's convenient). */
3521
3522static rtx
609ae0e2 3523expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
9cb65f92 3524{
5039610b 3525 tree dst, src;
db3927fb 3526 location_t loc = EXPR_LOCATION (exp);
5039610b
SL
3527
3528 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3529 return NULL_RTX;
3530
3531 dst = CALL_EXPR_ARG (exp, 0);
3532 src = CALL_EXPR_ARG (exp, 1);
3533
beed8fc0 3534 /* If return value is ignored, transform stpcpy into strcpy. */
0d2a6e08 3535 if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
ad4319ec
AO
3536 {
3537 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
44e10129 3538 tree result = build_call_nofold (fn, 2, dst, src);
0d2a6e08 3539 return expand_expr (result, target, mode, EXPAND_NORMAL);
ad4319ec 3540 }
9cb65f92
KG
3541 else
3542 {
5039610b 3543 tree len, lenp1;
beed8fc0 3544 rtx ret;
e3e9f108 3545
8fd3cf4e 3546 /* Ensure we get an actual string whose length can be evaluated at
c22cacf3
MS
3547 compile-time, not an expression containing a string. This is
3548 because the latter will potentially produce pessimized code
3549 when used to produce the return value. */
ae808627 3550 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
5039610b 3551 return expand_movstr (dst, src, target, /*endp=*/2);
9cb65f92 3552
db3927fb 3553 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
44e10129 3554 ret = expand_builtin_mempcpy_args (dst, src, lenp1,
5039610b 3555 target, mode, /*endp=*/2);
beed8fc0
AO
3556
3557 if (ret)
3558 return ret;
3559
3560 if (TREE_CODE (len) == INTEGER_CST)
3561 {
84217346 3562 rtx len_rtx = expand_normal (len);
beed8fc0 3563
481683e1 3564 if (CONST_INT_P (len_rtx))
beed8fc0 3565 {
44e10129 3566 ret = expand_builtin_strcpy_args (dst, src, target);
beed8fc0
AO
3567
3568 if (ret)
3569 {
3570 if (! target)
58ec6ece
SE
3571 {
3572 if (mode != VOIDmode)
3573 target = gen_reg_rtx (mode);
3574 else
3575 target = gen_reg_rtx (GET_MODE (ret));
3576 }
beed8fc0
AO
3577 if (GET_MODE (target) != GET_MODE (ret))
3578 ret = gen_lowpart (GET_MODE (target), ret);
3579
7ce3fc8f
UW
3580 ret = plus_constant (ret, INTVAL (len_rtx));
3581 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
298e6adc 3582 gcc_assert (ret);
beed8fc0
AO
3583
3584 return target;
3585 }
3586 }
3587 }
3588
5039610b 3589 return expand_movstr (dst, src, target, /*endp=*/2);
9cb65f92
KG
3590 }
3591}
3592
57814e5e
JJ
3593/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3594 bytes from constant string DATA + OFFSET and return it as target
3595 constant. */
3596
14a43348 3597rtx
4682ae04
AJ
3598builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3599 enum machine_mode mode)
57814e5e
JJ
3600{
3601 const char *str = (const char *) data;
3602
3603 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3604 return const0_rtx;
3605
3606 return c_readstr (str + offset, mode);
3607}
3608
b8698a0f 3609/* Expand expression EXP, which is a call to the strncpy builtin. Return
5039610b 3610 NULL_RTX if we failed the caller should emit a normal call. */
da9e9f08
KG
3611
3612static rtx
44e10129 3613expand_builtin_strncpy (tree exp, rtx target)
da9e9f08 3614{
db3927fb 3615 location_t loc = EXPR_LOCATION (exp);
5039610b
SL
3616
3617 if (validate_arglist (exp,
3618 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
da9e9f08 3619 {
5039610b
SL
3620 tree dest = CALL_EXPR_ARG (exp, 0);
3621 tree src = CALL_EXPR_ARG (exp, 1);
3622 tree len = CALL_EXPR_ARG (exp, 2);
3623 tree slen = c_strlen (src, 1);
57814e5e 3624
559837f7
KG
3625 /* We must be passed a constant len and src parameter. */
3626 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
5039610b 3627 return NULL_RTX;
da9e9f08 3628
db3927fb 3629 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
da9e9f08
KG
3630
3631 /* We're required to pad with trailing zeros if the requested
c22cacf3 3632 len is greater than strlen(s2)+1. In that case try to
57814e5e 3633 use store_by_pieces, if it fails, punt. */
da9e9f08 3634 if (tree_int_cst_lt (slen, len))
57814e5e 3635 {
5197bd50
RK
3636 unsigned int dest_align
3637 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
5039610b 3638 const char *p = c_getstr (src);
57814e5e
JJ
3639 rtx dest_mem;
3640
5197bd50
RK
3641 if (!p || dest_align == 0 || !host_integerp (len, 1)
3642 || !can_store_by_pieces (tree_low_cst (len, 1),
57814e5e 3643 builtin_strncpy_read_str,
f883e0a7
KG
3644 CONST_CAST (char *, p),
3645 dest_align, false))
5039610b 3646 return NULL_RTX;
57814e5e 3647
435bb2a1 3648 dest_mem = get_memory_rtx (dest, len);
5197bd50 3649 store_by_pieces (dest_mem, tree_low_cst (len, 1),
57814e5e 3650 builtin_strncpy_read_str,
f883e0a7 3651 CONST_CAST (char *, p), dest_align, false, 0);
44e10129 3652 dest_mem = force_operand (XEXP (dest_mem, 0), target);
5ae6cd0d 3653 dest_mem = convert_memory_address (ptr_mode, dest_mem);
aa0f70e6 3654 return dest_mem;
57814e5e 3655 }
da9e9f08 3656 }
5039610b 3657 return NULL_RTX;
da9e9f08
KG
3658}
3659
ab937357
JJ
3660/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3661 bytes from constant string DATA + OFFSET and return it as target
3662 constant. */
3663
34d85166 3664rtx
4682ae04
AJ
3665builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3666 enum machine_mode mode)
ab937357
JJ
3667{
3668 const char *c = (const char *) data;
f883e0a7 3669 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
ab937357
JJ
3670
3671 memset (p, *c, GET_MODE_SIZE (mode));
3672
3673 return c_readstr (p, mode);
3674}
3675
1a887f86
RS
3676/* Callback routine for store_by_pieces. Return the RTL of a register
3677 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3678 char value given in the RTL register data. For example, if mode is
3679 4 bytes wide, return the RTL for 0x01010101*data. */
3680
3681static rtx
4682ae04
AJ
3682builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3683 enum machine_mode mode)
1a887f86
RS
3684{
3685 rtx target, coeff;
3686 size_t size;
3687 char *p;
3688
3689 size = GET_MODE_SIZE (mode);
5ab2f7b7
KH
3690 if (size == 1)
3691 return (rtx) data;
1a887f86 3692
f883e0a7 3693 p = XALLOCAVEC (char, size);
1a887f86
RS
3694 memset (p, 1, size);
3695 coeff = c_readstr (p, mode);
3696
5ab2f7b7 3697 target = convert_to_mode (mode, (rtx) data, 1);
1a887f86
RS
3698 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3699 return force_reg (mode, target);
3700}
3701
b8698a0f
L
3702/* Expand expression EXP, which is a call to the memset builtin. Return
3703 NULL_RTX if we failed the caller should emit a normal call, otherwise
5039610b 3704 try to get the result in TARGET, if convenient (and in mode MODE if that's
c2bd38e8 3705 convenient). */
fed3cef0 3706
28f4ec01 3707static rtx
5039610b 3708expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
28f4ec01 3709{
5039610b
SL
3710 if (!validate_arglist (exp,
3711 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3712 return NULL_RTX;
28f4ec01
BS
3713 else
3714 {
5039610b
SL
3715 tree dest = CALL_EXPR_ARG (exp, 0);
3716 tree val = CALL_EXPR_ARG (exp, 1);
3717 tree len = CALL_EXPR_ARG (exp, 2);
3718 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3719 }
3720}
28f4ec01 3721
5039610b
SL
3722/* Helper function to do the actual work for expand_builtin_memset. The
3723 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3724 so that this can also be called without constructing an actual CALL_EXPR.
3725 The other arguments and return value are the same as for
3726 expand_builtin_memset. */
880864cf 3727
5039610b
SL
3728static rtx
3729expand_builtin_memset_args (tree dest, tree val, tree len,
3730 rtx target, enum machine_mode mode, tree orig_exp)
3731{
3732 tree fndecl, fn;
3733 enum built_in_function fcode;
3734 char c;
3735 unsigned int dest_align;
3736 rtx dest_mem, dest_addr, len_rtx;
3737 HOST_WIDE_INT expected_size = -1;
3738 unsigned int expected_align = 0;
28f4ec01 3739
5039610b 3740 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
079a182e 3741
5039610b
SL
3742 /* If DEST is not a pointer type, don't do this operation in-line. */
3743 if (dest_align == 0)
3744 return NULL_RTX;
c2bd38e8 3745
a5883ba0
MM
3746 if (currently_expanding_gimple_stmt)
3747 stringop_block_profile (currently_expanding_gimple_stmt,
3748 &expected_align, &expected_size);
726a989a 3749
5039610b
SL
3750 if (expected_align < dest_align)
3751 expected_align = dest_align;
880864cf 3752
5039610b
SL
3753 /* If the LEN parameter is zero, return DEST. */
3754 if (integer_zerop (len))
3755 {
3756 /* Evaluate and ignore VAL in case it has side-effects. */
3757 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3758 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3759 }
57e84f18 3760
5039610b
SL
3761 /* Stabilize the arguments in case we fail. */
3762 dest = builtin_save_expr (dest);
3763 val = builtin_save_expr (val);
3764 len = builtin_save_expr (len);
1a887f86 3765
5039610b
SL
3766 len_rtx = expand_normal (len);
3767 dest_mem = get_memory_rtx (dest, len);
1a887f86 3768
5039610b
SL
3769 if (TREE_CODE (val) != INTEGER_CST)
3770 {
3771 rtx val_rtx;
1a887f86 3772
5039610b
SL
3773 val_rtx = expand_normal (val);
3774 val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3775 val_rtx, 0);
28f4ec01 3776
5039610b
SL
3777 /* Assume that we can memset by pieces if we can store
3778 * the coefficients by pieces (in the required modes).
3779 * We can't pass builtin_memset_gen_str as that emits RTL. */
3780 c = 1;
3781 if (host_integerp (len, 1)
5039610b 3782 && can_store_by_pieces (tree_low_cst (len, 1),
cfa31150
SL
3783 builtin_memset_read_str, &c, dest_align,
3784 true))
5039610b
SL
3785 {
3786 val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3787 val_rtx);
3788 store_by_pieces (dest_mem, tree_low_cst (len, 1),
cfa31150
SL
3789 builtin_memset_gen_str, val_rtx, dest_align,
3790 true, 0);
5039610b
SL
3791 }
3792 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3793 dest_align, expected_align,
3794 expected_size))
880864cf 3795 goto do_libcall;
b8698a0f 3796
5039610b
SL
3797 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3798 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3799 return dest_mem;
3800 }
28f4ec01 3801
5039610b
SL
3802 if (target_char_cast (val, &c))
3803 goto do_libcall;
ab937357 3804
5039610b
SL
3805 if (c)
3806 {
3807 if (host_integerp (len, 1)
5039610b 3808 && can_store_by_pieces (tree_low_cst (len, 1),
cfa31150
SL
3809 builtin_memset_read_str, &c, dest_align,
3810 true))
5039610b 3811 store_by_pieces (dest_mem, tree_low_cst (len, 1),
cfa31150 3812 builtin_memset_read_str, &c, dest_align, true, 0);
5039610b
SL
3813 else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3814 dest_align, expected_align,
3815 expected_size))
3816 goto do_libcall;
b8698a0f 3817
5039610b
SL
3818 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3819 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3820 return dest_mem;
3821 }
ab937357 3822
5039610b
SL
3823 set_mem_align (dest_mem, dest_align);
3824 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3825 CALL_EXPR_TAILCALL (orig_exp)
3826 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3827 expected_align, expected_size);
28f4ec01 3828
5039610b
SL
3829 if (dest_addr == 0)
3830 {
3831 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3832 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3833 }
28f4ec01 3834
5039610b 3835 return dest_addr;
880864cf 3836
5039610b
SL
3837 do_libcall:
3838 fndecl = get_callee_fndecl (orig_exp);
3839 fcode = DECL_FUNCTION_CODE (fndecl);
3840 if (fcode == BUILT_IN_MEMSET)
44e10129 3841 fn = build_call_nofold (fndecl, 3, dest, val, len);
5039610b 3842 else if (fcode == BUILT_IN_BZERO)
44e10129 3843 fn = build_call_nofold (fndecl, 2, dest, len);
5039610b
SL
3844 else
3845 gcc_unreachable ();
44e10129
MM
3846 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3847 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
5039610b 3848 return expand_call (fn, target, target == const0_rtx);
28f4ec01
BS
3849}
3850
b8698a0f 3851/* Expand expression EXP, which is a call to the bzero builtin. Return
5039610b 3852 NULL_RTX if we failed the caller should emit a normal call. */
5197bd50 3853
e3a709be 3854static rtx
8148fe65 3855expand_builtin_bzero (tree exp)
e3a709be 3856{
5039610b 3857 tree dest, size;
db3927fb 3858 location_t loc = EXPR_LOCATION (exp);
e3a709be 3859
5039610b 3860 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3477addf 3861 return NULL_RTX;
e3a709be 3862
5039610b
SL
3863 dest = CALL_EXPR_ARG (exp, 0);
3864 size = CALL_EXPR_ARG (exp, 1);
8d51ecf8 3865
3477addf 3866 /* New argument list transforming bzero(ptr x, int y) to
c2bd38e8
RS
3867 memset(ptr x, int 0, size_t y). This is done this way
3868 so that if it isn't expanded inline, we fallback to
3869 calling bzero instead of memset. */
8d51ecf8 3870
5039610b 3871 return expand_builtin_memset_args (dest, integer_zero_node,
db3927fb 3872 fold_convert_loc (loc, sizetype, size),
5039610b 3873 const0_rtx, VOIDmode, exp);
e3a709be
KG
3874}
3875
2be3b5ce 3876/* Expand expression EXP, which is a call to the memcmp built-in function.
5039610b 3877 Return NULL_RTX if we failed and the
28f4ec01 3878 caller should emit a normal call, otherwise try to get the result in
c2bd38e8 3879 TARGET, if convenient (and in mode MODE, if that's convenient). */
5197bd50 3880
28f4ec01 3881static rtx
44e10129
MM
3882expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3883 ATTRIBUTE_UNUSED enum machine_mode mode)
28f4ec01 3884{
44e10129 3885 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
db3927fb 3886
5039610b
SL
3887 if (!validate_arglist (exp,
3888 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3889 return NULL_RTX;
c2bd38e8 3890
40c1d5f8 3891#if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
28f4ec01 3892 {
8878e913 3893 rtx arg1_rtx, arg2_rtx, arg3_rtx;
28f4ec01 3894 rtx result;
8878e913 3895 rtx insn;
5039610b
SL
3896 tree arg1 = CALL_EXPR_ARG (exp, 0);
3897 tree arg2 = CALL_EXPR_ARG (exp, 1);
3898 tree len = CALL_EXPR_ARG (exp, 2);
28f4ec01
BS
3899
3900 int arg1_align
3901 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3902 int arg2_align
3903 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
358b8f01
JJ
3904 enum machine_mode insn_mode;
3905
3906#ifdef HAVE_cmpmemsi
3907 if (HAVE_cmpmemsi)
3908 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3909 else
3910#endif
40c1d5f8
AS
3911#ifdef HAVE_cmpstrnsi
3912 if (HAVE_cmpstrnsi)
3913 insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
358b8f01
JJ
3914 else
3915#endif
5039610b 3916 return NULL_RTX;
28f4ec01
BS
3917
3918 /* If we don't have POINTER_TYPE, call the function. */
3919 if (arg1_align == 0 || arg2_align == 0)
5039610b 3920 return NULL_RTX;
28f4ec01
BS
3921
3922 /* Make a place to write the result of the instruction. */
3923 result = target;
3924 if (! (result != 0
f8cfc6aa 3925 && REG_P (result) && GET_MODE (result) == insn_mode
28f4ec01
BS
3926 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3927 result = gen_reg_rtx (insn_mode);
3928
435bb2a1
JJ
3929 arg1_rtx = get_memory_rtx (arg1, len);
3930 arg2_rtx = get_memory_rtx (arg2, len);
db3927fb 3931 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
6cbaec9e
UW
3932
3933 /* Set MEM_SIZE as appropriate. */
481683e1 3934 if (CONST_INT_P (arg3_rtx))
6cbaec9e
UW
3935 {
3936 set_mem_size (arg1_rtx, arg3_rtx);
3937 set_mem_size (arg2_rtx, arg3_rtx);
3938 }
3939
358b8f01
JJ
3940#ifdef HAVE_cmpmemsi
3941 if (HAVE_cmpmemsi)
3942 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3943 GEN_INT (MIN (arg1_align, arg2_align)));
8878e913 3944 else
358b8f01 3945#endif
40c1d5f8
AS
3946#ifdef HAVE_cmpstrnsi
3947 if (HAVE_cmpstrnsi)
3948 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3949 GEN_INT (MIN (arg1_align, arg2_align)));
358b8f01
JJ
3950 else
3951#endif
298e6adc 3952 gcc_unreachable ();
8878e913
JH
3953
3954 if (insn)
3955 emit_insn (insn);
3956 else
84b8030f 3957 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
8878e913
JH
3958 TYPE_MODE (integer_type_node), 3,
3959 XEXP (arg1_rtx, 0), Pmode,
3960 XEXP (arg2_rtx, 0), Pmode,
3961 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
8df83eae 3962 TYPE_UNSIGNED (sizetype)),
8878e913 3963 TYPE_MODE (sizetype));
28f4ec01
BS
3964
3965 /* Return the value in the proper mode for this function. */
3966 mode = TYPE_MODE (TREE_TYPE (exp));
3967 if (GET_MODE (result) == mode)
3968 return result;
3969 else if (target != 0)
3970 {
3971 convert_move (target, result, 0);
3972 return target;
3973 }
3974 else
3975 return convert_to_mode (mode, result, 0);
3976 }
2dee4af1 3977#endif
28f4ec01 3978
5039610b 3979 return NULL_RTX;
c2bd38e8
RS
3980}
3981
5039610b 3982/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
28f4ec01
BS
3983 if we failed the caller should emit a normal call, otherwise try to get
3984 the result in TARGET, if convenient. */
fed3cef0 3985
28f4ec01 3986static rtx
44e10129 3987expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
28f4ec01 3988{
5039610b
SL
3989 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3990 return NULL_RTX;
8d51ecf8 3991
40c1d5f8
AS
3992#if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3993 if (cmpstr_optab[SImode] != CODE_FOR_nothing
3994 || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3995 {
3996 rtx arg1_rtx, arg2_rtx;
3997 rtx result, insn = NULL_RTX;
3998 tree fndecl, fn;
5039610b
SL
3999 tree arg1 = CALL_EXPR_ARG (exp, 0);
4000 tree arg2 = CALL_EXPR_ARG (exp, 1);
c22cacf3 4001
40c1d5f8
AS
4002 int arg1_align
4003 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4004 int arg2_align
4005 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4006
4007 /* If we don't have POINTER_TYPE, call the function. */
4008 if (arg1_align == 0 || arg2_align == 0)
5039610b 4009 return NULL_RTX;
2be3b5ce 4010
40c1d5f8
AS
4011 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
4012 arg1 = builtin_save_expr (arg1);
4013 arg2 = builtin_save_expr (arg2);
2be3b5ce 4014
435bb2a1
JJ
4015 arg1_rtx = get_memory_rtx (arg1, NULL);
4016 arg2_rtx = get_memory_rtx (arg2, NULL);
28f4ec01 4017
40c1d5f8
AS
4018#ifdef HAVE_cmpstrsi
4019 /* Try to call cmpstrsi. */
4020 if (HAVE_cmpstrsi)
4021 {
c22cacf3 4022 enum machine_mode insn_mode
40c1d5f8
AS
4023 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4024
4025 /* Make a place to write the result of the instruction. */
4026 result = target;
4027 if (! (result != 0
4028 && REG_P (result) && GET_MODE (result) == insn_mode
4029 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4030 result = gen_reg_rtx (insn_mode);
4031
4032 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4033 GEN_INT (MIN (arg1_align, arg2_align)));
4034 }
4035#endif
3425c35f 4036#ifdef HAVE_cmpstrnsi
40c1d5f8 4037 /* Try to determine at least one length and call cmpstrnsi. */
c22cacf3 4038 if (!insn && HAVE_cmpstrnsi)
40c1d5f8
AS
4039 {
4040 tree len;
4041 rtx arg3_rtx;
4042
c22cacf3 4043 enum machine_mode insn_mode
40c1d5f8
AS
4044 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4045 tree len1 = c_strlen (arg1, 1);
4046 tree len2 = c_strlen (arg2, 1);
4047
4048 if (len1)
4049 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4050 if (len2)
4051 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4052
4053 /* If we don't have a constant length for the first, use the length
4054 of the second, if we know it. We don't require a constant for
4055 this case; some cost analysis could be done if both are available
4056 but neither is constant. For now, assume they're equally cheap,
4057 unless one has side effects. If both strings have constant lengths,
4058 use the smaller. */
4059
4060 if (!len1)
4061 len = len2;
4062 else if (!len2)
4063 len = len1;
4064 else if (TREE_SIDE_EFFECTS (len1))
4065 len = len2;
4066 else if (TREE_SIDE_EFFECTS (len2))
4067 len = len1;
4068 else if (TREE_CODE (len1) != INTEGER_CST)
4069 len = len2;
4070 else if (TREE_CODE (len2) != INTEGER_CST)
4071 len = len1;
4072 else if (tree_int_cst_lt (len1, len2))
4073 len = len1;
4074 else
4075 len = len2;
4076
4077 /* If both arguments have side effects, we cannot optimize. */
4078 if (!len || TREE_SIDE_EFFECTS (len))
880864cf 4079 goto do_libcall;
28f4ec01 4080
84217346 4081 arg3_rtx = expand_normal (len);
fed3cef0 4082
40c1d5f8
AS
4083 /* Make a place to write the result of the instruction. */
4084 result = target;
4085 if (! (result != 0
4086 && REG_P (result) && GET_MODE (result) == insn_mode
4087 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4088 result = gen_reg_rtx (insn_mode);
28f4ec01 4089
40c1d5f8
AS
4090 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4091 GEN_INT (MIN (arg1_align, arg2_align)));
4092 }
4093#endif
c43fa1f5 4094
40c1d5f8
AS
4095 if (insn)
4096 {
44e10129 4097 enum machine_mode mode;
40c1d5f8 4098 emit_insn (insn);
c43fa1f5 4099
40c1d5f8
AS
4100 /* Return the value in the proper mode for this function. */
4101 mode = TYPE_MODE (TREE_TYPE (exp));
4102 if (GET_MODE (result) == mode)
4103 return result;
4104 if (target == 0)
4105 return convert_to_mode (mode, result, 0);
4106 convert_move (target, result, 0);
4107 return target;
4108 }
fed3cef0 4109
40c1d5f8
AS
4110 /* Expand the library call ourselves using a stabilized argument
4111 list to avoid re-evaluating the function's arguments twice. */
c2f07c00 4112#ifdef HAVE_cmpstrnsi
880864cf 4113 do_libcall:
c2f07c00 4114#endif
40c1d5f8 4115 fndecl = get_callee_fndecl (exp);
44e10129
MM
4116 fn = build_call_nofold (fndecl, 2, arg1, arg2);
4117 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4118 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
40c1d5f8
AS
4119 return expand_call (fn, target, target == const0_rtx);
4120 }
2be3b5ce 4121#endif
5039610b 4122 return NULL_RTX;
2dee4af1 4123}
28f4ec01 4124
b8698a0f 4125/* Expand expression EXP, which is a call to the strncmp builtin. Return
5039610b 4126 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
da9e9f08 4127 the result in TARGET, if convenient. */
5197bd50 4128
da9e9f08 4129static rtx
44e10129
MM
4130expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
4131 ATTRIBUTE_UNUSED enum machine_mode mode)
da9e9f08 4132{
44e10129 4133 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
db3927fb 4134
5039610b
SL
4135 if (!validate_arglist (exp,
4136 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4137 return NULL_RTX;
da9e9f08 4138
819c1488 4139 /* If c_strlen can determine an expression for one of the string
40c1d5f8 4140 lengths, and it doesn't have side effects, then emit cmpstrnsi
2be3b5ce 4141 using length MIN(strlen(string)+1, arg3). */
40c1d5f8
AS
4142#ifdef HAVE_cmpstrnsi
4143 if (HAVE_cmpstrnsi)
2be3b5ce
RS
4144 {
4145 tree len, len1, len2;
4146 rtx arg1_rtx, arg2_rtx, arg3_rtx;
4147 rtx result, insn;
8148fe65 4148 tree fndecl, fn;
5039610b
SL
4149 tree arg1 = CALL_EXPR_ARG (exp, 0);
4150 tree arg2 = CALL_EXPR_ARG (exp, 1);
4151 tree arg3 = CALL_EXPR_ARG (exp, 2);
c2bd38e8 4152
2be3b5ce
RS
4153 int arg1_align
4154 = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4155 int arg2_align
4156 = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4157 enum machine_mode insn_mode
40c1d5f8 4158 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
8d51ecf8 4159
ae808627
JJ
4160 len1 = c_strlen (arg1, 1);
4161 len2 = c_strlen (arg2, 1);
2be3b5ce
RS
4162
4163 if (len1)
db3927fb 4164 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
2be3b5ce 4165 if (len2)
db3927fb 4166 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
2be3b5ce
RS
4167
4168 /* If we don't have a constant length for the first, use the length
4169 of the second, if we know it. We don't require a constant for
4170 this case; some cost analysis could be done if both are available
4171 but neither is constant. For now, assume they're equally cheap,
4172 unless one has side effects. If both strings have constant lengths,
4173 use the smaller. */
4174
4175 if (!len1)
4176 len = len2;
4177 else if (!len2)
4178 len = len1;
4179 else if (TREE_SIDE_EFFECTS (len1))
4180 len = len2;
4181 else if (TREE_SIDE_EFFECTS (len2))
4182 len = len1;
4183 else if (TREE_CODE (len1) != INTEGER_CST)
4184 len = len2;
4185 else if (TREE_CODE (len2) != INTEGER_CST)
4186 len = len1;
4187 else if (tree_int_cst_lt (len1, len2))
4188 len = len1;
4189 else
4190 len = len2;
819c1488 4191
2be3b5ce
RS
4192 /* If both arguments have side effects, we cannot optimize. */
4193 if (!len || TREE_SIDE_EFFECTS (len))
5039610b 4194 return NULL_RTX;
8d51ecf8 4195
2be3b5ce 4196 /* The actual new length parameter is MIN(len,arg3). */
db3927fb
AH
4197 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
4198 fold_convert_loc (loc, TREE_TYPE (len), arg3));
2be3b5ce
RS
4199
4200 /* If we don't have POINTER_TYPE, call the function. */
4201 if (arg1_align == 0 || arg2_align == 0)
5039610b 4202 return NULL_RTX;
2be3b5ce
RS
4203
4204 /* Make a place to write the result of the instruction. */
4205 result = target;
4206 if (! (result != 0
f8cfc6aa 4207 && REG_P (result) && GET_MODE (result) == insn_mode
2be3b5ce
RS
4208 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4209 result = gen_reg_rtx (insn_mode);
4210
44e10129
MM
4211 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
4212 arg1 = builtin_save_expr (arg1);
4213 arg2 = builtin_save_expr (arg2);
4214 len = builtin_save_expr (len);
5197bd50 4215
44e10129
MM
4216 arg1_rtx = get_memory_rtx (arg1, len);
4217 arg2_rtx = get_memory_rtx (arg2, len);
4218 arg3_rtx = expand_normal (len);
4219 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4220 GEN_INT (MIN (arg1_align, arg2_align)));
4221 if (insn)
4222 {
4223 emit_insn (insn);
d118937d 4224
44e10129
MM
4225 /* Return the value in the proper mode for this function. */
4226 mode = TYPE_MODE (TREE_TYPE (exp));
4227 if (GET_MODE (result) == mode)
4228 return result;
4229 if (target == 0)
4230 return convert_to_mode (mode, result, 0);
4231 convert_move (target, result, 0);
4232 return target;
4233 }
5197bd50 4234
44e10129
MM
4235 /* Expand the library call ourselves using a stabilized argument
4236 list to avoid re-evaluating the function's arguments twice. */
4237 fndecl = get_callee_fndecl (exp);
4238 fn = build_call_nofold (fndecl, 3, arg1, arg2, len);
4239 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4240 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4241 return expand_call (fn, target, target == const0_rtx);
4242 }
4243#endif
5039610b 4244 return NULL_RTX;
d118937d
KG
4245}
4246
d3707adb
RH
4247/* Expand a call to __builtin_saveregs, generating the result in TARGET,
4248 if that's convenient. */
fed3cef0 4249
d3707adb 4250rtx
4682ae04 4251expand_builtin_saveregs (void)
28f4ec01 4252{
d3707adb 4253 rtx val, seq;
28f4ec01
BS
4254
4255 /* Don't do __builtin_saveregs more than once in a function.
4256 Save the result of the first call and reuse it. */
4257 if (saveregs_value != 0)
4258 return saveregs_value;
28f4ec01 4259
d3707adb
RH
4260 /* When this function is called, it means that registers must be
4261 saved on entry to this function. So we migrate the call to the
4262 first insn of this function. */
4263
4264 start_sequence ();
28f4ec01 4265
d3707adb 4266 /* Do whatever the machine needs done in this case. */
61f71b34 4267 val = targetm.calls.expand_builtin_saveregs ();
28f4ec01 4268
d3707adb
RH
4269 seq = get_insns ();
4270 end_sequence ();
28f4ec01 4271
d3707adb 4272 saveregs_value = val;
28f4ec01 4273
2f937369
DM
4274 /* Put the insns after the NOTE that starts the function. If this
4275 is inside a start_sequence, make the outer-level insn chain current, so
d3707adb
RH
4276 the code is placed at the start of the function. */
4277 push_topmost_sequence ();
242229bb 4278 emit_insn_after (seq, entry_of_function ());
d3707adb
RH
4279 pop_topmost_sequence ();
4280
4281 return val;
28f4ec01
BS
4282}
4283
4284/* __builtin_args_info (N) returns word N of the arg space info
4285 for the current function. The number and meanings of words
4286 is controlled by the definition of CUMULATIVE_ARGS. */
3bdf5ad1 4287
28f4ec01 4288static rtx
5039610b 4289expand_builtin_args_info (tree exp)
28f4ec01 4290{
28f4ec01 4291 int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
38173d38 4292 int *word_ptr = (int *) &crtl->args.info;
28f4ec01 4293
298e6adc 4294 gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
28f4ec01 4295
5039610b 4296 if (call_expr_nargs (exp) != 0)
28f4ec01 4297 {
5039610b 4298 if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
971801ff 4299 error ("argument of %<__builtin_args_info%> must be constant");
28f4ec01
BS
4300 else
4301 {
5039610b 4302 HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
28f4ec01 4303
5197bd50 4304 if (wordnum < 0 || wordnum >= nwords)
971801ff 4305 error ("argument of %<__builtin_args_info%> out of range");
28f4ec01
BS
4306 else
4307 return GEN_INT (word_ptr[wordnum]);
4308 }
4309 }
4310 else
971801ff 4311 error ("missing argument in %<__builtin_args_info%>");
28f4ec01
BS
4312
4313 return const0_rtx;
28f4ec01
BS
4314}
4315
8870e212 4316/* Expand a call to __builtin_next_arg. */
5197bd50 4317
28f4ec01 4318static rtx
8870e212 4319expand_builtin_next_arg (void)
28f4ec01 4320{
8870e212
JJ
4321 /* Checking arguments is already done in fold_builtin_next_arg
4322 that must be called before this function. */
4319e38c 4323 return expand_binop (ptr_mode, add_optab,
38173d38
JH
4324 crtl->args.internal_arg_pointer,
4325 crtl->args.arg_offset_rtx,
28f4ec01
BS
4326 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4327}
4328
d3707adb
RH
4329/* Make it easier for the backends by protecting the valist argument
4330 from multiple evaluations. */
4331
4332static tree
db3927fb 4333stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
d3707adb 4334{
35cbb299
KT
4335 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4336
4337 gcc_assert (vatype != NULL_TREE);
4338
4339 if (TREE_CODE (vatype) == ARRAY_TYPE)
d3707adb 4340 {
9f720c3e
GK
4341 if (TREE_SIDE_EFFECTS (valist))
4342 valist = save_expr (valist);
8ebecc3b 4343
9f720c3e 4344 /* For this case, the backends will be expecting a pointer to
35cbb299
KT
4345 vatype, but it's possible we've actually been given an array
4346 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
9f720c3e
GK
4347 So fix it. */
4348 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
daf68dd7 4349 {
35cbb299 4350 tree p1 = build_pointer_type (TREE_TYPE (vatype));
db3927fb 4351 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
daf68dd7 4352 }
d3707adb 4353 }
8ebecc3b 4354 else
d3707adb 4355 {
9f720c3e 4356 tree pt;
8ebecc3b 4357
9f720c3e
GK
4358 if (! needs_lvalue)
4359 {
8ebecc3b
RH
4360 if (! TREE_SIDE_EFFECTS (valist))
4361 return valist;
8d51ecf8 4362
35cbb299 4363 pt = build_pointer_type (vatype);
db3927fb 4364 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
d3707adb 4365 TREE_SIDE_EFFECTS (valist) = 1;
d3707adb 4366 }
9f720c3e 4367
8ebecc3b 4368 if (TREE_SIDE_EFFECTS (valist))
9f720c3e 4369 valist = save_expr (valist);
db3927fb 4370 valist = build_fold_indirect_ref_loc (loc, valist);
d3707adb
RH
4371 }
4372
4373 return valist;
4374}
4375
c35d187f
RH
4376/* The "standard" definition of va_list is void*. */
4377
4378tree
4379std_build_builtin_va_list (void)
4380{
4381 return ptr_type_node;
4382}
4383
35cbb299
KT
4384/* The "standard" abi va_list is va_list_type_node. */
4385
4386tree
4387std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4388{
4389 return va_list_type_node;
4390}
4391
4392/* The "standard" type of va_list is va_list_type_node. */
4393
4394tree
4395std_canonical_va_list_type (tree type)
4396{
4397 tree wtype, htype;
4398
4399 if (INDIRECT_REF_P (type))
4400 type = TREE_TYPE (type);
4401 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4402 type = TREE_TYPE (type);
35cbb299
KT
4403 wtype = va_list_type_node;
4404 htype = type;
e65d1ec6
KT
4405 /* Treat structure va_list types. */
4406 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4407 htype = TREE_TYPE (htype);
4408 else if (TREE_CODE (wtype) == ARRAY_TYPE)
35cbb299
KT
4409 {
4410 /* If va_list is an array type, the argument may have decayed
4411 to a pointer type, e.g. by being passed to another function.
4412 In that case, unwrap both types so that we can compare the
4413 underlying records. */
4414 if (TREE_CODE (htype) == ARRAY_TYPE
4415 || POINTER_TYPE_P (htype))
4416 {
4417 wtype = TREE_TYPE (wtype);
4418 htype = TREE_TYPE (htype);
4419 }
4420 }
4421 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4422 return va_list_type_node;
4423
4424 return NULL_TREE;
4425}
4426
d3707adb
RH
4427/* The "standard" implementation of va_start: just assign `nextarg' to
4428 the variable. */
5197bd50 4429
d3707adb 4430void
4682ae04 4431std_expand_builtin_va_start (tree valist, rtx nextarg)
d3707adb 4432{
508dabda
ILT
4433 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4434 convert_move (va_r, nextarg, 0);
d3707adb
RH
4435}
4436
5039610b 4437/* Expand EXP, a call to __builtin_va_start. */
5197bd50 4438
d3707adb 4439static rtx
5039610b 4440expand_builtin_va_start (tree exp)
d3707adb
RH
4441{
4442 rtx nextarg;
5039610b 4443 tree valist;
db3927fb 4444 location_t loc = EXPR_LOCATION (exp);
d3707adb 4445
5039610b 4446 if (call_expr_nargs (exp) < 2)
c69c9b36 4447 {
db3927fb 4448 error_at (loc, "too few arguments to function %<va_start%>");
c69c9b36
JM
4449 return const0_rtx;
4450 }
d3707adb 4451
5039610b 4452 if (fold_builtin_next_arg (exp, true))
8870e212 4453 return const0_rtx;
d3147f64 4454
8870e212 4455 nextarg = expand_builtin_next_arg ();
db3927fb 4456 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
d3707adb 4457
d7bd8aeb
JJ
4458 if (targetm.expand_builtin_va_start)
4459 targetm.expand_builtin_va_start (valist, nextarg);
4460 else
4461 std_expand_builtin_va_start (valist, nextarg);
d3707adb
RH
4462
4463 return const0_rtx;
4464}
4465
d3707adb
RH
4466/* The "standard" implementation of va_arg: read the value from the
4467 current (padded) address and increment by the (padded) size. */
3bdf5ad1 4468
23a60a04 4469tree
726a989a
RB
4470std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4471 gimple_seq *post_p)
cd3ce9b4 4472{
e4d3eef1 4473 tree addr, t, type_size, rounded_size, valist_tmp;
07b8df0a 4474 unsigned HOST_WIDE_INT align, boundary;
af064de5 4475 bool indirect;
e4d3eef1
RH
4476
4477#ifdef ARGS_GROW_DOWNWARD
4478 /* All of the alignment and movement below is for args-grow-up machines.
4479 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4480 implement their own specialized gimplify_va_arg_expr routines. */
298e6adc 4481 gcc_unreachable ();
e4d3eef1 4482#endif
cd3ce9b4 4483
af064de5
RH
4484 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4485 if (indirect)
4486 type = build_pointer_type (type);
4487
e4d3eef1 4488 align = PARM_BOUNDARY / BITS_PER_UNIT;
c565a1e7
L
4489 boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4490
4491 /* When we align parameter on stack for caller, if the parameter
90c700cd
L
4492 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4493 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
c565a1e7 4494 here with caller. */
90c700cd
L
4495 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4496 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
c565a1e7
L
4497
4498 boundary /= BITS_PER_UNIT;
cd3ce9b4 4499
e4d3eef1 4500 /* Hoist the valist value into a temporary for the moment. */
37369edc
RH
4501 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4502
cd3ce9b4
JM
4503 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4504 requires greater alignment, we must perform dynamic alignment. */
f5a7da0f
RG
4505 if (boundary > align
4506 && !integer_zerop (TYPE_SIZE (type)))
cd3ce9b4 4507 {
939409af 4508 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
db3927fb
AH
4509 fold_build2 (POINTER_PLUS_EXPR,
4510 TREE_TYPE (valist),
5be014d5 4511 valist_tmp, size_int (boundary - 1)));
e4d3eef1
RH
4512 gimplify_and_add (t, pre_p);
4513
5be014d5 4514 t = fold_convert (sizetype, valist_tmp);
939409af 4515 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
5be014d5
AP
4516 fold_convert (TREE_TYPE (valist),
4517 fold_build2 (BIT_AND_EXPR, sizetype, t,
4518 size_int (-boundary))));
37369edc 4519 gimplify_and_add (t, pre_p);
cd3ce9b4 4520 }
bfc45551
AM
4521 else
4522 boundary = align;
4523
4524 /* If the actual alignment is less than the alignment of the type,
4525 adjust the type accordingly so that we don't assume strict alignment
fa10beec 4526 when dereferencing the pointer. */
bfc45551
AM
4527 boundary *= BITS_PER_UNIT;
4528 if (boundary < TYPE_ALIGN (type))
4529 {
4530 type = build_variant_type_copy (type);
4531 TYPE_ALIGN (type) = boundary;
4532 }
cd3ce9b4 4533
76aa5713 4534 /* Compute the rounded size of the type. */
e4d3eef1
RH
4535 type_size = size_in_bytes (type);
4536 rounded_size = round_up (type_size, align);
4537
cd3ce9b4
JM
4538 /* Reduce rounded_size so it's sharable with the postqueue. */
4539 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4540
4541 /* Get AP. */
37369edc 4542 addr = valist_tmp;
e4d3eef1 4543 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
cd3ce9b4
JM
4544 {
4545 /* Small args are padded downward. */
db3927fb
AH
4546 t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4547 rounded_size, size_int (align));
987b67bc
KH
4548 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4549 size_binop (MINUS_EXPR, rounded_size, type_size));
db3927fb
AH
4550 addr = fold_build2 (POINTER_PLUS_EXPR,
4551 TREE_TYPE (addr), addr, t);
cd3ce9b4
JM
4552 }
4553
cd3ce9b4 4554 /* Compute new value for AP. */
5be014d5 4555 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
939409af 4556 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
37369edc 4557 gimplify_and_add (t, pre_p);
23a60a04
JM
4558
4559 addr = fold_convert (build_pointer_type (type), addr);
cd3ce9b4 4560
af064de5 4561 if (indirect)
c2433d7d
FCE
4562 addr = build_va_arg_indirect_ref (addr);
4563
4564 return build_va_arg_indirect_ref (addr);
4565}
4882ad24 4566
c2433d7d
FCE
4567/* Build an indirect-ref expression over the given TREE, which represents a
4568 piece of a va_arg() expansion. */
4569tree
4570build_va_arg_indirect_ref (tree addr)
4571{
db3927fb 4572 addr = build_fold_indirect_ref_loc (EXPR_LOCATION (addr), addr);
c2433d7d 4573
4882ad24
FCE
4574 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4575 mf_mark (addr);
af064de5 4576
4882ad24 4577 return addr;
083385aa
RH
4578}
4579
cd3ce9b4
JM
4580/* Return a dummy expression of type TYPE in order to keep going after an
4581 error. */
4582
4583static tree
4584dummy_object (tree type)
4585{
b6f65e3c 4586 tree t = build_int_cst (build_pointer_type (type), 0);
cd3ce9b4
JM
4587 return build1 (INDIRECT_REF, type, t);
4588}
4589
77c9db77
RH
4590/* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4591 builtin function, but a very special sort of operator. */
cd3ce9b4
JM
4592
4593enum gimplify_status
726a989a 4594gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
cd3ce9b4 4595{
35cbb299 4596 tree promoted_type, have_va_type;
cd3ce9b4
JM
4597 tree valist = TREE_OPERAND (*expr_p, 0);
4598 tree type = TREE_TYPE (*expr_p);
4599 tree t;
db3927fb 4600 location_t loc = EXPR_LOCATION (*expr_p);
cd3ce9b4
JM
4601
4602 /* Verify that valist is of the proper type. */
cd3ce9b4 4603 have_va_type = TREE_TYPE (valist);
97bb4af7
RH
4604 if (have_va_type == error_mark_node)
4605 return GS_ERROR;
35cbb299 4606 have_va_type = targetm.canonical_va_list_type (have_va_type);
97bb4af7 4607
35cbb299 4608 if (have_va_type == NULL_TREE)
cd3ce9b4 4609 {
c2255bc4 4610 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
23a60a04 4611 return GS_ERROR;
cd3ce9b4
JM
4612 }
4613
4614 /* Generate a diagnostic for requesting data of a type that cannot
4615 be passed through `...' due to type promotion at the call site. */
35cbb299 4616 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
cd3ce9b4
JM
4617 != type)
4618 {
4619 static bool gave_help;
71205d17 4620 bool warned;
cd3ce9b4
JM
4621
4622 /* Unfortunately, this is merely undefined, rather than a constraint
4623 violation, so we cannot make this an error. If this call is never
4624 executed, the program is still strictly conforming. */
c2255bc4
AH
4625 warned = warning_at (loc, 0,
4626 "%qT is promoted to %qT when passed through %<...%>",
4627 type, promoted_type);
71205d17 4628 if (!gave_help && warned)
cd3ce9b4
JM
4629 {
4630 gave_help = true;
c2255bc4
AH
4631 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4632 promoted_type, type);
cd3ce9b4
JM
4633 }
4634
4635 /* We can, however, treat "undefined" any way we please.
4636 Call abort to encourage the user to fix the program. */
71205d17 4637 if (warned)
c2255bc4 4638 inform (loc, "if this code is reached, the program will abort");
ab4194da
JM
4639 /* Before the abort, allow the evaluation of the va_list
4640 expression to exit or longjmp. */
4641 gimplify_and_add (valist, pre_p);
db3927fb
AH
4642 t = build_call_expr_loc (loc,
4643 implicit_built_in_decls[BUILT_IN_TRAP], 0);
726a989a 4644 gimplify_and_add (t, pre_p);
cd3ce9b4
JM
4645
4646 /* This is dead code, but go ahead and finish so that the
4647 mode of the result comes out right. */
4648 *expr_p = dummy_object (type);
4649 return GS_ALL_DONE;
4650 }
4651 else
4652 {
4653 /* Make it easier for the backends by protecting the valist argument
c22cacf3 4654 from multiple evaluations. */
35cbb299 4655 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
23a60a04
JM
4656 {
4657 /* For this case, the backends will be expecting a pointer to
35cbb299
KT
4658 TREE_TYPE (abi), but it's possible we've
4659 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
23a60a04
JM
4660 So fix it. */
4661 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4662 {
35cbb299 4663 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
db3927fb
AH
4664 valist = fold_convert_loc (loc, p1,
4665 build_fold_addr_expr_loc (loc, valist));
23a60a04 4666 }
726a989a 4667
23a60a04
JM
4668 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4669 }
4670 else
4671 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
cd3ce9b4 4672
cdc3ddb8 4673 if (!targetm.gimplify_va_arg_expr)
726a989a 4674 /* FIXME: Once most targets are converted we should merely
535a42b1 4675 assert this is non-null. */
cd3ce9b4
JM
4676 return GS_ALL_DONE;
4677
cdc3ddb8 4678 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
cd3ce9b4
JM
4679 return GS_OK;
4680 }
4681}
4682
5039610b 4683/* Expand EXP, a call to __builtin_va_end. */
3bdf5ad1 4684
d3707adb 4685static rtx
5039610b 4686expand_builtin_va_end (tree exp)
d3707adb 4687{
5039610b 4688 tree valist = CALL_EXPR_ARG (exp, 0);
daf68dd7 4689
daf68dd7
RH
4690 /* Evaluate for side effects, if needed. I hate macros that don't
4691 do that. */
4692 if (TREE_SIDE_EFFECTS (valist))
4693 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
d3707adb
RH
4694
4695 return const0_rtx;
4696}
4697
5039610b 4698/* Expand EXP, a call to __builtin_va_copy. We do this as a
d3707adb
RH
4699 builtin rather than just as an assignment in stdarg.h because of the
4700 nastiness of array-type va_list types. */
3bdf5ad1 4701
d3707adb 4702static rtx
5039610b 4703expand_builtin_va_copy (tree exp)
d3707adb
RH
4704{
4705 tree dst, src, t;
db3927fb 4706 location_t loc = EXPR_LOCATION (exp);
d3707adb 4707
5039610b
SL
4708 dst = CALL_EXPR_ARG (exp, 0);
4709 src = CALL_EXPR_ARG (exp, 1);
d3707adb 4710
db3927fb
AH
4711 dst = stabilize_va_list_loc (loc, dst, 1);
4712 src = stabilize_va_list_loc (loc, src, 0);
d3707adb 4713
35cbb299
KT
4714 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4715
4716 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
d3707adb 4717 {
35cbb299 4718 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
d3707adb
RH
4719 TREE_SIDE_EFFECTS (t) = 1;
4720 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4721 }
4722 else
4723 {
8ebecc3b
RH
4724 rtx dstb, srcb, size;
4725
4726 /* Evaluate to pointers. */
4727 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4728 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
35cbb299
KT
4729 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4730 NULL_RTX, VOIDmode, EXPAND_NORMAL);
8ebecc3b 4731
5ae6cd0d
MM
4732 dstb = convert_memory_address (Pmode, dstb);
4733 srcb = convert_memory_address (Pmode, srcb);
ce2d32cd 4734
8ebecc3b
RH
4735 /* "Dereference" to BLKmode memories. */
4736 dstb = gen_rtx_MEM (BLKmode, dstb);
ba4828e0 4737 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
35cbb299 4738 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
8ebecc3b 4739 srcb = gen_rtx_MEM (BLKmode, srcb);
ba4828e0 4740 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
35cbb299 4741 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
8ebecc3b
RH
4742
4743 /* Copy. */
44bb111a 4744 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
d3707adb
RH
4745 }
4746
4747 return const0_rtx;
4748}
4749
28f4ec01
BS
4750/* Expand a call to one of the builtin functions __builtin_frame_address or
4751 __builtin_return_address. */
5197bd50 4752
28f4ec01 4753static rtx
5039610b 4754expand_builtin_frame_address (tree fndecl, tree exp)
28f4ec01 4755{
28f4ec01
BS
4756 /* The argument must be a nonnegative integer constant.
4757 It counts the number of frames to scan up the stack.
4758 The value is the return address saved in that frame. */
5039610b 4759 if (call_expr_nargs (exp) == 0)
28f4ec01
BS
4760 /* Warning about missing arg was already issued. */
4761 return const0_rtx;
5039610b 4762 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
28f4ec01
BS
4763 {
4764 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
40b97a2e 4765 error ("invalid argument to %<__builtin_frame_address%>");
28f4ec01 4766 else
40b97a2e 4767 error ("invalid argument to %<__builtin_return_address%>");
28f4ec01
BS
4768 return const0_rtx;
4769 }
4770 else
4771 {
5197bd50
RK
4772 rtx tem
4773 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
5039610b 4774 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
28f4ec01
BS
4775
4776 /* Some ports cannot access arbitrary stack frames. */
4777 if (tem == NULL)
4778 {
4779 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
d4ee4d25 4780 warning (0, "unsupported argument to %<__builtin_frame_address%>");
28f4ec01 4781 else
d4ee4d25 4782 warning (0, "unsupported argument to %<__builtin_return_address%>");
28f4ec01
BS
4783 return const0_rtx;
4784 }
4785
4786 /* For __builtin_frame_address, return what we've got. */
4787 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4788 return tem;
4789
f8cfc6aa 4790 if (!REG_P (tem)
28f4ec01
BS
4791 && ! CONSTANT_P (tem))
4792 tem = copy_to_mode_reg (Pmode, tem);
4793 return tem;
4794 }
4795}
4796
5039610b 4797/* Expand EXP, a call to the alloca builtin. Return NULL_RTX if
28f4ec01
BS
4798 we failed and the caller should emit a normal call, otherwise try to get
4799 the result in TARGET, if convenient. */
d5457140 4800
28f4ec01 4801static rtx
5039610b 4802expand_builtin_alloca (tree exp, rtx target)
28f4ec01
BS
4803{
4804 rtx op0;
d5457140 4805 rtx result;
28f4ec01 4806
efb303b1 4807 /* Emit normal call if marked not-inlineable. */
b8698a0f 4808 if (CALL_CANNOT_INLINE_P (exp))
5039610b 4809 return NULL_RTX;
6de9cd9a 4810
5039610b
SL
4811 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4812 return NULL_RTX;
28f4ec01
BS
4813
4814 /* Compute the argument. */
5039610b 4815 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
28f4ec01
BS
4816
4817 /* Allocate the desired space. */
d5457140 4818 result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
5ae6cd0d 4819 result = convert_memory_address (ptr_mode, result);
d5457140
RK
4820
4821 return result;
28f4ec01
BS
4822}
4823
5039610b 4824/* Expand a call to a bswap builtin with argument ARG0. MODE
167fa32c
EC
4825 is the mode to expand with. */
4826
4827static rtx
5039610b 4828expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
167fa32c
EC
4829{
4830 enum machine_mode mode;
4831 tree arg;
4832 rtx op0;
4833
5039610b
SL
4834 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4835 return NULL_RTX;
167fa32c 4836
5039610b 4837 arg = CALL_EXPR_ARG (exp, 0);
167fa32c 4838 mode = TYPE_MODE (TREE_TYPE (arg));
49452c07 4839 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
167fa32c
EC
4840
4841 target = expand_unop (mode, bswap_optab, op0, target, 1);
4842
4843 gcc_assert (target);
4844
4845 return convert_to_mode (mode, target, 0);
4846}
4847
5039610b
SL
4848/* Expand a call to a unary builtin in EXP.
4849 Return NULL_RTX if a normal call should be emitted rather than expanding the
28f4ec01
BS
4850 function in-line. If convenient, the result should be placed in TARGET.
4851 SUBTARGET may be used as the target for computing one of EXP's operands. */
d5457140 4852
28f4ec01 4853static rtx
5039610b 4854expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4682ae04 4855 rtx subtarget, optab op_optab)
28f4ec01
BS
4856{
4857 rtx op0;
5039610b
SL
4858
4859 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4860 return NULL_RTX;
28f4ec01
BS
4861
4862 /* Compute the argument. */
49452c07
UB
4863 op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
4864 VOIDmode, EXPAND_NORMAL);
2928cd7a 4865 /* Compute op, into TARGET if possible.
28f4ec01 4866 Set TARGET to wherever the result comes back. */
5039610b 4867 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
2928cd7a 4868 op_optab, op0, target, 1);
298e6adc 4869 gcc_assert (target);
5906d013 4870
6c537d03 4871 return convert_to_mode (target_mode, target, 0);
28f4ec01 4872}
994a57cd 4873
b8698a0f 4874/* Expand a call to __builtin_expect. We just return our argument
ef950eba
JH
4875 as the builtin_expect semantic should've been already executed by
4876 tree branch prediction pass. */
994a57cd
RH
4877
4878static rtx
5039610b 4879expand_builtin_expect (tree exp, rtx target)
994a57cd 4880{
451409e4 4881 tree arg;
994a57cd 4882
5039610b 4883 if (call_expr_nargs (exp) < 2)
994a57cd 4884 return const0_rtx;
5039610b 4885 arg = CALL_EXPR_ARG (exp, 0);
994a57cd 4886
5039610b 4887 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
ef950eba 4888 /* When guessing was done, the hints should be already stripped away. */
1d8381f1
JJ
4889 gcc_assert (!flag_guess_branch_prob
4890 || optimize == 0 || errorcount || sorrycount);
994a57cd
RH
4891 return target;
4892}
5f2d6cfa 4893
1e188d1e 4894void
4682ae04 4895expand_builtin_trap (void)
9602f5a0
RH
4896{
4897#ifdef HAVE_trap
4898 if (HAVE_trap)
4899 emit_insn (gen_trap ());
4900 else
4901#endif
4902 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4903 emit_barrier ();
4904}
075ec276 4905
468059bc
DD
4906/* Expand a call to __builtin_unreachable. We do nothing except emit
4907 a barrier saying that control flow will not pass here.
4908
4909 It is the responsibility of the program being compiled to ensure
4910 that control flow does never reach __builtin_unreachable. */
4911static void
4912expand_builtin_unreachable (void)
4913{
4914 emit_barrier ();
4915}
4916
5039610b
SL
4917/* Expand EXP, a call to fabs, fabsf or fabsl.
4918 Return NULL_RTX if a normal call should be emitted rather than expanding
075ec276
RS
4919 the function inline. If convenient, the result should be placed
4920 in TARGET. SUBTARGET may be used as the target for computing
4921 the operand. */
4922
4923static rtx
5039610b 4924expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
075ec276
RS
4925{
4926 enum machine_mode mode;
4927 tree arg;
4928 rtx op0;
4929
5039610b
SL
4930 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4931 return NULL_RTX;
075ec276 4932
5039610b 4933 arg = CALL_EXPR_ARG (exp, 0);
4cd8e76f 4934 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
075ec276 4935 mode = TYPE_MODE (TREE_TYPE (arg));
49452c07 4936 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
075ec276
RS
4937 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4938}
4939
5039610b 4940/* Expand EXP, a call to copysign, copysignf, or copysignl.
046625fa
RH
4941 Return NULL is a normal call should be emitted rather than expanding the
4942 function inline. If convenient, the result should be placed in TARGET.
4943 SUBTARGET may be used as the target for computing the operand. */
4944
4945static rtx
5039610b 4946expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
046625fa
RH
4947{
4948 rtx op0, op1;
4949 tree arg;
4950
5039610b
SL
4951 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4952 return NULL_RTX;
046625fa 4953
5039610b 4954 arg = CALL_EXPR_ARG (exp, 0);
84217346 4955 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
046625fa 4956
5039610b 4957 arg = CALL_EXPR_ARG (exp, 1);
84217346 4958 op1 = expand_normal (arg);
046625fa
RH
4959
4960 return expand_copysign (op0, op1, target);
4961}
4962
868b8cda
RS
4963/* Create a new constant string literal and return a char* pointer to it.
4964 The STRING_CST value is the LEN characters at STR. */
953ff289 4965tree
868b8cda
RS
4966build_string_literal (int len, const char *str)
4967{
4968 tree t, elem, index, type;
4969
4970 t = build_string (len, str);
4971 elem = build_type_variant (char_type_node, 1, 0);
acdfeac3 4972 index = build_index_type (size_int (len - 1));
868b8cda
RS
4973 type = build_array_type (elem, index);
4974 TREE_TYPE (t) = type;
4975 TREE_CONSTANT (t) = 1;
4976 TREE_READONLY (t) = 1;
4977 TREE_STATIC (t) = 1;
4978
868b8cda 4979 type = build_pointer_type (elem);
acdfeac3
RG
4980 t = build1 (ADDR_EXPR, type,
4981 build4 (ARRAY_REF, elem,
4982 t, integer_zero_node, NULL_TREE, NULL_TREE));
868b8cda
RS
4983 return t;
4984}
4985
8148fe65 4986/* Expand EXP, a call to printf or printf_unlocked.
5039610b 4987 Return NULL_RTX if a normal call should be emitted rather than transforming
868b8cda 4988 the function inline. If convenient, the result should be placed in
33521f7d 4989 TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
868b8cda
RS
4990 call. */
4991static rtx
8148fe65 4992expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
868b8cda
RS
4993 bool unlocked)
4994{
7e7b53aa
KG
4995 /* If we're using an unlocked function, assume the other unlocked
4996 functions exist explicitly. */
4997 tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4998 : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4999 tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5000 : implicit_built_in_decls[BUILT_IN_PUTS];
868b8cda 5001 const char *fmt_str;
5039610b
SL
5002 tree fn = 0;
5003 tree fmt, arg;
5004 int nargs = call_expr_nargs (exp);
868b8cda
RS
5005
5006 /* If the return value is used, don't do the transformation. */
5007 if (target != const0_rtx)
5039610b 5008 return NULL_RTX;
868b8cda
RS
5009
5010 /* Verify the required arguments in the original call. */
5039610b
SL
5011 if (nargs == 0)
5012 return NULL_RTX;
5013 fmt = CALL_EXPR_ARG (exp, 0);
7b922122 5014 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5039610b 5015 return NULL_RTX;
868b8cda
RS
5016
5017 /* Check whether the format is a literal string constant. */
5018 fmt_str = c_getstr (fmt);
5019 if (fmt_str == NULL)
5039610b 5020 return NULL_RTX;
868b8cda 5021
62e5bf5d 5022 if (!init_target_chars ())
5039610b 5023 return NULL_RTX;
c22cacf3 5024
868b8cda 5025 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
000ba23d 5026 if (strcmp (fmt_str, target_percent_s_newline) == 0)
868b8cda 5027 {
5039610b
SL
5028 if ((nargs != 2)
5029 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5030 return NULL_RTX;
5031 if (fn_puts)
44e10129 5032 fn = build_call_nofold (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
868b8cda
RS
5033 }
5034 /* If the format specifier was "%c", call __builtin_putchar(arg). */
000ba23d 5035 else if (strcmp (fmt_str, target_percent_c) == 0)
868b8cda 5036 {
5039610b
SL
5037 if ((nargs != 2)
5038 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5039 return NULL_RTX;
5040 if (fn_putchar)
44e10129 5041 fn = build_call_nofold (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
868b8cda
RS
5042 }
5043 else
5044 {
5045 /* We can't handle anything else with % args or %% ... yet. */
000ba23d 5046 if (strchr (fmt_str, target_percent))
5039610b 5047 return NULL_RTX;
868b8cda 5048
5039610b
SL
5049 if (nargs > 1)
5050 return NULL_RTX;
868b8cda
RS
5051
5052 /* If the format specifier was "", printf does nothing. */
5053 if (fmt_str[0] == '\0')
5054 return const0_rtx;
5055 /* If the format specifier has length of 1, call putchar. */
5056 if (fmt_str[1] == '\0')
5057 {
5058 /* Given printf("c"), (where c is any one character,)
5059 convert "c"[0] to an int and pass that to the replacement
5060 function. */
7d60be94 5061 arg = build_int_cst (NULL_TREE, fmt_str[0]);
5039610b 5062 if (fn_putchar)
44e10129 5063 fn = build_call_nofold (fn_putchar, 1, arg);
868b8cda
RS
5064 }
5065 else
5066 {
5067 /* If the format specifier was "string\n", call puts("string"). */
5068 size_t len = strlen (fmt_str);
000ba23d 5069 if ((unsigned char)fmt_str[len - 1] == target_newline)
868b8cda 5070 {
a98ebe2e 5071 /* Create a NUL-terminated string that's one char shorter
868b8cda 5072 than the original, stripping off the trailing '\n'. */
f883e0a7 5073 char *newstr = XALLOCAVEC (char, len);
868b8cda
RS
5074 memcpy (newstr, fmt_str, len - 1);
5075 newstr[len - 1] = 0;
868b8cda 5076 arg = build_string_literal (len, newstr);
5039610b 5077 if (fn_puts)
44e10129 5078 fn = build_call_nofold (fn_puts, 1, arg);
868b8cda
RS
5079 }
5080 else
5081 /* We'd like to arrange to call fputs(string,stdout) here,
5082 but we need stdout and don't have a way to get it yet. */
5039610b 5083 return NULL_RTX;
868b8cda
RS
5084 }
5085 }
5086
5087 if (!fn)
5039610b 5088 return NULL_RTX;
44e10129
MM
5089 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5090 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
8148fe65 5091 return expand_expr (fn, target, mode, EXPAND_NORMAL);
868b8cda
RS
5092}
5093
8148fe65 5094/* Expand EXP, a call to fprintf or fprintf_unlocked.
5039610b 5095 Return NULL_RTX if a normal call should be emitted rather than transforming
868b8cda 5096 the function inline. If convenient, the result should be placed in
33521f7d 5097 TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
868b8cda
RS
5098 call. */
5099static rtx
8148fe65 5100expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
c22cacf3 5101 bool unlocked)
868b8cda 5102{
7e7b53aa
KG
5103 /* If we're using an unlocked function, assume the other unlocked
5104 functions exist explicitly. */
5105 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5106 : implicit_built_in_decls[BUILT_IN_FPUTC];
5107 tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5108 : implicit_built_in_decls[BUILT_IN_FPUTS];
868b8cda 5109 const char *fmt_str;
5039610b
SL
5110 tree fn = 0;
5111 tree fmt, fp, arg;
5112 int nargs = call_expr_nargs (exp);
868b8cda
RS
5113
5114 /* If the return value is used, don't do the transformation. */
5115 if (target != const0_rtx)
5039610b 5116 return NULL_RTX;
868b8cda
RS
5117
5118 /* Verify the required arguments in the original call. */
5039610b
SL
5119 if (nargs < 2)
5120 return NULL_RTX;
5121 fp = CALL_EXPR_ARG (exp, 0);
7b922122 5122 if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5039610b
SL
5123 return NULL_RTX;
5124 fmt = CALL_EXPR_ARG (exp, 1);
7b922122 5125 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5039610b 5126 return NULL_RTX;
868b8cda
RS
5127
5128 /* Check whether the format is a literal string constant. */
5129 fmt_str = c_getstr (fmt);
5130 if (fmt_str == NULL)
5039610b 5131 return NULL_RTX;
868b8cda 5132
62e5bf5d 5133 if (!init_target_chars ())
5039610b 5134 return NULL_RTX;
c22cacf3 5135
868b8cda 5136 /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
000ba23d 5137 if (strcmp (fmt_str, target_percent_s) == 0)
868b8cda 5138 {
5039610b
SL
5139 if ((nargs != 3)
5140 || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5141 return NULL_RTX;
5142 arg = CALL_EXPR_ARG (exp, 2);
5143 if (fn_fputs)
44e10129 5144 fn = build_call_nofold (fn_fputs, 2, arg, fp);
868b8cda
RS
5145 }
5146 /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
000ba23d 5147 else if (strcmp (fmt_str, target_percent_c) == 0)
868b8cda 5148 {
5039610b
SL
5149 if ((nargs != 3)
5150 || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5151 return NULL_RTX;
5152 arg = CALL_EXPR_ARG (exp, 2);
5153 if (fn_fputc)
44e10129 5154 fn = build_call_nofold (fn_fputc, 2, arg, fp);
868b8cda
RS
5155 }
5156 else
5157 {
5158 /* We can't handle anything else with % args or %% ... yet. */
000ba23d 5159 if (strchr (fmt_str, target_percent))
5039610b 5160 return NULL_RTX;
868b8cda 5161
5039610b
SL
5162 if (nargs > 2)
5163 return NULL_RTX;
868b8cda
RS
5164
5165 /* If the format specifier was "", fprintf does nothing. */
5166 if (fmt_str[0] == '\0')
5167 {
5168 /* Evaluate and ignore FILE* argument for side-effects. */
5169 expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5170 return const0_rtx;
5171 }
5172
5173 /* When "string" doesn't contain %, replace all cases of
5174 fprintf(stream,string) with fputs(string,stream). The fputs
5175 builtin will take care of special cases like length == 1. */
5039610b 5176 if (fn_fputs)
44e10129 5177 fn = build_call_nofold (fn_fputs, 2, fmt, fp);
868b8cda
RS
5178 }
5179
5180 if (!fn)
5039610b 5181 return NULL_RTX;
44e10129
MM
5182 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5183 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
8148fe65 5184 return expand_expr (fn, target, mode, EXPAND_NORMAL);
868b8cda
RS
5185}
5186
5039610b 5187/* Expand a call EXP to sprintf. Return NULL_RTX if
8e0952f0
RS
5188 a normal call should be emitted rather than expanding the function
5189 inline. If convenient, the result should be placed in TARGET with
5190 mode MODE. */
5191
5192static rtx
5039610b 5193expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
8e0952f0 5194{
5039610b 5195 tree dest, fmt;
6ba701c8 5196 const char *fmt_str;
5039610b 5197 int nargs = call_expr_nargs (exp);
8e0952f0
RS
5198
5199 /* Verify the required arguments in the original call. */
5039610b
SL
5200 if (nargs < 2)
5201 return NULL_RTX;
5202 dest = CALL_EXPR_ARG (exp, 0);
7b922122 5203 if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5039610b
SL
5204 return NULL_RTX;
5205 fmt = CALL_EXPR_ARG (exp, 0);
7b922122 5206 if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5039610b 5207 return NULL_RTX;
8e0952f0
RS
5208
5209 /* Check whether the format is a literal string constant. */
6ba701c8
RS
5210 fmt_str = c_getstr (fmt);
5211 if (fmt_str == NULL)
5039610b 5212 return NULL_RTX;
8e0952f0 5213
62e5bf5d 5214 if (!init_target_chars ())
5039610b 5215 return NULL_RTX;
000ba23d 5216
8e0952f0 5217 /* If the format doesn't contain % args or %%, use strcpy. */
000ba23d 5218 if (strchr (fmt_str, target_percent) == 0)
8e0952f0
RS
5219 {
5220 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5221 tree exp;
5222
5039610b
SL
5223 if ((nargs > 2) || ! fn)
5224 return NULL_RTX;
44e10129 5225 expand_expr (build_call_nofold (fn, 2, dest, fmt),
8e0952f0
RS
5226 const0_rtx, VOIDmode, EXPAND_NORMAL);
5227 if (target == const0_rtx)
5228 return const0_rtx;
7d60be94 5229 exp = build_int_cst (NULL_TREE, strlen (fmt_str));
8e0952f0
RS
5230 return expand_expr (exp, target, mode, EXPAND_NORMAL);
5231 }
6ba701c8 5232 /* If the format is "%s", use strcpy if the result isn't used. */
000ba23d 5233 else if (strcmp (fmt_str, target_percent_s) == 0)
8e0952f0 5234 {
6ba701c8
RS
5235 tree fn, arg, len;
5236 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8e0952f0 5237
6ba701c8 5238 if (! fn)
5039610b
SL
5239 return NULL_RTX;
5240 if (nargs != 3)
5241 return NULL_RTX;
5242 arg = CALL_EXPR_ARG (exp, 2);
7b922122 5243 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5039610b 5244 return NULL_RTX;
8e0952f0
RS
5245
5246 if (target != const0_rtx)
5247 {
ae808627 5248 len = c_strlen (arg, 1);
6ba701c8 5249 if (! len || TREE_CODE (len) != INTEGER_CST)
5039610b 5250 return NULL_RTX;
8e0952f0
RS
5251 }
5252 else
6ba701c8 5253 len = NULL_TREE;
8e0952f0 5254
44e10129 5255 expand_expr (build_call_nofold (fn, 2, dest, arg),
8e0952f0
RS
5256 const0_rtx, VOIDmode, EXPAND_NORMAL);
5257
5258 if (target == const0_rtx)
5259 return const0_rtx;
6ba701c8 5260 return expand_expr (len, target, mode, EXPAND_NORMAL);
8e0952f0
RS
5261 }
5262
5039610b 5263 return NULL_RTX;
8e0952f0 5264}
ef79730c 5265
6de9cd9a
DN
5266/* Expand a call to either the entry or exit function profiler. */
5267
5268static rtx
5269expand_builtin_profile_func (bool exitp)
5270{
82d6e6fc 5271 rtx this_rtx, which;
6de9cd9a 5272
82d6e6fc
KG
5273 this_rtx = DECL_RTL (current_function_decl);
5274 gcc_assert (MEM_P (this_rtx));
5275 this_rtx = XEXP (this_rtx, 0);
6de9cd9a
DN
5276
5277 if (exitp)
5278 which = profile_function_exit_libfunc;
5279 else
5280 which = profile_function_entry_libfunc;
5281
82d6e6fc 5282 emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
6de9cd9a 5283 expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
c6d01079 5284 0),
6de9cd9a
DN
5285 Pmode);
5286
5287 return const0_rtx;
5288}
5289
677feb77
DD
5290/* Expand a call to __builtin___clear_cache. */
5291
5292static rtx
5293expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5294{
5295#ifndef HAVE_clear_cache
5296#ifdef CLEAR_INSN_CACHE
5297 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5298 does something. Just do the default expansion to a call to
5299 __clear_cache(). */
5300 return NULL_RTX;
5301#else
5302 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5303 does nothing. There is no need to call it. Do nothing. */
5304 return const0_rtx;
5305#endif /* CLEAR_INSN_CACHE */
5306#else
5307 /* We have a "clear_cache" insn, and it will handle everything. */
5308 tree begin, end;
5309 rtx begin_rtx, end_rtx;
5310 enum insn_code icode;
5311
5312 /* We must not expand to a library call. If we did, any
5313 fallback library function in libgcc that might contain a call to
5314 __builtin___clear_cache() would recurse infinitely. */
5315 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5316 {
5317 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5318 return const0_rtx;
5319 }
5320
5321 if (HAVE_clear_cache)
5322 {
5323 icode = CODE_FOR_clear_cache;
5324
5325 begin = CALL_EXPR_ARG (exp, 0);
5326 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5327 begin_rtx = convert_memory_address (Pmode, begin_rtx);
5328 if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5329 begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5330
5331 end = CALL_EXPR_ARG (exp, 1);
5332 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5333 end_rtx = convert_memory_address (Pmode, end_rtx);
5334 if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5335 end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5336
5337 emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5338 }
5339 return const0_rtx;
5340#endif /* HAVE_clear_cache */
5341}
5342
6de9cd9a
DN
5343/* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
5344
5345static rtx
5346round_trampoline_addr (rtx tramp)
5347{
5348 rtx temp, addend, mask;
5349
5350 /* If we don't need too much alignment, we'll have been guaranteed
5351 proper alignment by get_trampoline_type. */
5352 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5353 return tramp;
5354
5355 /* Round address up to desired boundary. */
5356 temp = gen_reg_rtx (Pmode);
5357 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5358 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5359
5360 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
5361 temp, 0, OPTAB_LIB_WIDEN);
5362 tramp = expand_simple_binop (Pmode, AND, temp, mask,
5363 temp, 0, OPTAB_LIB_WIDEN);
5364
5365 return tramp;
5366}
5367
5368static rtx
5039610b 5369expand_builtin_init_trampoline (tree exp)
6de9cd9a
DN
5370{
5371 tree t_tramp, t_func, t_chain;
531ca746 5372 rtx m_tramp, r_tramp, r_chain, tmp;
6de9cd9a 5373
5039610b 5374 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
6de9cd9a
DN
5375 POINTER_TYPE, VOID_TYPE))
5376 return NULL_RTX;
5377
5039610b
SL
5378 t_tramp = CALL_EXPR_ARG (exp, 0);
5379 t_func = CALL_EXPR_ARG (exp, 1);
5380 t_chain = CALL_EXPR_ARG (exp, 2);
6de9cd9a 5381
84217346 5382 r_tramp = expand_normal (t_tramp);
531ca746
RH
5383 m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
5384 MEM_NOTRAP_P (m_tramp) = 1;
5385
5386 /* The TRAMP argument should be the address of a field within the
5387 local function's FRAME decl. Let's see if we can fill in the
5388 to fill in the MEM_ATTRs for this memory. */
5389 if (TREE_CODE (t_tramp) == ADDR_EXPR)
5390 set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
5391 true, 0);
5392
5393 tmp = round_trampoline_addr (r_tramp);
5394 if (tmp != r_tramp)
5395 {
5396 m_tramp = change_address (m_tramp, BLKmode, tmp);
5397 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
5398 set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE));
5399 }
5400
5401 /* The FUNC argument should be the address of the nested function.
5402 Extract the actual function decl to pass to the hook. */
5403 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
5404 t_func = TREE_OPERAND (t_func, 0);
5405 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
5406
84217346 5407 r_chain = expand_normal (t_chain);
6de9cd9a
DN
5408
5409 /* Generate insns to initialize the trampoline. */
531ca746 5410 targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
6de9cd9a 5411
531ca746 5412 trampolines_created = 1;
6de9cd9a
DN
5413 return const0_rtx;
5414}
5415
5416static rtx
5039610b 5417expand_builtin_adjust_trampoline (tree exp)
6de9cd9a
DN
5418{
5419 rtx tramp;
5420
5039610b 5421 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6de9cd9a
DN
5422 return NULL_RTX;
5423
5039610b 5424 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
6de9cd9a 5425 tramp = round_trampoline_addr (tramp);
531ca746
RH
5426 if (targetm.calls.trampoline_adjust_address)
5427 tramp = targetm.calls.trampoline_adjust_address (tramp);
6de9cd9a
DN
5428
5429 return tramp;
5430}
5431
0f67fa83
WG
5432/* Expand the call EXP to the built-in signbit, signbitf or signbitl
5433 function. The function first checks whether the back end provides
5434 an insn to implement signbit for the respective mode. If not, it
5435 checks whether the floating point format of the value is such that
5436 the sign bit can be extracted. If that is not the case, the
5437 function returns NULL_RTX to indicate that a normal call should be
5438 emitted rather than expanding the function in-line. EXP is the
5439 expression that is a call to the builtin function; if convenient,
5440 the result should be placed in TARGET. */
ef79730c
RS
5441static rtx
5442expand_builtin_signbit (tree exp, rtx target)
5443{
5444 const struct real_format *fmt;
5445 enum machine_mode fmode, imode, rmode;
5446 HOST_WIDE_INT hi, lo;
5039610b 5447 tree arg;
e4fbead1 5448 int word, bitpos;
d0c9d431 5449 enum insn_code icode;
ef79730c 5450 rtx temp;
db3927fb 5451 location_t loc = EXPR_LOCATION (exp);
ef79730c 5452
5039610b
SL
5453 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5454 return NULL_RTX;
ef79730c 5455
5039610b 5456 arg = CALL_EXPR_ARG (exp, 0);
ef79730c
RS
5457 fmode = TYPE_MODE (TREE_TYPE (arg));
5458 rmode = TYPE_MODE (TREE_TYPE (exp));
5459 fmt = REAL_MODE_FORMAT (fmode);
5460
0f67fa83
WG
5461 arg = builtin_save_expr (arg);
5462
5463 /* Expand the argument yielding a RTX expression. */
5464 temp = expand_normal (arg);
5465
5466 /* Check if the back end provides an insn that handles signbit for the
5467 argument's mode. */
d0c9d431
UB
5468 icode = signbit_optab->handlers [(int) fmode].insn_code;
5469 if (icode != CODE_FOR_nothing)
0f67fa83
WG
5470 {
5471 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
d0c9d431 5472 emit_unop_insn (icode, target, temp, UNKNOWN);
0f67fa83
WG
5473 return target;
5474 }
5475
ef79730c
RS
5476 /* For floating point formats without a sign bit, implement signbit
5477 as "ARG < 0.0". */
b87a0206 5478 bitpos = fmt->signbit_ro;
e4fbead1 5479 if (bitpos < 0)
ef79730c
RS
5480 {
5481 /* But we can't do this if the format supports signed zero. */
5482 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5039610b 5483 return NULL_RTX;
ef79730c 5484
db3927fb 5485 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
987b67bc 5486 build_real (TREE_TYPE (arg), dconst0));
ef79730c
RS
5487 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5488 }
5489
e4fbead1 5490 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
ef79730c 5491 {
e4fbead1
RS
5492 imode = int_mode_for_mode (fmode);
5493 if (imode == BLKmode)
5039610b 5494 return NULL_RTX;
e4fbead1 5495 temp = gen_lowpart (imode, temp);
254878ea
RS
5496 }
5497 else
5498 {
e4fbead1
RS
5499 imode = word_mode;
5500 /* Handle targets with different FP word orders. */
5501 if (FLOAT_WORDS_BIG_ENDIAN)
c22cacf3 5502 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
e4fbead1 5503 else
c22cacf3 5504 word = bitpos / BITS_PER_WORD;
e4fbead1
RS
5505 temp = operand_subword_force (temp, word, fmode);
5506 bitpos = bitpos % BITS_PER_WORD;
5507 }
5508
210e1852
RS
5509 /* Force the intermediate word_mode (or narrower) result into a
5510 register. This avoids attempting to create paradoxical SUBREGs
5511 of floating point modes below. */
5512 temp = force_reg (imode, temp);
5513
e4fbead1
RS
5514 /* If the bitpos is within the "result mode" lowpart, the operation
5515 can be implement with a single bitwise AND. Otherwise, we need
5516 a right shift and an AND. */
5517
5518 if (bitpos < GET_MODE_BITSIZE (rmode))
5519 {
254878ea 5520 if (bitpos < HOST_BITS_PER_WIDE_INT)
ef79730c 5521 {
254878ea
RS
5522 hi = 0;
5523 lo = (HOST_WIDE_INT) 1 << bitpos;
ef79730c
RS
5524 }
5525 else
254878ea
RS
5526 {
5527 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5528 lo = 0;
5529 }
ef79730c 5530
515e442a 5531 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
e4fbead1 5532 temp = gen_lowpart (rmode, temp);
254878ea
RS
5533 temp = expand_binop (rmode, and_optab, temp,
5534 immed_double_const (lo, hi, rmode),
e4fbead1 5535 NULL_RTX, 1, OPTAB_LIB_WIDEN);
ef79730c 5536 }
e4fbead1
RS
5537 else
5538 {
5539 /* Perform a logical right shift to place the signbit in the least
c22cacf3 5540 significant bit, then truncate the result to the desired mode
e4fbead1
RS
5541 and mask just this bit. */
5542 temp = expand_shift (RSHIFT_EXPR, imode, temp,
5543 build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5544 temp = gen_lowpart (rmode, temp);
5545 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5546 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5547 }
5548
ef79730c
RS
5549 return temp;
5550}
d1c38823
ZD
5551
5552/* Expand fork or exec calls. TARGET is the desired target of the
5039610b 5553 call. EXP is the call. FN is the
d1c38823
ZD
5554 identificator of the actual function. IGNORE is nonzero if the
5555 value is to be ignored. */
5556
5557static rtx
5039610b 5558expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
d1c38823
ZD
5559{
5560 tree id, decl;
5561 tree call;
5562
5563 /* If we are not profiling, just call the function. */
5564 if (!profile_arc_flag)
5565 return NULL_RTX;
5566
5567 /* Otherwise call the wrapper. This should be equivalent for the rest of
5568 compiler, so the code does not diverge, and the wrapper may run the
2b8a92de 5569 code necessary for keeping the profiling sane. */
d1c38823
ZD
5570
5571 switch (DECL_FUNCTION_CODE (fn))
5572 {
5573 case BUILT_IN_FORK:
5574 id = get_identifier ("__gcov_fork");
5575 break;
5576
5577 case BUILT_IN_EXECL:
5578 id = get_identifier ("__gcov_execl");
5579 break;
5580
5581 case BUILT_IN_EXECV:
5582 id = get_identifier ("__gcov_execv");
5583 break;
5584
5585 case BUILT_IN_EXECLP:
5586 id = get_identifier ("__gcov_execlp");
5587 break;
5588
5589 case BUILT_IN_EXECLE:
5590 id = get_identifier ("__gcov_execle");
5591 break;
5592
5593 case BUILT_IN_EXECVP:
5594 id = get_identifier ("__gcov_execvp");
5595 break;
5596
5597 case BUILT_IN_EXECVE:
5598 id = get_identifier ("__gcov_execve");
5599 break;
5600
5601 default:
298e6adc 5602 gcc_unreachable ();
d1c38823
ZD
5603 }
5604
c2255bc4
AH
5605 decl = build_decl (DECL_SOURCE_LOCATION (fn),
5606 FUNCTION_DECL, id, TREE_TYPE (fn));
d1c38823
ZD
5607 DECL_EXTERNAL (decl) = 1;
5608 TREE_PUBLIC (decl) = 1;
5609 DECL_ARTIFICIAL (decl) = 1;
5610 TREE_NOTHROW (decl) = 1;
ac382b62
JM
5611 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5612 DECL_VISIBILITY_SPECIFIED (decl) = 1;
db3927fb 5613 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
d1c38823 5614 return expand_call (call, target, ignore);
5039610b 5615 }
b8698a0f 5616
48ae6c13
RH
5617
5618\f
02ee605c
RH
5619/* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5620 the pointer in these functions is void*, the tree optimizers may remove
5621 casts. The mode computed in expand_builtin isn't reliable either, due
5622 to __sync_bool_compare_and_swap.
5623
5624 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5625 group of builtins. This gives us log2 of the mode size. */
5626
5627static inline enum machine_mode
5628get_builtin_sync_mode (int fcode_diff)
5629{
2de0aa52
HPN
5630 /* The size is not negotiable, so ask not to get BLKmode in return
5631 if the target indicates that a smaller size would be better. */
5632 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
02ee605c
RH
5633}
5634
1387fef3
AS
5635/* Expand the memory expression LOC and return the appropriate memory operand
5636 for the builtin_sync operations. */
5637
5638static rtx
5639get_builtin_sync_mem (tree loc, enum machine_mode mode)
5640{
5641 rtx addr, mem;
5642
f46835f5
JJ
5643 addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5644 addr = convert_memory_address (Pmode, addr);
1387fef3
AS
5645
5646 /* Note that we explicitly do not want any alias information for this
5647 memory, so that we kill all other live memories. Otherwise we don't
5648 satisfy the full barrier semantics of the intrinsic. */
5649 mem = validize_mem (gen_rtx_MEM (mode, addr));
5650
5651 set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
9cd9e512 5652 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
1387fef3
AS
5653 MEM_VOLATILE_P (mem) = 1;
5654
5655 return mem;
5656}
5657
48ae6c13 5658/* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5039610b 5659 EXP is the CALL_EXPR. CODE is the rtx code
48ae6c13
RH
5660 that corresponds to the arithmetic or logical operation from the name;
5661 an exception here is that NOT actually means NAND. TARGET is an optional
5662 place for us to store the results; AFTER is true if this is the
5663 fetch_and_xxx form. IGNORE is true if we don't actually care about
5664 the result of the operation at all. */
5665
5666static rtx
5039610b 5667expand_builtin_sync_operation (enum machine_mode mode, tree exp,
02ee605c 5668 enum rtx_code code, bool after,
48ae6c13
RH
5669 rtx target, bool ignore)
5670{
1387fef3 5671 rtx val, mem;
1e395249 5672 enum machine_mode old_mode;
c2255bc4 5673 location_t loc = EXPR_LOCATION (exp);
48ae6c13 5674
23462d4d
UB
5675 if (code == NOT && warn_sync_nand)
5676 {
5677 tree fndecl = get_callee_fndecl (exp);
5678 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5679
5680 static bool warned_f_a_n, warned_n_a_f;
5681
5682 switch (fcode)
5683 {
5684 case BUILT_IN_FETCH_AND_NAND_1:
5685 case BUILT_IN_FETCH_AND_NAND_2:
5686 case BUILT_IN_FETCH_AND_NAND_4:
5687 case BUILT_IN_FETCH_AND_NAND_8:
5688 case BUILT_IN_FETCH_AND_NAND_16:
5689
5690 if (warned_f_a_n)
5691 break;
5692
5693 fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
c2255bc4 5694 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
23462d4d
UB
5695 warned_f_a_n = true;
5696 break;
5697
5698 case BUILT_IN_NAND_AND_FETCH_1:
5699 case BUILT_IN_NAND_AND_FETCH_2:
5700 case BUILT_IN_NAND_AND_FETCH_4:
5701 case BUILT_IN_NAND_AND_FETCH_8:
5702 case BUILT_IN_NAND_AND_FETCH_16:
5703
5704 if (warned_n_a_f)
5705 break;
5706
5707 fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
c2255bc4 5708 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
23462d4d
UB
5709 warned_n_a_f = true;
5710 break;
5711
5712 default:
5713 gcc_unreachable ();
5714 }
5715 }
5716
48ae6c13 5717 /* Expand the operands. */
5039610b 5718 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
48ae6c13 5719
49452c07 5720 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
1e395249
MM
5721 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5722 of CONST_INTs, where we know the old_mode only from the call argument. */
5723 old_mode = GET_MODE (val);
5724 if (old_mode == VOIDmode)
5725 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5726 val = convert_modes (mode, old_mode, val, 1);
48ae6c13 5727
48ae6c13
RH
5728 if (ignore)
5729 return expand_sync_operation (mem, val, code);
5730 else
5731 return expand_sync_fetch_operation (mem, val, code, after, target);
5732}
5733
5734/* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5039610b 5735 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
48ae6c13
RH
5736 true if this is the boolean form. TARGET is a place for us to store the
5737 results; this is NOT optional if IS_BOOL is true. */
5738
5739static rtx
5039610b 5740expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
02ee605c 5741 bool is_bool, rtx target)
48ae6c13 5742{
1387fef3 5743 rtx old_val, new_val, mem;
1e395249 5744 enum machine_mode old_mode;
48ae6c13
RH
5745
5746 /* Expand the operands. */
5039610b 5747 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
48ae6c13 5748
5039610b 5749
49452c07
UB
5750 old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
5751 mode, EXPAND_NORMAL);
1e395249
MM
5752 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5753 of CONST_INTs, where we know the old_mode only from the call argument. */
5754 old_mode = GET_MODE (old_val);
5755 if (old_mode == VOIDmode)
5756 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5757 old_val = convert_modes (mode, old_mode, old_val, 1);
48ae6c13 5758
49452c07
UB
5759 new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
5760 mode, EXPAND_NORMAL);
1e395249
MM
5761 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5762 of CONST_INTs, where we know the old_mode only from the call argument. */
5763 old_mode = GET_MODE (new_val);
5764 if (old_mode == VOIDmode)
5765 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
5766 new_val = convert_modes (mode, old_mode, new_val, 1);
48ae6c13 5767
48ae6c13
RH
5768 if (is_bool)
5769 return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5770 else
5771 return expand_val_compare_and_swap (mem, old_val, new_val, target);
5772}
5773
5774/* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5775 general form is actually an atomic exchange, and some targets only
5776 support a reduced form with the second argument being a constant 1.
b8698a0f 5777 EXP is the CALL_EXPR; TARGET is an optional place for us to store
5039610b 5778 the results. */
48ae6c13
RH
5779
5780static rtx
5039610b 5781expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
02ee605c 5782 rtx target)
48ae6c13 5783{
1387fef3 5784 rtx val, mem;
1e395249 5785 enum machine_mode old_mode;
48ae6c13
RH
5786
5787 /* Expand the operands. */
5039610b 5788 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
49452c07 5789 val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
1e395249
MM
5790 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5791 of CONST_INTs, where we know the old_mode only from the call argument. */
5792 old_mode = GET_MODE (val);
5793 if (old_mode == VOIDmode)
5794 old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5795 val = convert_modes (mode, old_mode, val, 1);
48ae6c13 5796
48ae6c13
RH
5797 return expand_sync_lock_test_and_set (mem, val, target);
5798}
5799
5800/* Expand the __sync_synchronize intrinsic. */
5801
5802static void
5803expand_builtin_synchronize (void)
5804{
28ed065e 5805 gimple x;
1c384bf1 5806 VEC (tree, gc) *v_clobbers;
48ae6c13
RH
5807
5808#ifdef HAVE_memory_barrier
5809 if (HAVE_memory_barrier)
5810 {
5811 emit_insn (gen_memory_barrier ());
5812 return;
5813 }
5814#endif
5815
e2ff10a9
RS
5816 if (synchronize_libfunc != NULL_RTX)
5817 {
5818 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5819 return;
5820 }
5821
74395677
RH
5822 /* If no explicit memory barrier instruction is available, create an
5823 empty asm stmt with a memory clobber. */
1c384bf1
RH
5824 v_clobbers = VEC_alloc (tree, gc, 1);
5825 VEC_quick_push (tree, v_clobbers,
5826 tree_cons (NULL, build_string (6, "memory"), NULL));
5827 x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
28ed065e
MM
5828 gimple_asm_set_volatile (x, true);
5829 expand_asm_stmt (x);
48ae6c13
RH
5830}
5831
5039610b 5832/* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
48ae6c13
RH
5833
5834static void
5039610b 5835expand_builtin_lock_release (enum machine_mode mode, tree exp)
48ae6c13 5836{
48ae6c13 5837 enum insn_code icode;
1387fef3 5838 rtx mem, insn;
02ee605c 5839 rtx val = const0_rtx;
48ae6c13
RH
5840
5841 /* Expand the operands. */
5039610b 5842 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
48ae6c13
RH
5843
5844 /* If there is an explicit operation in the md file, use it. */
5845 icode = sync_lock_release[mode];
5846 if (icode != CODE_FOR_nothing)
5847 {
5848 if (!insn_data[icode].operand[1].predicate (val, mode))
5849 val = force_reg (mode, val);
5850
5851 insn = GEN_FCN (icode) (mem, val);
5852 if (insn)
5853 {
5854 emit_insn (insn);
5855 return;
5856 }
5857 }
5858
5859 /* Otherwise we can implement this operation by emitting a barrier
5860 followed by a store of zero. */
5861 expand_builtin_synchronize ();
5862 emit_move_insn (mem, val);
5863}
28f4ec01
BS
5864\f
5865/* Expand an expression EXP that calls a built-in function,
5866 with result going to TARGET if that's convenient
5867 (and in mode MODE if that's convenient).
5868 SUBTARGET may be used as the target for computing one of EXP's operands.
5869 IGNORE is nonzero if the value is to be ignored. */
5870
5871rtx
4682ae04
AJ
5872expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5873 int ignore)
28f4ec01 5874{
2f503025 5875 tree fndecl = get_callee_fndecl (exp);
28f4ec01 5876 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6c537d03 5877 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
28f4ec01 5878
26db82d8 5879 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5fd9b178 5880 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
8d51ecf8 5881
28f4ec01
BS
5882 /* When not optimizing, generate calls to library functions for a certain
5883 set of builtins. */
d25225de 5884 if (!optimize
48ae6c13 5885 && !called_as_built_in (fndecl)
d25225de 5886 && DECL_ASSEMBLER_NAME_SET_P (fndecl)
f9555f40
JJ
5887 && fcode != BUILT_IN_ALLOCA
5888 && fcode != BUILT_IN_FREE)
d25225de 5889 return expand_call (exp, target, ignore);
28f4ec01 5890
0a45ec5c
RS
5891 /* The built-in function expanders test for target == const0_rtx
5892 to determine whether the function's result will be ignored. */
5893 if (ignore)
5894 target = const0_rtx;
5895
5896 /* If the result of a pure or const built-in function is ignored, and
5897 none of its arguments are volatile, we can avoid expanding the
5898 built-in call and just evaluate the arguments for side-effects. */
5899 if (target == const0_rtx
becfd6e5 5900 && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
0a45ec5c
RS
5901 {
5902 bool volatilep = false;
5903 tree arg;
5039610b 5904 call_expr_arg_iterator iter;
0a45ec5c 5905
5039610b
SL
5906 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5907 if (TREE_THIS_VOLATILE (arg))
0a45ec5c
RS
5908 {
5909 volatilep = true;
5910 break;
5911 }
5912
5913 if (! volatilep)
5914 {
5039610b
SL
5915 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5916 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
0a45ec5c
RS
5917 return const0_rtx;
5918 }
5919 }
5920
28f4ec01
BS
5921 switch (fcode)
5922 {
ea6a6627 5923 CASE_FLT_FN (BUILT_IN_FABS):
5039610b 5924 target = expand_builtin_fabs (exp, target, subtarget);
075ec276 5925 if (target)
c22cacf3 5926 return target;
075ec276
RS
5927 break;
5928
ea6a6627 5929 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5039610b 5930 target = expand_builtin_copysign (exp, target, subtarget);
046625fa
RH
5931 if (target)
5932 return target;
5933 break;
5934
5906d013
EC
5935 /* Just do a normal library call if we were unable to fold
5936 the values. */
ea6a6627 5937 CASE_FLT_FN (BUILT_IN_CABS):
075ec276 5938 break;
28f4ec01 5939
ea6a6627
VR
5940 CASE_FLT_FN (BUILT_IN_EXP):
5941 CASE_FLT_FN (BUILT_IN_EXP10):
5942 CASE_FLT_FN (BUILT_IN_POW10):
5943 CASE_FLT_FN (BUILT_IN_EXP2):
5944 CASE_FLT_FN (BUILT_IN_EXPM1):
5945 CASE_FLT_FN (BUILT_IN_LOGB):
ea6a6627
VR
5946 CASE_FLT_FN (BUILT_IN_LOG):
5947 CASE_FLT_FN (BUILT_IN_LOG10):
5948 CASE_FLT_FN (BUILT_IN_LOG2):
5949 CASE_FLT_FN (BUILT_IN_LOG1P):
5950 CASE_FLT_FN (BUILT_IN_TAN):
5951 CASE_FLT_FN (BUILT_IN_ASIN):
5952 CASE_FLT_FN (BUILT_IN_ACOS):
5953 CASE_FLT_FN (BUILT_IN_ATAN):
dc6707b8 5954 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
de6c5979
BL
5955 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5956 because of possible accuracy problems. */
5957 if (! flag_unsafe_math_optimizations)
28f4ec01 5958 break;
ea6a6627
VR
5959 CASE_FLT_FN (BUILT_IN_SQRT):
5960 CASE_FLT_FN (BUILT_IN_FLOOR):
5961 CASE_FLT_FN (BUILT_IN_CEIL):
5962 CASE_FLT_FN (BUILT_IN_TRUNC):
5963 CASE_FLT_FN (BUILT_IN_ROUND):
5964 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5965 CASE_FLT_FN (BUILT_IN_RINT):
28f4ec01
BS
5966 target = expand_builtin_mathfn (exp, target, subtarget);
5967 if (target)
5968 return target;
5969 break;
5970
eaee4464
UB
5971 CASE_FLT_FN (BUILT_IN_ILOGB):
5972 if (! flag_unsafe_math_optimizations)
5973 break;
9ed4207f 5974 CASE_FLT_FN (BUILT_IN_ISINF):
0c8d3c2b
KG
5975 CASE_FLT_FN (BUILT_IN_FINITE):
5976 case BUILT_IN_ISFINITE:
8a91c45b 5977 case BUILT_IN_ISNORMAL:
eaee4464
UB
5978 target = expand_builtin_interclass_mathfn (exp, target, subtarget);
5979 if (target)
5980 return target;
5981 break;
5982
ea6a6627
VR
5983 CASE_FLT_FN (BUILT_IN_LCEIL):
5984 CASE_FLT_FN (BUILT_IN_LLCEIL):
5985 CASE_FLT_FN (BUILT_IN_LFLOOR):
5986 CASE_FLT_FN (BUILT_IN_LLFLOOR):
1856c8dc 5987 target = expand_builtin_int_roundingfn (exp, target);
d8b42d06
UB
5988 if (target)
5989 return target;
5990 break;
5991
0bfa1541
RG
5992 CASE_FLT_FN (BUILT_IN_LRINT):
5993 CASE_FLT_FN (BUILT_IN_LLRINT):
4d81bf84
RG
5994 CASE_FLT_FN (BUILT_IN_LROUND):
5995 CASE_FLT_FN (BUILT_IN_LLROUND):
1856c8dc 5996 target = expand_builtin_int_roundingfn_2 (exp, target);
0bfa1541
RG
5997 if (target)
5998 return target;
5999 break;
6000
ea6a6627 6001 CASE_FLT_FN (BUILT_IN_POW):
2082e02f
RS
6002 target = expand_builtin_pow (exp, target, subtarget);
6003 if (target)
6004 return target;
6005 break;
6006
ea6a6627 6007 CASE_FLT_FN (BUILT_IN_POWI):
17684d46
RG
6008 target = expand_builtin_powi (exp, target, subtarget);
6009 if (target)
6010 return target;
6011 break;
6012
ea6a6627
VR
6013 CASE_FLT_FN (BUILT_IN_ATAN2):
6014 CASE_FLT_FN (BUILT_IN_LDEXP):
0c0d910d
KG
6015 CASE_FLT_FN (BUILT_IN_SCALB):
6016 CASE_FLT_FN (BUILT_IN_SCALBN):
6017 CASE_FLT_FN (BUILT_IN_SCALBLN):
b5e01d4b
RS
6018 if (! flag_unsafe_math_optimizations)
6019 break;
17b98269
UB
6020
6021 CASE_FLT_FN (BUILT_IN_FMOD):
6022 CASE_FLT_FN (BUILT_IN_REMAINDER):
6023 CASE_FLT_FN (BUILT_IN_DREM):
b5e01d4b
RS
6024 target = expand_builtin_mathfn_2 (exp, target, subtarget);
6025 if (target)
6026 return target;
6027 break;
6028
75c7c595
RG
6029 CASE_FLT_FN (BUILT_IN_CEXPI):
6030 target = expand_builtin_cexpi (exp, target, subtarget);
6031 gcc_assert (target);
6032 return target;
6033
ea6a6627
VR
6034 CASE_FLT_FN (BUILT_IN_SIN):
6035 CASE_FLT_FN (BUILT_IN_COS):
6c7cf1f0
UB
6036 if (! flag_unsafe_math_optimizations)
6037 break;
6038 target = expand_builtin_mathfn_3 (exp, target, subtarget);
6039 if (target)
6040 return target;
6041 break;
6042
403e54f0
RG
6043 CASE_FLT_FN (BUILT_IN_SINCOS):
6044 if (! flag_unsafe_math_optimizations)
6045 break;
6046 target = expand_builtin_sincos (exp);
6047 if (target)
6048 return target;
6049 break;
6050
28f4ec01
BS
6051 case BUILT_IN_APPLY_ARGS:
6052 return expand_builtin_apply_args ();
6053
6054 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6055 FUNCTION with a copy of the parameters described by
6056 ARGUMENTS, and ARGSIZE. It returns a block of memory
6057 allocated on the stack into which is stored all the registers
6058 that might possibly be used for returning the result of a
6059 function. ARGUMENTS is the value returned by
6060 __builtin_apply_args. ARGSIZE is the number of bytes of
6061 arguments that must be copied. ??? How should this value be
6062 computed? We'll also need a safe worst case value for varargs
6063 functions. */
6064 case BUILT_IN_APPLY:
5039610b 6065 if (!validate_arglist (exp, POINTER_TYPE,
019fa094 6066 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5039610b 6067 && !validate_arglist (exp, REFERENCE_TYPE,
019fa094 6068 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
28f4ec01
BS
6069 return const0_rtx;
6070 else
6071 {
28f4ec01
BS
6072 rtx ops[3];
6073
5039610b
SL
6074 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6075 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6076 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
28f4ec01
BS
6077
6078 return expand_builtin_apply (ops[0], ops[1], ops[2]);
6079 }
6080
6081 /* __builtin_return (RESULT) causes the function to return the
6082 value described by RESULT. RESULT is address of the block of
6083 memory returned by __builtin_apply. */
6084 case BUILT_IN_RETURN:
5039610b
SL
6085 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6086 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
28f4ec01
BS
6087 return const0_rtx;
6088
6089 case BUILT_IN_SAVEREGS:
d3707adb 6090 return expand_builtin_saveregs ();
28f4ec01
BS
6091
6092 case BUILT_IN_ARGS_INFO:
5039610b 6093 return expand_builtin_args_info (exp);
28f4ec01 6094
6ef5231b
JJ
6095 case BUILT_IN_VA_ARG_PACK:
6096 /* All valid uses of __builtin_va_arg_pack () are removed during
6097 inlining. */
c94ed7a1 6098 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6ef5231b
JJ
6099 return const0_rtx;
6100
ab0e176c
JJ
6101 case BUILT_IN_VA_ARG_PACK_LEN:
6102 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6103 inlining. */
c94ed7a1 6104 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
ab0e176c
JJ
6105 return const0_rtx;
6106
28f4ec01
BS
6107 /* Return the address of the first anonymous stack arg. */
6108 case BUILT_IN_NEXT_ARG:
5039610b 6109 if (fold_builtin_next_arg (exp, false))
c22cacf3 6110 return const0_rtx;
8870e212 6111 return expand_builtin_next_arg ();
28f4ec01 6112
677feb77
DD
6113 case BUILT_IN_CLEAR_CACHE:
6114 target = expand_builtin___clear_cache (exp);
6115 if (target)
6116 return target;
6117 break;
6118
28f4ec01 6119 case BUILT_IN_CLASSIFY_TYPE:
5039610b 6120 return expand_builtin_classify_type (exp);
28f4ec01
BS
6121
6122 case BUILT_IN_CONSTANT_P:
6de9cd9a 6123 return const0_rtx;
28f4ec01
BS
6124
6125 case BUILT_IN_FRAME_ADDRESS:
6126 case BUILT_IN_RETURN_ADDRESS:
5039610b 6127 return expand_builtin_frame_address (fndecl, exp);
28f4ec01
BS
6128
6129 /* Returns the address of the area where the structure is returned.
6130 0 otherwise. */
6131 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5039610b 6132 if (call_expr_nargs (exp) != 0
ca7fd9cd 6133 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
3c0cb5de 6134 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
ca7fd9cd 6135 return const0_rtx;
28f4ec01 6136 else
ca7fd9cd 6137 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
28f4ec01
BS
6138
6139 case BUILT_IN_ALLOCA:
5039610b 6140 target = expand_builtin_alloca (exp, target);
28f4ec01
BS
6141 if (target)
6142 return target;
6143 break;
6144
6de9cd9a
DN
6145 case BUILT_IN_STACK_SAVE:
6146 return expand_stack_save ();
6147
6148 case BUILT_IN_STACK_RESTORE:
5039610b 6149 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6de9cd9a
DN
6150 return const0_rtx;
6151
167fa32c
EC
6152 case BUILT_IN_BSWAP32:
6153 case BUILT_IN_BSWAP64:
5039610b 6154 target = expand_builtin_bswap (exp, target, subtarget);
167fa32c
EC
6155
6156 if (target)
6157 return target;
6158 break;
6159
ea6a6627 6160 CASE_INT_FN (BUILT_IN_FFS):
2319a1d1 6161 case BUILT_IN_FFSIMAX:
5039610b 6162 target = expand_builtin_unop (target_mode, exp, target,
6c537d03 6163 subtarget, ffs_optab);
2928cd7a
RH
6164 if (target)
6165 return target;
6166 break;
6167
ea6a6627 6168 CASE_INT_FN (BUILT_IN_CLZ):
2319a1d1 6169 case BUILT_IN_CLZIMAX:
5039610b 6170 target = expand_builtin_unop (target_mode, exp, target,
6c537d03 6171 subtarget, clz_optab);
2928cd7a
RH
6172 if (target)
6173 return target;
6174 break;
6175
ea6a6627 6176 CASE_INT_FN (BUILT_IN_CTZ):
2319a1d1 6177 case BUILT_IN_CTZIMAX:
5039610b 6178 target = expand_builtin_unop (target_mode, exp, target,
6c537d03 6179 subtarget, ctz_optab);
2928cd7a
RH
6180 if (target)
6181 return target;
6182 break;
6183
ea6a6627 6184 CASE_INT_FN (BUILT_IN_POPCOUNT):
2319a1d1 6185 case BUILT_IN_POPCOUNTIMAX:
5039610b 6186 target = expand_builtin_unop (target_mode, exp, target,
6c537d03 6187 subtarget, popcount_optab);
2928cd7a
RH
6188 if (target)
6189 return target;
6190 break;
6191
ea6a6627 6192 CASE_INT_FN (BUILT_IN_PARITY):
2319a1d1 6193 case BUILT_IN_PARITYIMAX:
5039610b 6194 target = expand_builtin_unop (target_mode, exp, target,
6c537d03 6195 subtarget, parity_optab);
28f4ec01
BS
6196 if (target)
6197 return target;
6198 break;
6199
6200 case BUILT_IN_STRLEN:
5039610b 6201 target = expand_builtin_strlen (exp, target, target_mode);
28f4ec01
BS
6202 if (target)
6203 return target;
6204 break;
6205
6206 case BUILT_IN_STRCPY:
44e10129 6207 target = expand_builtin_strcpy (exp, target);
28f4ec01
BS
6208 if (target)
6209 return target;
6210 break;
8d51ecf8 6211
da9e9f08 6212 case BUILT_IN_STRNCPY:
44e10129 6213 target = expand_builtin_strncpy (exp, target);
da9e9f08
KG
6214 if (target)
6215 return target;
6216 break;
8d51ecf8 6217
9cb65f92 6218 case BUILT_IN_STPCPY:
609ae0e2 6219 target = expand_builtin_stpcpy (exp, target, mode);
9cb65f92
KG
6220 if (target)
6221 return target;
6222 break;
6223
28f4ec01 6224 case BUILT_IN_MEMCPY:
44e10129 6225 target = expand_builtin_memcpy (exp, target);
9cb65f92
KG
6226 if (target)
6227 return target;
6228 break;
6229
6230 case BUILT_IN_MEMPCPY:
5039610b 6231 target = expand_builtin_mempcpy (exp, target, mode);
28f4ec01
BS
6232 if (target)
6233 return target;
6234 break;
6235
6236 case BUILT_IN_MEMSET:
5039610b 6237 target = expand_builtin_memset (exp, target, mode);
28f4ec01
BS
6238 if (target)
6239 return target;
6240 break;
6241
e3a709be 6242 case BUILT_IN_BZERO:
8148fe65 6243 target = expand_builtin_bzero (exp);
e3a709be
KG
6244 if (target)
6245 return target;
6246 break;
6247
28f4ec01 6248 case BUILT_IN_STRCMP:
44e10129 6249 target = expand_builtin_strcmp (exp, target);
28f4ec01
BS
6250 if (target)
6251 return target;
6252 break;
6253
da9e9f08
KG
6254 case BUILT_IN_STRNCMP:
6255 target = expand_builtin_strncmp (exp, target, mode);
6256 if (target)
6257 return target;
6258 break;
6259
4b2a62db 6260 case BUILT_IN_BCMP:
28f4ec01 6261 case BUILT_IN_MEMCMP:
5039610b 6262 target = expand_builtin_memcmp (exp, target, mode);
28f4ec01
BS
6263 if (target)
6264 return target;
6265 break;
28f4ec01
BS
6266
6267 case BUILT_IN_SETJMP:
4f6c2131
EB
6268 /* This should have been lowered to the builtins below. */
6269 gcc_unreachable ();
6270
6271 case BUILT_IN_SETJMP_SETUP:
6272 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6273 and the receiver label. */
5039610b 6274 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4f6c2131 6275 {
5039610b 6276 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
4f6c2131 6277 VOIDmode, EXPAND_NORMAL);
5039610b 6278 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
4f6c2131
EB
6279 rtx label_r = label_rtx (label);
6280
6281 /* This is copied from the handling of non-local gotos. */
6282 expand_builtin_setjmp_setup (buf_addr, label_r);
6283 nonlocal_goto_handler_labels
6284 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6285 nonlocal_goto_handler_labels);
6286 /* ??? Do not let expand_label treat us as such since we would
6287 not want to be both on the list of non-local labels and on
6288 the list of forced labels. */
6289 FORCED_LABEL (label) = 0;
6290 return const0_rtx;
6291 }
6292 break;
6293
6294 case BUILT_IN_SETJMP_DISPATCHER:
6295 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
5039610b 6296 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4f6c2131 6297 {
5039610b 6298 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
4f6c2131
EB
6299 rtx label_r = label_rtx (label);
6300
6301 /* Remove the dispatcher label from the list of non-local labels
6302 since the receiver labels have been added to it above. */
6303 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6304 return const0_rtx;
6305 }
6306 break;
6307
6308 case BUILT_IN_SETJMP_RECEIVER:
6309 /* __builtin_setjmp_receiver is passed the receiver label. */
5039610b 6310 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4f6c2131 6311 {
5039610b 6312 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
4f6c2131
EB
6313 rtx label_r = label_rtx (label);
6314
6315 expand_builtin_setjmp_receiver (label_r);
6316 return const0_rtx;
6317 }
250d07b6 6318 break;
28f4ec01
BS
6319
6320 /* __builtin_longjmp is passed a pointer to an array of five words.
6321 It's similar to the C library longjmp function but works with
6322 __builtin_setjmp above. */
6323 case BUILT_IN_LONGJMP:
5039610b 6324 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
28f4ec01 6325 {
5039610b 6326 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
84217346 6327 VOIDmode, EXPAND_NORMAL);
5039610b 6328 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
28f4ec01
BS
6329
6330 if (value != const1_rtx)
6331 {
9e637a26 6332 error ("%<__builtin_longjmp%> second argument must be 1");
28f4ec01
BS
6333 return const0_rtx;
6334 }
6335
6336 expand_builtin_longjmp (buf_addr, value);
6337 return const0_rtx;
6338 }
4f6c2131 6339 break;
28f4ec01 6340
6de9cd9a 6341 case BUILT_IN_NONLOCAL_GOTO:
5039610b 6342 target = expand_builtin_nonlocal_goto (exp);
6de9cd9a
DN
6343 if (target)
6344 return target;
6345 break;
6346
2b92e7f5
RK
6347 /* This updates the setjmp buffer that is its argument with the value
6348 of the current stack pointer. */
6349 case BUILT_IN_UPDATE_SETJMP_BUF:
5039610b 6350 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2b92e7f5
RK
6351 {
6352 rtx buf_addr
5039610b 6353 = expand_normal (CALL_EXPR_ARG (exp, 0));
2b92e7f5
RK
6354
6355 expand_builtin_update_setjmp_buf (buf_addr);
6356 return const0_rtx;
6357 }
6358 break;
6359
28f4ec01 6360 case BUILT_IN_TRAP:
9602f5a0 6361 expand_builtin_trap ();
28f4ec01
BS
6362 return const0_rtx;
6363
468059bc
DD
6364 case BUILT_IN_UNREACHABLE:
6365 expand_builtin_unreachable ();
6366 return const0_rtx;
6367
868b8cda 6368 case BUILT_IN_PRINTF:
8148fe65 6369 target = expand_builtin_printf (exp, target, mode, false);
868b8cda
RS
6370 if (target)
6371 return target;
6372 break;
6373
6374 case BUILT_IN_PRINTF_UNLOCKED:
8148fe65 6375 target = expand_builtin_printf (exp, target, mode, true);
868b8cda
RS
6376 if (target)
6377 return target;
6378 break;
6379
868b8cda 6380 case BUILT_IN_FPRINTF:
8148fe65 6381 target = expand_builtin_fprintf (exp, target, mode, false);
868b8cda
RS
6382 if (target)
6383 return target;
6384 break;
6385
6386 case BUILT_IN_FPRINTF_UNLOCKED:
8148fe65 6387 target = expand_builtin_fprintf (exp, target, mode, true);
3ff5f682
KG
6388 if (target)
6389 return target;
6390 break;
8d51ecf8 6391
8e0952f0 6392 case BUILT_IN_SPRINTF:
5039610b 6393 target = expand_builtin_sprintf (exp, target, mode);
8e0952f0
RS
6394 if (target)
6395 return target;
6396 break;
6397
ea6a6627 6398 CASE_FLT_FN (BUILT_IN_SIGNBIT):
44aea9ac
JJ
6399 case BUILT_IN_SIGNBITD32:
6400 case BUILT_IN_SIGNBITD64:
6401 case BUILT_IN_SIGNBITD128:
ef79730c
RS
6402 target = expand_builtin_signbit (exp, target);
6403 if (target)
6404 return target;
6405 break;
6406
28f4ec01
BS
6407 /* Various hooks for the DWARF 2 __throw routine. */
6408 case BUILT_IN_UNWIND_INIT:
6409 expand_builtin_unwind_init ();
6410 return const0_rtx;
6411 case BUILT_IN_DWARF_CFA:
6412 return virtual_cfa_rtx;
6413#ifdef DWARF2_UNWIND_INFO
9c80ff25
RH
6414 case BUILT_IN_DWARF_SP_COLUMN:
6415 return expand_builtin_dwarf_sp_column ();
d9d5c9de 6416 case BUILT_IN_INIT_DWARF_REG_SIZES:
5039610b 6417 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
d9d5c9de 6418 return const0_rtx;
28f4ec01
BS
6419#endif
6420 case BUILT_IN_FROB_RETURN_ADDR:
5039610b 6421 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
28f4ec01 6422 case BUILT_IN_EXTRACT_RETURN_ADDR:
5039610b 6423 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
28f4ec01 6424 case BUILT_IN_EH_RETURN:
5039610b
SL
6425 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6426 CALL_EXPR_ARG (exp, 1));
28f4ec01 6427 return const0_rtx;
52a11cbf
RH
6428#ifdef EH_RETURN_DATA_REGNO
6429 case BUILT_IN_EH_RETURN_DATA_REGNO:
5039610b 6430 return expand_builtin_eh_return_data_regno (exp);
52a11cbf 6431#endif
c76362b4 6432 case BUILT_IN_EXTEND_POINTER:
5039610b 6433 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
1d65f45c
RH
6434 case BUILT_IN_EH_POINTER:
6435 return expand_builtin_eh_pointer (exp);
6436 case BUILT_IN_EH_FILTER:
6437 return expand_builtin_eh_filter (exp);
6438 case BUILT_IN_EH_COPY_VALUES:
6439 return expand_builtin_eh_copy_values (exp);
c76362b4 6440
6c535c69 6441 case BUILT_IN_VA_START:
5039610b 6442 return expand_builtin_va_start (exp);
d3707adb 6443 case BUILT_IN_VA_END:
5039610b 6444 return expand_builtin_va_end (exp);
d3707adb 6445 case BUILT_IN_VA_COPY:
5039610b 6446 return expand_builtin_va_copy (exp);
994a57cd 6447 case BUILT_IN_EXPECT:
5039610b 6448 return expand_builtin_expect (exp, target);
a9ccbb60 6449 case BUILT_IN_PREFETCH:
5039610b 6450 expand_builtin_prefetch (exp);
a9ccbb60
JJ
6451 return const0_rtx;
6452
6de9cd9a
DN
6453 case BUILT_IN_PROFILE_FUNC_ENTER:
6454 return expand_builtin_profile_func (false);
6455 case BUILT_IN_PROFILE_FUNC_EXIT:
6456 return expand_builtin_profile_func (true);
6457
6458 case BUILT_IN_INIT_TRAMPOLINE:
5039610b 6459 return expand_builtin_init_trampoline (exp);
6de9cd9a 6460 case BUILT_IN_ADJUST_TRAMPOLINE:
5039610b 6461 return expand_builtin_adjust_trampoline (exp);
6de9cd9a 6462
d1c38823
ZD
6463 case BUILT_IN_FORK:
6464 case BUILT_IN_EXECL:
6465 case BUILT_IN_EXECV:
6466 case BUILT_IN_EXECLP:
6467 case BUILT_IN_EXECLE:
6468 case BUILT_IN_EXECVP:
6469 case BUILT_IN_EXECVE:
5039610b 6470 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
d1c38823
ZD
6471 if (target)
6472 return target;
6473 break;
28f4ec01 6474
48ae6c13
RH
6475 case BUILT_IN_FETCH_AND_ADD_1:
6476 case BUILT_IN_FETCH_AND_ADD_2:
6477 case BUILT_IN_FETCH_AND_ADD_4:
6478 case BUILT_IN_FETCH_AND_ADD_8:
a0274e3e 6479 case BUILT_IN_FETCH_AND_ADD_16:
02ee605c 6480 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
5039610b 6481 target = expand_builtin_sync_operation (mode, exp, PLUS,
48ae6c13
RH
6482 false, target, ignore);
6483 if (target)
6484 return target;
6485 break;
6486
6487 case BUILT_IN_FETCH_AND_SUB_1:
6488 case BUILT_IN_FETCH_AND_SUB_2:
6489 case BUILT_IN_FETCH_AND_SUB_4:
6490 case BUILT_IN_FETCH_AND_SUB_8:
a0274e3e 6491 case BUILT_IN_FETCH_AND_SUB_16:
02ee605c 6492 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
5039610b 6493 target = expand_builtin_sync_operation (mode, exp, MINUS,
48ae6c13
RH
6494 false, target, ignore);
6495 if (target)
6496 return target;
6497 break;
6498
6499 case BUILT_IN_FETCH_AND_OR_1:
6500 case BUILT_IN_FETCH_AND_OR_2:
6501 case BUILT_IN_FETCH_AND_OR_4:
6502 case BUILT_IN_FETCH_AND_OR_8:
a0274e3e 6503 case BUILT_IN_FETCH_AND_OR_16:
02ee605c 6504 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
5039610b 6505 target = expand_builtin_sync_operation (mode, exp, IOR,
48ae6c13
RH
6506 false, target, ignore);
6507 if (target)
6508 return target;
6509 break;
6510
6511 case BUILT_IN_FETCH_AND_AND_1:
6512 case BUILT_IN_FETCH_AND_AND_2:
6513 case BUILT_IN_FETCH_AND_AND_4:
6514 case BUILT_IN_FETCH_AND_AND_8:
a0274e3e 6515 case BUILT_IN_FETCH_AND_AND_16:
02ee605c 6516 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
5039610b 6517 target = expand_builtin_sync_operation (mode, exp, AND,
48ae6c13
RH
6518 false, target, ignore);
6519 if (target)
6520 return target;
6521 break;
6522
6523 case BUILT_IN_FETCH_AND_XOR_1:
6524 case BUILT_IN_FETCH_AND_XOR_2:
6525 case BUILT_IN_FETCH_AND_XOR_4:
6526 case BUILT_IN_FETCH_AND_XOR_8:
a0274e3e 6527 case BUILT_IN_FETCH_AND_XOR_16:
02ee605c 6528 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
5039610b 6529 target = expand_builtin_sync_operation (mode, exp, XOR,
48ae6c13
RH
6530 false, target, ignore);
6531 if (target)
6532 return target;
6533 break;
6534
6535 case BUILT_IN_FETCH_AND_NAND_1:
6536 case BUILT_IN_FETCH_AND_NAND_2:
6537 case BUILT_IN_FETCH_AND_NAND_4:
6538 case BUILT_IN_FETCH_AND_NAND_8:
a0274e3e 6539 case BUILT_IN_FETCH_AND_NAND_16:
02ee605c 6540 mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
5039610b 6541 target = expand_builtin_sync_operation (mode, exp, NOT,
48ae6c13
RH
6542 false, target, ignore);
6543 if (target)
6544 return target;
6545 break;
6546
6547 case BUILT_IN_ADD_AND_FETCH_1:
6548 case BUILT_IN_ADD_AND_FETCH_2:
6549 case BUILT_IN_ADD_AND_FETCH_4:
6550 case BUILT_IN_ADD_AND_FETCH_8:
a0274e3e 6551 case BUILT_IN_ADD_AND_FETCH_16:
02ee605c 6552 mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
5039610b 6553 target = expand_builtin_sync_operation (mode, exp, PLUS,
48ae6c13
RH
6554 true, target, ignore);
6555 if (target)
6556 return target;
6557 break;
6558
6559 case BUILT_IN_SUB_AND_FETCH_1:
6560 case BUILT_IN_SUB_AND_FETCH_2:
6561 case BUILT_IN_SUB_AND_FETCH_4:
6562 case BUILT_IN_SUB_AND_FETCH_8:
a0274e3e 6563 case BUILT_IN_SUB_AND_FETCH_16:
02ee605c 6564 mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
5039610b 6565 target = expand_builtin_sync_operation (mode, exp, MINUS,
48ae6c13
RH
6566 true, target, ignore);
6567 if (target)
6568 return target;
6569 break;
6570
6571 case BUILT_IN_OR_AND_FETCH_1:
6572 case BUILT_IN_OR_AND_FETCH_2:
6573 case BUILT_IN_OR_AND_FETCH_4:
6574 case BUILT_IN_OR_AND_FETCH_8:
a0274e3e 6575 case BUILT_IN_OR_AND_FETCH_16:
02ee605c 6576 mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
5039610b 6577 target = expand_builtin_sync_operation (mode, exp, IOR,
48ae6c13
RH
6578 true, target, ignore);
6579 if (target)
6580 return target;
6581 break;
6582
6583 case BUILT_IN_AND_AND_FETCH_1:
6584 case BUILT_IN_AND_AND_FETCH_2:
6585 case BUILT_IN_AND_AND_FETCH_4:
6586 case BUILT_IN_AND_AND_FETCH_8:
a0274e3e 6587 case BUILT_IN_AND_AND_FETCH_16:
02ee605c 6588 mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
5039610b 6589 target = expand_builtin_sync_operation (mode, exp, AND,
48ae6c13
RH
6590 true, target, ignore);
6591 if (target)
6592 return target;
6593 break;
6594
6595 case BUILT_IN_XOR_AND_FETCH_1:
6596 case BUILT_IN_XOR_AND_FETCH_2:
6597 case BUILT_IN_XOR_AND_FETCH_4:
6598 case BUILT_IN_XOR_AND_FETCH_8:
a0274e3e 6599 case BUILT_IN_XOR_AND_FETCH_16:
02ee605c 6600 mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
5039610b 6601 target = expand_builtin_sync_operation (mode, exp, XOR,
48ae6c13
RH
6602 true, target, ignore);
6603 if (target)
6604 return target;
6605 break;
6606
6607 case BUILT_IN_NAND_AND_FETCH_1:
6608 case BUILT_IN_NAND_AND_FETCH_2:
6609 case BUILT_IN_NAND_AND_FETCH_4:
6610 case BUILT_IN_NAND_AND_FETCH_8:
a0274e3e 6611 case BUILT_IN_NAND_AND_FETCH_16:
02ee605c 6612 mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
5039610b 6613 target = expand_builtin_sync_operation (mode, exp, NOT,
48ae6c13
RH
6614 true, target, ignore);
6615 if (target)
6616 return target;
6617 break;
6618
6619 case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6620 case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6621 case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6622 case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
a0274e3e 6623 case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
5b5513d0
RH
6624 if (mode == VOIDmode)
6625 mode = TYPE_MODE (boolean_type_node);
48ae6c13
RH
6626 if (!target || !register_operand (target, mode))
6627 target = gen_reg_rtx (mode);
02ee605c
RH
6628
6629 mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
5039610b 6630 target = expand_builtin_compare_and_swap (mode, exp, true, target);
48ae6c13
RH
6631 if (target)
6632 return target;
6633 break;
6634
6635 case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6636 case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6637 case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6638 case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
a0274e3e 6639 case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
02ee605c 6640 mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
5039610b 6641 target = expand_builtin_compare_and_swap (mode, exp, false, target);
48ae6c13
RH
6642 if (target)
6643 return target;
6644 break;
6645
6646 case BUILT_IN_LOCK_TEST_AND_SET_1:
6647 case BUILT_IN_LOCK_TEST_AND_SET_2:
6648 case BUILT_IN_LOCK_TEST_AND_SET_4:
6649 case BUILT_IN_LOCK_TEST_AND_SET_8:
a0274e3e 6650 case BUILT_IN_LOCK_TEST_AND_SET_16:
02ee605c 6651 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
5039610b 6652 target = expand_builtin_lock_test_and_set (mode, exp, target);
48ae6c13
RH
6653 if (target)
6654 return target;
6655 break;
6656
6657 case BUILT_IN_LOCK_RELEASE_1:
6658 case BUILT_IN_LOCK_RELEASE_2:
6659 case BUILT_IN_LOCK_RELEASE_4:
6660 case BUILT_IN_LOCK_RELEASE_8:
a0274e3e 6661 case BUILT_IN_LOCK_RELEASE_16:
02ee605c 6662 mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
5039610b 6663 expand_builtin_lock_release (mode, exp);
48ae6c13
RH
6664 return const0_rtx;
6665
6666 case BUILT_IN_SYNCHRONIZE:
6667 expand_builtin_synchronize ();
6668 return const0_rtx;
6669
10a0d495
JJ
6670 case BUILT_IN_OBJECT_SIZE:
6671 return expand_builtin_object_size (exp);
6672
6673 case BUILT_IN_MEMCPY_CHK:
6674 case BUILT_IN_MEMPCPY_CHK:
6675 case BUILT_IN_MEMMOVE_CHK:
6676 case BUILT_IN_MEMSET_CHK:
6677 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6678 if (target)
6679 return target;
6680 break;
6681
6682 case BUILT_IN_STRCPY_CHK:
6683 case BUILT_IN_STPCPY_CHK:
6684 case BUILT_IN_STRNCPY_CHK:
6685 case BUILT_IN_STRCAT_CHK:
1c2fc017 6686 case BUILT_IN_STRNCAT_CHK:
10a0d495
JJ
6687 case BUILT_IN_SNPRINTF_CHK:
6688 case BUILT_IN_VSNPRINTF_CHK:
6689 maybe_emit_chk_warning (exp, fcode);
6690 break;
6691
6692 case BUILT_IN_SPRINTF_CHK:
6693 case BUILT_IN_VSPRINTF_CHK:
6694 maybe_emit_sprintf_chk_warning (exp, fcode);
6695 break;
6696
f9555f40
JJ
6697 case BUILT_IN_FREE:
6698 maybe_emit_free_warning (exp);
6699 break;
6700
e62f4abc 6701 default: /* just do library call, if unknown builtin */
84b8b0e0 6702 break;
28f4ec01
BS
6703 }
6704
6705 /* The switch statement above can drop through to cause the function
6706 to be called normally. */
6707 return expand_call (exp, target, ignore);
6708}
b0b3afb2 6709
4977bab6 6710/* Determine whether a tree node represents a call to a built-in
feda1845
RS
6711 function. If the tree T is a call to a built-in function with
6712 the right number of arguments of the appropriate types, return
6713 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6714 Otherwise the return value is END_BUILTINS. */
4682ae04 6715
4977bab6 6716enum built_in_function
fa233e34 6717builtin_mathfn_code (const_tree t)
4977bab6 6718{
fa233e34
KG
6719 const_tree fndecl, arg, parmlist;
6720 const_tree argtype, parmtype;
6721 const_call_expr_arg_iterator iter;
4977bab6
ZW
6722
6723 if (TREE_CODE (t) != CALL_EXPR
5039610b 6724 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
4977bab6
ZW
6725 return END_BUILTINS;
6726
2f503025
JM
6727 fndecl = get_callee_fndecl (t);
6728 if (fndecl == NULL_TREE
feda1845 6729 || TREE_CODE (fndecl) != FUNCTION_DECL
4977bab6
ZW
6730 || ! DECL_BUILT_IN (fndecl)
6731 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6732 return END_BUILTINS;
6733
feda1845 6734 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
fa233e34 6735 init_const_call_expr_arg_iterator (t, &iter);
feda1845 6736 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
c0a47a61 6737 {
feda1845
RS
6738 /* If a function doesn't take a variable number of arguments,
6739 the last element in the list will have type `void'. */
6740 parmtype = TREE_VALUE (parmlist);
6741 if (VOID_TYPE_P (parmtype))
6742 {
fa233e34 6743 if (more_const_call_expr_args_p (&iter))
feda1845
RS
6744 return END_BUILTINS;
6745 return DECL_FUNCTION_CODE (fndecl);
6746 }
6747
fa233e34 6748 if (! more_const_call_expr_args_p (&iter))
c0a47a61 6749 return END_BUILTINS;
b8698a0f 6750
fa233e34 6751 arg = next_const_call_expr_arg (&iter);
5039610b 6752 argtype = TREE_TYPE (arg);
feda1845
RS
6753
6754 if (SCALAR_FLOAT_TYPE_P (parmtype))
6755 {
6756 if (! SCALAR_FLOAT_TYPE_P (argtype))
6757 return END_BUILTINS;
6758 }
6759 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6760 {
6761 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6762 return END_BUILTINS;
6763 }
6764 else if (POINTER_TYPE_P (parmtype))
6765 {
6766 if (! POINTER_TYPE_P (argtype))
6767 return END_BUILTINS;
6768 }
6769 else if (INTEGRAL_TYPE_P (parmtype))
6770 {
6771 if (! INTEGRAL_TYPE_P (argtype))
6772 return END_BUILTINS;
6773 }
6774 else
c0a47a61 6775 return END_BUILTINS;
c0a47a61
RS
6776 }
6777
feda1845 6778 /* Variable-length argument list. */
4977bab6
ZW
6779 return DECL_FUNCTION_CODE (fndecl);
6780}
6781
5039610b
SL
6782/* Fold a call to __builtin_constant_p, if we know its argument ARG will
6783 evaluate to a constant. */
b0b3afb2
BS
6784
6785static tree
5039610b 6786fold_builtin_constant_p (tree arg)
b0b3afb2 6787{
b0b3afb2
BS
6788 /* We return 1 for a numeric type that's known to be a constant
6789 value at compile-time or for an aggregate type that's a
6790 literal constant. */
5039610b 6791 STRIP_NOPS (arg);
b0b3afb2
BS
6792
6793 /* If we know this is a constant, emit the constant of one. */
5039610b
SL
6794 if (CONSTANT_CLASS_P (arg)
6795 || (TREE_CODE (arg) == CONSTRUCTOR
6796 && TREE_CONSTANT (arg)))
b0b3afb2 6797 return integer_one_node;
5039610b 6798 if (TREE_CODE (arg) == ADDR_EXPR)
fb664a2c 6799 {
5039610b 6800 tree op = TREE_OPERAND (arg, 0);
fb664a2c
RG
6801 if (TREE_CODE (op) == STRING_CST
6802 || (TREE_CODE (op) == ARRAY_REF
6803 && integer_zerop (TREE_OPERAND (op, 1))
6804 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6805 return integer_one_node;
6806 }
b0b3afb2 6807
0dcd3840
RH
6808 /* If this expression has side effects, show we don't know it to be a
6809 constant. Likewise if it's a pointer or aggregate type since in
6810 those case we only want literals, since those are only optimized
13104975
ZW
6811 when generating RTL, not later.
6812 And finally, if we are compiling an initializer, not code, we
6813 need to return a definite result now; there's not going to be any
6814 more optimization done. */
5039610b
SL
6815 if (TREE_SIDE_EFFECTS (arg)
6816 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6817 || POINTER_TYPE_P (TREE_TYPE (arg))
63b48197
MS
6818 || cfun == 0
6819 || folding_initializer)
b0b3afb2
BS
6820 return integer_zero_node;
6821
5039610b 6822 return NULL_TREE;
b0b3afb2
BS
6823}
6824
419ce103
AN
6825/* Create builtin_expect with PRED and EXPECTED as its arguments and
6826 return it as a truthvalue. */
6de9cd9a
DN
6827
6828static tree
db3927fb 6829build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6de9cd9a 6830{
419ce103 6831 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6de9cd9a 6832
419ce103
AN
6833 fn = built_in_decls[BUILT_IN_EXPECT];
6834 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6835 ret_type = TREE_TYPE (TREE_TYPE (fn));
6836 pred_type = TREE_VALUE (arg_types);
6837 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6838
db3927fb
AH
6839 pred = fold_convert_loc (loc, pred_type, pred);
6840 expected = fold_convert_loc (loc, expected_type, expected);
6841 call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
419ce103
AN
6842
6843 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6844 build_int_cst (ret_type, 0));
6845}
6846
6847/* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
6848 NULL_TREE if no simplification is possible. */
6849
6850static tree
db3927fb 6851fold_builtin_expect (location_t loc, tree arg0, tree arg1)
419ce103
AN
6852{
6853 tree inner, fndecl;
6854 enum tree_code code;
6855
6856 /* If this is a builtin_expect within a builtin_expect keep the
6857 inner one. See through a comparison against a constant. It
6858 might have been added to create a thruthvalue. */
6859 inner = arg0;
6860 if (COMPARISON_CLASS_P (inner)
6861 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6862 inner = TREE_OPERAND (inner, 0);
6863
6864 if (TREE_CODE (inner) == CALL_EXPR
6865 && (fndecl = get_callee_fndecl (inner))
6866 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
6867 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
6868 return arg0;
6869
6870 /* Distribute the expected value over short-circuiting operators.
6871 See through the cast from truthvalue_type_node to long. */
6872 inner = arg0;
6873 while (TREE_CODE (inner) == NOP_EXPR
6874 && INTEGRAL_TYPE_P (TREE_TYPE (inner))
6875 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
6876 inner = TREE_OPERAND (inner, 0);
6877
6878 code = TREE_CODE (inner);
6879 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
6880 {
6881 tree op0 = TREE_OPERAND (inner, 0);
6882 tree op1 = TREE_OPERAND (inner, 1);
6883
db3927fb
AH
6884 op0 = build_builtin_expect_predicate (loc, op0, arg1);
6885 op1 = build_builtin_expect_predicate (loc, op1, arg1);
419ce103
AN
6886 inner = build2 (code, TREE_TYPE (inner), op0, op1);
6887
db3927fb 6888 return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
419ce103
AN
6889 }
6890
6891 /* If the argument isn't invariant then there's nothing else we can do. */
51eed280 6892 if (!TREE_CONSTANT (arg0))
5039610b 6893 return NULL_TREE;
6de9cd9a 6894
419ce103
AN
6895 /* If we expect that a comparison against the argument will fold to
6896 a constant return the constant. In practice, this means a true
6897 constant or the address of a non-weak symbol. */
6898 inner = arg0;
6de9cd9a
DN
6899 STRIP_NOPS (inner);
6900 if (TREE_CODE (inner) == ADDR_EXPR)
6901 {
6902 do
6903 {
6904 inner = TREE_OPERAND (inner, 0);
6905 }
6906 while (TREE_CODE (inner) == COMPONENT_REF
6907 || TREE_CODE (inner) == ARRAY_REF);
5f26a230
JJ
6908 if ((TREE_CODE (inner) == VAR_DECL
6909 || TREE_CODE (inner) == FUNCTION_DECL)
6910 && DECL_WEAK (inner))
5039610b 6911 return NULL_TREE;
6de9cd9a
DN
6912 }
6913
419ce103
AN
6914 /* Otherwise, ARG0 already has the proper type for the return value. */
6915 return arg0;
6de9cd9a
DN
6916}
6917
5039610b 6918/* Fold a call to __builtin_classify_type with argument ARG. */
5197bd50 6919
ad82abb8 6920static tree
5039610b 6921fold_builtin_classify_type (tree arg)
ad82abb8 6922{
5039610b 6923 if (arg == 0)
7d60be94 6924 return build_int_cst (NULL_TREE, no_type_class);
ad82abb8 6925
5039610b 6926 return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
ad82abb8
ZW
6927}
6928
5039610b 6929/* Fold a call to __builtin_strlen with argument ARG. */
667bbbbb
EC
6930
6931static tree
db3927fb 6932fold_builtin_strlen (location_t loc, tree arg)
667bbbbb 6933{
5039610b 6934 if (!validate_arg (arg, POINTER_TYPE))
667bbbbb
EC
6935 return NULL_TREE;
6936 else
6937 {
5039610b 6938 tree len = c_strlen (arg, 0);
667bbbbb
EC
6939
6940 if (len)
6941 {
6942 /* Convert from the internal "sizetype" type to "size_t". */
6943 if (size_type_node)
db3927fb 6944 len = fold_convert_loc (loc, size_type_node, len);
667bbbbb
EC
6945 return len;
6946 }
6947
6948 return NULL_TREE;
6949 }
6950}
6951
ab5e2615
RH
6952/* Fold a call to __builtin_inf or __builtin_huge_val. */
6953
6954static tree
db3927fb 6955fold_builtin_inf (location_t loc, tree type, int warn)
ab5e2615 6956{
efdc7e19
RH
6957 REAL_VALUE_TYPE real;
6958
6d84156b
JM
6959 /* __builtin_inff is intended to be usable to define INFINITY on all
6960 targets. If an infinity is not available, INFINITY expands "to a
6961 positive constant of type float that overflows at translation
6962 time", footnote "In this case, using INFINITY will violate the
6963 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6964 Thus we pedwarn to ensure this constraint violation is
6965 diagnosed. */
ab5e2615 6966 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
db3927fb 6967 pedwarn (loc, 0, "target format does not support infinity");
ab5e2615 6968
efdc7e19
RH
6969 real_inf (&real);
6970 return build_real (type, real);
ab5e2615
RH
6971}
6972
5039610b 6973/* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
1472e41c
RH
6974
6975static tree
5039610b 6976fold_builtin_nan (tree arg, tree type, int quiet)
1472e41c
RH
6977{
6978 REAL_VALUE_TYPE real;
6979 const char *str;
6980
5039610b
SL
6981 if (!validate_arg (arg, POINTER_TYPE))
6982 return NULL_TREE;
6983 str = c_getstr (arg);
1472e41c 6984 if (!str)
5039610b 6985 return NULL_TREE;
1472e41c
RH
6986
6987 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5039610b 6988 return NULL_TREE;
1472e41c
RH
6989
6990 return build_real (type, real);
6991}
6992
0a9530a9
RS
6993/* Return true if the floating point expression T has an integer value.
6994 We also allow +Inf, -Inf and NaN to be considered integer values. */
6995
6996static bool
6997integer_valued_real_p (tree t)
6998{
6999 switch (TREE_CODE (t))
7000 {
7001 case FLOAT_EXPR:
7002 return true;
7003
7004 case ABS_EXPR:
7005 case SAVE_EXPR:
0a9530a9
RS
7006 return integer_valued_real_p (TREE_OPERAND (t, 0));
7007
7008 case COMPOUND_EXPR:
939409af 7009 case MODIFY_EXPR:
0a9530a9 7010 case BIND_EXPR:
726a989a 7011 return integer_valued_real_p (TREE_OPERAND (t, 1));
0a9530a9
RS
7012
7013 case PLUS_EXPR:
7014 case MINUS_EXPR:
7015 case MULT_EXPR:
7016 case MIN_EXPR:
7017 case MAX_EXPR:
7018 return integer_valued_real_p (TREE_OPERAND (t, 0))
7019 && integer_valued_real_p (TREE_OPERAND (t, 1));
7020
7021 case COND_EXPR:
7022 return integer_valued_real_p (TREE_OPERAND (t, 1))
7023 && integer_valued_real_p (TREE_OPERAND (t, 2));
7024
7025 case REAL_CST:
313f234b 7026 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
0a9530a9
RS
7027
7028 case NOP_EXPR:
7029 {
7030 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7031 if (TREE_CODE (type) == INTEGER_TYPE)
7032 return true;
7033 if (TREE_CODE (type) == REAL_TYPE)
7034 return integer_valued_real_p (TREE_OPERAND (t, 0));
7035 break;
7036 }
7037
7038 case CALL_EXPR:
7039 switch (builtin_mathfn_code (t))
7040 {
ea6a6627
VR
7041 CASE_FLT_FN (BUILT_IN_CEIL):
7042 CASE_FLT_FN (BUILT_IN_FLOOR):
7043 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7044 CASE_FLT_FN (BUILT_IN_RINT):
7045 CASE_FLT_FN (BUILT_IN_ROUND):
7046 CASE_FLT_FN (BUILT_IN_TRUNC):
0a9530a9
RS
7047 return true;
7048
b64d949c
KG
7049 CASE_FLT_FN (BUILT_IN_FMIN):
7050 CASE_FLT_FN (BUILT_IN_FMAX):
5039610b
SL
7051 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7052 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
b64d949c 7053
0a9530a9
RS
7054 default:
7055 break;
7056 }
7057 break;
7058
7059 default:
7060 break;
7061 }
7062 return false;
7063}
7064
5039610b 7065/* FNDECL is assumed to be a builtin where truncation can be propagated
27a6aa72 7066 across (for instance floor((double)f) == (double)floorf (f).
5039610b 7067 Do the transformation for a call with argument ARG. */
0a9530a9 7068
27a6aa72 7069static tree
db3927fb 7070fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
27a6aa72 7071{
27a6aa72 7072 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
0a9530a9 7073
5039610b
SL
7074 if (!validate_arg (arg, REAL_TYPE))
7075 return NULL_TREE;
27a6aa72 7076
0a9530a9
RS
7077 /* Integer rounding functions are idempotent. */
7078 if (fcode == builtin_mathfn_code (arg))
7079 return arg;
7080
7081 /* If argument is already integer valued, and we don't need to worry
7082 about setting errno, there's no need to perform rounding. */
7083 if (! flag_errno_math && integer_valued_real_p (arg))
7084 return arg;
7085
7086 if (optimize)
27a6aa72 7087 {
0a9530a9 7088 tree arg0 = strip_float_extensions (arg);
b87e6936 7089 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
27a6aa72
JH
7090 tree newtype = TREE_TYPE (arg0);
7091 tree decl;
7092
7093 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7094 && (decl = mathfn_built_in (newtype, fcode)))
db3927fb
AH
7095 return fold_convert_loc (loc, ftype,
7096 build_call_expr_loc (loc, decl, 1,
7097 fold_convert_loc (loc,
7098 newtype,
7099 arg0)));
27a6aa72 7100 }
5039610b 7101 return NULL_TREE;
27a6aa72
JH
7102}
7103
5039610b
SL
7104/* FNDECL is assumed to be builtin which can narrow the FP type of
7105 the argument, for instance lround((double)f) -> lroundf (f).
7106 Do the transformation for a call with argument ARG. */
ca3df643
KG
7107
7108static tree
db3927fb 7109fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
ca3df643 7110{
ca3df643 7111 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
ca3df643 7112
5039610b
SL
7113 if (!validate_arg (arg, REAL_TYPE))
7114 return NULL_TREE;
ca3df643
KG
7115
7116 /* If argument is already integer valued, and we don't need to worry
7117 about setting errno, there's no need to perform rounding. */
7118 if (! flag_errno_math && integer_valued_real_p (arg))
db3927fb
AH
7119 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7120 TREE_TYPE (TREE_TYPE (fndecl)), arg);
ca3df643
KG
7121
7122 if (optimize)
7123 {
7124 tree ftype = TREE_TYPE (arg);
7125 tree arg0 = strip_float_extensions (arg);
7126 tree newtype = TREE_TYPE (arg0);
7127 tree decl;
7128
7129 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7130 && (decl = mathfn_built_in (newtype, fcode)))
db3927fb
AH
7131 return build_call_expr_loc (loc, decl, 1,
7132 fold_convert_loc (loc, newtype, arg0));
ca3df643 7133 }
482c6ce8
RS
7134
7135 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7136 sizeof (long long) == sizeof (long). */
7137 if (TYPE_PRECISION (long_long_integer_type_node)
7138 == TYPE_PRECISION (long_integer_type_node))
7139 {
7140 tree newfn = NULL_TREE;
7141 switch (fcode)
7142 {
7143 CASE_FLT_FN (BUILT_IN_LLCEIL):
7144 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7145 break;
7146
7147 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7148 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7149 break;
7150
7151 CASE_FLT_FN (BUILT_IN_LLROUND):
7152 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7153 break;
7154
7155 CASE_FLT_FN (BUILT_IN_LLRINT):
7156 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7157 break;
7158
7159 default:
7160 break;
7161 }
7162
7163 if (newfn)
7164 {
db3927fb
AH
7165 tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7166 return fold_convert_loc (loc,
7167 TREE_TYPE (TREE_TYPE (fndecl)), newcall);
482c6ce8
RS
7168 }
7169 }
7170
5039610b 7171 return NULL_TREE;
ca3df643
KG
7172}
7173
5039610b
SL
7174/* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7175 return type. Return NULL_TREE if no simplification can be made. */
07bae5ad
RS
7176
7177static tree
db3927fb 7178fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
07bae5ad 7179{
5039610b 7180 tree res;
07bae5ad 7181
376da68e 7182 if (!validate_arg (arg, COMPLEX_TYPE)
07bae5ad
RS
7183 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7184 return NULL_TREE;
7185
01ffa370
KG
7186 /* Calculate the result when the argument is a constant. */
7187 if (TREE_CODE (arg) == COMPLEX_CST
7188 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7189 type, mpfr_hypot)))
7190 return res;
b8698a0f 7191
d1ad84c2
KG
7192 if (TREE_CODE (arg) == COMPLEX_EXPR)
7193 {
7194 tree real = TREE_OPERAND (arg, 0);
7195 tree imag = TREE_OPERAND (arg, 1);
b8698a0f 7196
d1ad84c2
KG
7197 /* If either part is zero, cabs is fabs of the other. */
7198 if (real_zerop (real))
db3927fb 7199 return fold_build1_loc (loc, ABS_EXPR, type, imag);
d1ad84c2 7200 if (real_zerop (imag))
db3927fb 7201 return fold_build1_loc (loc, ABS_EXPR, type, real);
d1ad84c2
KG
7202
7203 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7204 if (flag_unsafe_math_optimizations
7205 && operand_equal_p (real, imag, OEP_PURE_SAME))
7206 {
b86a760a 7207 const REAL_VALUE_TYPE sqrt2_trunc
9c02cf68 7208 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
d1ad84c2 7209 STRIP_NOPS (real);
db3927fb
AH
7210 return fold_build2_loc (loc, MULT_EXPR, type,
7211 fold_build1_loc (loc, ABS_EXPR, type, real),
b86a760a 7212 build_real (type, sqrt2_trunc));
d1ad84c2
KG
7213 }
7214 }
07bae5ad 7215
4f31c7ec
RS
7216 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7217 if (TREE_CODE (arg) == NEGATE_EXPR
7218 || TREE_CODE (arg) == CONJ_EXPR)
db3927fb 7219 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
4f31c7ec 7220
5906d013
EC
7221 /* Don't do this when optimizing for size. */
7222 if (flag_unsafe_math_optimizations
efd8f750 7223 && optimize && optimize_function_for_speed_p (cfun))
07bae5ad 7224 {
a69934e0 7225 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
07bae5ad
RS
7226
7227 if (sqrtfn != NULL_TREE)
7228 {
5039610b 7229 tree rpart, ipart, result;
07bae5ad 7230
6de9cd9a 7231 arg = builtin_save_expr (arg);
892955bf 7232
db3927fb
AH
7233 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7234 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
07bae5ad 7235
6de9cd9a
DN
7236 rpart = builtin_save_expr (rpart);
7237 ipart = builtin_save_expr (ipart);
07bae5ad 7238
db3927fb
AH
7239 result = fold_build2_loc (loc, PLUS_EXPR, type,
7240 fold_build2_loc (loc, MULT_EXPR, type,
987b67bc 7241 rpart, rpart),
db3927fb 7242 fold_build2_loc (loc, MULT_EXPR, type,
987b67bc 7243 ipart, ipart));
07bae5ad 7244
db3927fb 7245 return build_call_expr_loc (loc, sqrtfn, 1, result);
07bae5ad
RS
7246 }
7247 }
7248
7249 return NULL_TREE;
7250}
7251
5039610b
SL
7252/* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7253 Return NULL_TREE if no simplification can be made. */
667bbbbb
EC
7254
7255static tree
db3927fb 7256fold_builtin_sqrt (location_t loc, tree arg, tree type)
667bbbbb
EC
7257{
7258
7259 enum built_in_function fcode;
4fc78423 7260 tree res;
5039610b
SL
7261
7262 if (!validate_arg (arg, REAL_TYPE))
667bbbbb
EC
7263 return NULL_TREE;
7264
4fc78423
KG
7265 /* Calculate the result when the argument is a constant. */
7266 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7267 return res;
b8698a0f 7268
667bbbbb
EC
7269 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7270 fcode = builtin_mathfn_code (arg);
7271 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7272 {
5039610b 7273 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
db3927fb 7274 arg = fold_build2_loc (loc, MULT_EXPR, type,
5039610b 7275 CALL_EXPR_ARG (arg, 0),
987b67bc 7276 build_real (type, dconsthalf));
db3927fb 7277 return build_call_expr_loc (loc, expfn, 1, arg);
667bbbbb
EC
7278 }
7279
7280 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7281 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7282 {
7283 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7284
7285 if (powfn)
7286 {
5039610b 7287 tree arg0 = CALL_EXPR_ARG (arg, 0);
667bbbbb
EC
7288 tree tree_root;
7289 /* The inner root was either sqrt or cbrt. */
30da6111 7290 /* This was a conditional expression but it triggered a bug
c4e93e28 7291 in Sun C 5.5. */
cb4ad180
AH
7292 REAL_VALUE_TYPE dconstroot;
7293 if (BUILTIN_SQRT_P (fcode))
7294 dconstroot = dconsthalf;
7295 else
7296 dconstroot = dconst_third ();
667bbbbb
EC
7297
7298 /* Adjust for the outer root. */
7299 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7300 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7301 tree_root = build_real (type, dconstroot);
db3927fb 7302 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
667bbbbb
EC
7303 }
7304 }
7305
6a96f5c1 7306 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
667bbbbb
EC
7307 if (flag_unsafe_math_optimizations
7308 && (fcode == BUILT_IN_POW
7309 || fcode == BUILT_IN_POWF
7310 || fcode == BUILT_IN_POWL))
7311 {
5039610b
SL
7312 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7313 tree arg0 = CALL_EXPR_ARG (arg, 0);
7314 tree arg1 = CALL_EXPR_ARG (arg, 1);
6a96f5c1
RG
7315 tree narg1;
7316 if (!tree_expr_nonnegative_p (arg0))
7317 arg0 = build1 (ABS_EXPR, type, arg0);
db3927fb 7318 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
987b67bc 7319 build_real (type, dconsthalf));
db3927fb 7320 return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
667bbbbb
EC
7321 }
7322
7323 return NULL_TREE;
7324}
7325
5039610b
SL
7326/* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7327 Return NULL_TREE if no simplification can be made. */
7328
667bbbbb 7329static tree
db3927fb 7330fold_builtin_cbrt (location_t loc, tree arg, tree type)
667bbbbb 7331{
667bbbbb 7332 const enum built_in_function fcode = builtin_mathfn_code (arg);
cf1491f0 7333 tree res;
667bbbbb 7334
5039610b 7335 if (!validate_arg (arg, REAL_TYPE))
667bbbbb
EC
7336 return NULL_TREE;
7337
cf1491f0
KG
7338 /* Calculate the result when the argument is a constant. */
7339 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7340 return res;
667bbbbb 7341
d86dc303 7342 if (flag_unsafe_math_optimizations)
667bbbbb 7343 {
d86dc303
KG
7344 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7345 if (BUILTIN_EXPONENT_P (fcode))
c22cacf3 7346 {
5039610b 7347 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
d86dc303 7348 const REAL_VALUE_TYPE third_trunc =
9c02cf68 7349 real_value_truncate (TYPE_MODE (type), dconst_third ());
db3927fb 7350 arg = fold_build2_loc (loc, MULT_EXPR, type,
5039610b 7351 CALL_EXPR_ARG (arg, 0),
987b67bc 7352 build_real (type, third_trunc));
db3927fb 7353 return build_call_expr_loc (loc, expfn, 1, arg);
d86dc303 7354 }
667bbbbb 7355
d86dc303
KG
7356 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7357 if (BUILTIN_SQRT_P (fcode))
c22cacf3 7358 {
d86dc303 7359 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
667bbbbb 7360
d86dc303
KG
7361 if (powfn)
7362 {
5039610b 7363 tree arg0 = CALL_EXPR_ARG (arg, 0);
d86dc303 7364 tree tree_root;
9c02cf68 7365 REAL_VALUE_TYPE dconstroot = dconst_third ();
d86dc303
KG
7366
7367 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7368 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7369 tree_root = build_real (type, dconstroot);
db3927fb 7370 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
d86dc303 7371 }
667bbbbb
EC
7372 }
7373
d86dc303
KG
7374 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7375 if (BUILTIN_CBRT_P (fcode))
c22cacf3 7376 {
5039610b 7377 tree arg0 = CALL_EXPR_ARG (arg, 0);
d86dc303
KG
7378 if (tree_expr_nonnegative_p (arg0))
7379 {
7380 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7381
7382 if (powfn)
c22cacf3 7383 {
d86dc303
KG
7384 tree tree_root;
7385 REAL_VALUE_TYPE dconstroot;
c22cacf3 7386
aefa9d43 7387 real_arithmetic (&dconstroot, MULT_EXPR,
9c02cf68 7388 dconst_third_ptr (), dconst_third_ptr ());
d86dc303
KG
7389 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7390 tree_root = build_real (type, dconstroot);
db3927fb 7391 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
d86dc303
KG
7392 }
7393 }
7394 }
c22cacf3 7395
d86dc303 7396 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
b8698a0f 7397 if (fcode == BUILT_IN_POW
5039610b 7398 || fcode == BUILT_IN_POWF
d86dc303 7399 || fcode == BUILT_IN_POWL)
c22cacf3 7400 {
5039610b
SL
7401 tree arg00 = CALL_EXPR_ARG (arg, 0);
7402 tree arg01 = CALL_EXPR_ARG (arg, 1);
d86dc303
KG
7403 if (tree_expr_nonnegative_p (arg00))
7404 {
5039610b 7405 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
d86dc303 7406 const REAL_VALUE_TYPE dconstroot
9c02cf68 7407 = real_value_truncate (TYPE_MODE (type), dconst_third ());
db3927fb 7408 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
987b67bc 7409 build_real (type, dconstroot));
db3927fb 7410 return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
d86dc303
KG
7411 }
7412 }
667bbbbb
EC
7413 }
7414 return NULL_TREE;
7415}
7416
5039610b
SL
7417/* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7418 TYPE is the type of the return value. Return NULL_TREE if no
7419 simplification can be made. */
7420
667bbbbb 7421static tree
db3927fb
AH
7422fold_builtin_cos (location_t loc,
7423 tree arg, tree type, tree fndecl)
667bbbbb 7424{
b81e7144 7425 tree res, narg;
667bbbbb 7426
5039610b 7427 if (!validate_arg (arg, REAL_TYPE))
667bbbbb
EC
7428 return NULL_TREE;
7429
1f3f1f68 7430 /* Calculate the result when the argument is a constant. */
b53fed56 7431 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
1f3f1f68 7432 return res;
b8698a0f 7433
667bbbbb 7434 /* Optimize cos(-x) into cos (x). */
b81e7144 7435 if ((narg = fold_strip_sign_ops (arg)))
db3927fb 7436 return build_call_expr_loc (loc, fndecl, 1, narg);
667bbbbb
EC
7437
7438 return NULL_TREE;
7439}
7440
5039610b
SL
7441/* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7442 Return NULL_TREE if no simplification can be made. */
7443
5c5b2155 7444static tree
db3927fb 7445fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
5c5b2155 7446{
5039610b 7447 if (validate_arg (arg, REAL_TYPE))
5c5b2155 7448 {
5c5b2155
KG
7449 tree res, narg;
7450
7451 /* Calculate the result when the argument is a constant. */
7452 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7453 return res;
b8698a0f 7454
5c5b2155
KG
7455 /* Optimize cosh(-x) into cosh (x). */
7456 if ((narg = fold_strip_sign_ops (arg)))
db3927fb 7457 return build_call_expr_loc (loc, fndecl, 1, narg);
5c5b2155 7458 }
b8698a0f 7459
5c5b2155
KG
7460 return NULL_TREE;
7461}
7462
c128599a
KG
7463/* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7464 argument ARG. TYPE is the type of the return value. Return
7465 NULL_TREE if no simplification can be made. */
7466
7467static tree
db3927fb
AH
7468fold_builtin_ccos (location_t loc,
7469 tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
c128599a
KG
7470 bool hyper ATTRIBUTE_UNUSED)
7471{
7472 if (validate_arg (arg, COMPLEX_TYPE)
7473 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7474 {
7475 tree tmp;
7476
7477#ifdef HAVE_mpc
7478 /* Calculate the result when the argument is a constant. */
7479 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7480 return tmp;
7481#endif
b8698a0f 7482
c128599a
KG
7483 /* Optimize fn(-x) into fn(x). */
7484 if ((tmp = fold_strip_sign_ops (arg)))
db3927fb 7485 return build_call_expr_loc (loc, fndecl, 1, tmp);
c128599a
KG
7486 }
7487
7488 return NULL_TREE;
7489}
7490
5039610b
SL
7491/* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7492 Return NULL_TREE if no simplification can be made. */
7493
667bbbbb 7494static tree
5039610b 7495fold_builtin_tan (tree arg, tree type)
667bbbbb
EC
7496{
7497 enum built_in_function fcode;
cf1491f0 7498 tree res;
667bbbbb 7499
5039610b 7500 if (!validate_arg (arg, REAL_TYPE))
667bbbbb
EC
7501 return NULL_TREE;
7502
1f3f1f68 7503 /* Calculate the result when the argument is a constant. */
b53fed56 7504 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
1f3f1f68 7505 return res;
b8698a0f 7506
667bbbbb
EC
7507 /* Optimize tan(atan(x)) = x. */
7508 fcode = builtin_mathfn_code (arg);
7509 if (flag_unsafe_math_optimizations
7510 && (fcode == BUILT_IN_ATAN
7511 || fcode == BUILT_IN_ATANF
7512 || fcode == BUILT_IN_ATANL))
5039610b 7513 return CALL_EXPR_ARG (arg, 0);
667bbbbb
EC
7514
7515 return NULL_TREE;
7516}
7517
75c7c595
RG
7518/* Fold function call to builtin sincos, sincosf, or sincosl. Return
7519 NULL_TREE if no simplification can be made. */
7520
7521static tree
db3927fb
AH
7522fold_builtin_sincos (location_t loc,
7523 tree arg0, tree arg1, tree arg2)
75c7c595 7524{
5039610b 7525 tree type;
75c7c595
RG
7526 tree res, fn, call;
7527
5039610b
SL
7528 if (!validate_arg (arg0, REAL_TYPE)
7529 || !validate_arg (arg1, POINTER_TYPE)
7530 || !validate_arg (arg2, POINTER_TYPE))
75c7c595
RG
7531 return NULL_TREE;
7532
75c7c595 7533 type = TREE_TYPE (arg0);
75c7c595
RG
7534
7535 /* Calculate the result when the argument is a constant. */
7536 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7537 return res;
7538
7539 /* Canonicalize sincos to cexpi. */
2d38026b
RS
7540 if (!TARGET_C99_FUNCTIONS)
7541 return NULL_TREE;
75c7c595
RG
7542 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7543 if (!fn)
7544 return NULL_TREE;
7545
db3927fb 7546 call = build_call_expr_loc (loc, fn, 1, arg0);
75c7c595
RG
7547 call = builtin_save_expr (call);
7548
928c19bb 7549 return build2 (COMPOUND_EXPR, void_type_node,
75c7c595 7550 build2 (MODIFY_EXPR, void_type_node,
db3927fb 7551 build_fold_indirect_ref_loc (loc, arg1),
75c7c595
RG
7552 build1 (IMAGPART_EXPR, type, call)),
7553 build2 (MODIFY_EXPR, void_type_node,
db3927fb 7554 build_fold_indirect_ref_loc (loc, arg2),
75c7c595
RG
7555 build1 (REALPART_EXPR, type, call)));
7556}
7557
28f4586b
RG
7558/* Fold function call to builtin cexp, cexpf, or cexpl. Return
7559 NULL_TREE if no simplification can be made. */
7560
7561static tree
db3927fb 7562fold_builtin_cexp (location_t loc, tree arg0, tree type)
28f4586b 7563{
5039610b 7564 tree rtype;
28f4586b 7565 tree realp, imagp, ifn;
c128599a
KG
7566#ifdef HAVE_mpc
7567 tree res;
7568#endif
28f4586b 7569
c128599a 7570 if (!validate_arg (arg0, COMPLEX_TYPE)
376da68e 7571 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
28f4586b
RG
7572 return NULL_TREE;
7573
c128599a
KG
7574#ifdef HAVE_mpc
7575 /* Calculate the result when the argument is a constant. */
7576 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7577 return res;
7578#endif
b8698a0f 7579
28f4586b
RG
7580 rtype = TREE_TYPE (TREE_TYPE (arg0));
7581
7582 /* In case we can figure out the real part of arg0 and it is constant zero
7583 fold to cexpi. */
2d38026b
RS
7584 if (!TARGET_C99_FUNCTIONS)
7585 return NULL_TREE;
28f4586b
RG
7586 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7587 if (!ifn)
7588 return NULL_TREE;
7589
db3927fb 7590 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
28f4586b
RG
7591 && real_zerop (realp))
7592 {
db3927fb
AH
7593 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7594 return build_call_expr_loc (loc, ifn, 1, narg);
28f4586b
RG
7595 }
7596
7597 /* In case we can easily decompose real and imaginary parts split cexp
7598 to exp (r) * cexpi (i). */
7599 if (flag_unsafe_math_optimizations
7600 && realp)
7601 {
7602 tree rfn, rcall, icall;
7603
7604 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7605 if (!rfn)
7606 return NULL_TREE;
7607
db3927fb 7608 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
28f4586b
RG
7609 if (!imagp)
7610 return NULL_TREE;
7611
db3927fb 7612 icall = build_call_expr_loc (loc, ifn, 1, imagp);
28f4586b 7613 icall = builtin_save_expr (icall);
db3927fb 7614 rcall = build_call_expr_loc (loc, rfn, 1, realp);
28f4586b 7615 rcall = builtin_save_expr (rcall);
db3927fb
AH
7616 return fold_build2_loc (loc, COMPLEX_EXPR, type,
7617 fold_build2_loc (loc, MULT_EXPR, rtype,
111f1fca 7618 rcall,
db3927fb
AH
7619 fold_build1_loc (loc, REALPART_EXPR,
7620 rtype, icall)),
7621 fold_build2_loc (loc, MULT_EXPR, rtype,
111f1fca 7622 rcall,
db3927fb
AH
7623 fold_build1_loc (loc, IMAGPART_EXPR,
7624 rtype, icall)));
28f4586b
RG
7625 }
7626
7627 return NULL_TREE;
7628}
7629
5039610b
SL
7630/* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7631 Return NULL_TREE if no simplification can be made. */
0a9530a9
RS
7632
7633static tree
db3927fb 7634fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
0a9530a9 7635{
5039610b
SL
7636 if (!validate_arg (arg, REAL_TYPE))
7637 return NULL_TREE;
0a9530a9
RS
7638
7639 /* Optimize trunc of constant value. */
455f14dd 7640 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
0a9530a9
RS
7641 {
7642 REAL_VALUE_TYPE r, x;
b87e6936 7643 tree type = TREE_TYPE (TREE_TYPE (fndecl));
0a9530a9
RS
7644
7645 x = TREE_REAL_CST (arg);
7646 real_trunc (&r, TYPE_MODE (type), &x);
7647 return build_real (type, r);
7648 }
7649
db3927fb 7650 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
0a9530a9
RS
7651}
7652
5039610b
SL
7653/* Fold function call to builtin floor, floorf or floorl with argument ARG.
7654 Return NULL_TREE if no simplification can be made. */
0a9530a9
RS
7655
7656static tree
db3927fb 7657fold_builtin_floor (location_t loc, tree fndecl, tree arg)
0a9530a9 7658{
5039610b
SL
7659 if (!validate_arg (arg, REAL_TYPE))
7660 return NULL_TREE;
0a9530a9
RS
7661
7662 /* Optimize floor of constant value. */
455f14dd 7663 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
0a9530a9
RS
7664 {
7665 REAL_VALUE_TYPE x;
7666
7667 x = TREE_REAL_CST (arg);
7668 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7669 {
b87e6936 7670 tree type = TREE_TYPE (TREE_TYPE (fndecl));
0a9530a9
RS
7671 REAL_VALUE_TYPE r;
7672
7673 real_floor (&r, TYPE_MODE (type), &x);
7674 return build_real (type, r);
7675 }
7676 }
7677
e1502f6e
RG
7678 /* Fold floor (x) where x is nonnegative to trunc (x). */
7679 if (tree_expr_nonnegative_p (arg))
7c73bdc1
RS
7680 {
7681 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7682 if (truncfn)
db3927fb 7683 return build_call_expr_loc (loc, truncfn, 1, arg);
7c73bdc1 7684 }
e1502f6e 7685
db3927fb 7686 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
0a9530a9
RS
7687}
7688
5039610b
SL
7689/* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7690 Return NULL_TREE if no simplification can be made. */
0a9530a9
RS
7691
7692static tree
db3927fb 7693fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
0a9530a9 7694{
5039610b
SL
7695 if (!validate_arg (arg, REAL_TYPE))
7696 return NULL_TREE;
0a9530a9
RS
7697
7698 /* Optimize ceil of constant value. */
455f14dd 7699 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
0a9530a9
RS
7700 {
7701 REAL_VALUE_TYPE x;
7702
7703 x = TREE_REAL_CST (arg);
7704 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7705 {
b87e6936 7706 tree type = TREE_TYPE (TREE_TYPE (fndecl));
0a9530a9
RS
7707 REAL_VALUE_TYPE r;
7708
7709 real_ceil (&r, TYPE_MODE (type), &x);
7710 return build_real (type, r);
7711 }
7712 }
7713
db3927fb 7714 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
0a9530a9
RS
7715}
7716
5039610b
SL
7717/* Fold function call to builtin round, roundf or roundl with argument ARG.
7718 Return NULL_TREE if no simplification can be made. */
25348c94
RS
7719
7720static tree
db3927fb 7721fold_builtin_round (location_t loc, tree fndecl, tree arg)
25348c94 7722{
5039610b
SL
7723 if (!validate_arg (arg, REAL_TYPE))
7724 return NULL_TREE;
25348c94 7725
3bf05748 7726 /* Optimize round of constant value. */
455f14dd 7727 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
25348c94
RS
7728 {
7729 REAL_VALUE_TYPE x;
7730
7731 x = TREE_REAL_CST (arg);
7732 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7733 {
b87e6936 7734 tree type = TREE_TYPE (TREE_TYPE (fndecl));
25348c94
RS
7735 REAL_VALUE_TYPE r;
7736
7737 real_round (&r, TYPE_MODE (type), &x);
7738 return build_real (type, r);
7739 }
7740 }
7741
db3927fb 7742 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
25348c94
RS
7743}
7744
3bf05748 7745/* Fold function call to builtin lround, lroundf or lroundl (or the
5039610b
SL
7746 corresponding long long versions) and other rounding functions. ARG
7747 is the argument to the call. Return NULL_TREE if no simplification
7748 can be made. */
3bf05748
KG
7749
7750static tree
db3927fb 7751fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
3bf05748 7752{
5039610b
SL
7753 if (!validate_arg (arg, REAL_TYPE))
7754 return NULL_TREE;
3bf05748
KG
7755
7756 /* Optimize lround of constant value. */
455f14dd 7757 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
3bf05748
KG
7758 {
7759 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7760
4c8c70e0 7761 if (real_isfinite (&x))
3bf05748 7762 {
b87e6936 7763 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
2b60792f
RG
7764 tree ftype = TREE_TYPE (arg);
7765 unsigned HOST_WIDE_INT lo2;
3bf05748
KG
7766 HOST_WIDE_INT hi, lo;
7767 REAL_VALUE_TYPE r;
7768
d8b42d06
UB
7769 switch (DECL_FUNCTION_CODE (fndecl))
7770 {
ea6a6627
VR
7771 CASE_FLT_FN (BUILT_IN_LFLOOR):
7772 CASE_FLT_FN (BUILT_IN_LLFLOOR):
d8b42d06
UB
7773 real_floor (&r, TYPE_MODE (ftype), &x);
7774 break;
7775
ea6a6627
VR
7776 CASE_FLT_FN (BUILT_IN_LCEIL):
7777 CASE_FLT_FN (BUILT_IN_LLCEIL):
f94b1661
UB
7778 real_ceil (&r, TYPE_MODE (ftype), &x);
7779 break;
7780
ea6a6627
VR
7781 CASE_FLT_FN (BUILT_IN_LROUND):
7782 CASE_FLT_FN (BUILT_IN_LLROUND):
d8b42d06
UB
7783 real_round (&r, TYPE_MODE (ftype), &x);
7784 break;
7785
7786 default:
7787 gcc_unreachable ();
7788 }
7789
3bf05748 7790 REAL_VALUE_TO_INT (&lo, &hi, r);
2b60792f
RG
7791 if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7792 return build_int_cst_wide (itype, lo2, hi);
3bf05748
KG
7793 }
7794 }
7795
e1502f6e
RG
7796 switch (DECL_FUNCTION_CODE (fndecl))
7797 {
7798 CASE_FLT_FN (BUILT_IN_LFLOOR):
7799 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7800 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
7801 if (tree_expr_nonnegative_p (arg))
db3927fb
AH
7802 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7803 TREE_TYPE (TREE_TYPE (fndecl)), arg);
e1502f6e
RG
7804 break;
7805 default:;
7806 }
7807
db3927fb 7808 return fold_fixed_mathfn (loc, fndecl, arg);
3bf05748
KG
7809}
7810
cf42869d 7811/* Fold function call to builtin ffs, clz, ctz, popcount and parity
5039610b
SL
7812 and their long and long long variants (i.e. ffsl and ffsll). ARG is
7813 the argument to the call. Return NULL_TREE if no simplification can
7814 be made. */
cf42869d
RS
7815
7816static tree
5039610b 7817fold_builtin_bitop (tree fndecl, tree arg)
cf42869d 7818{
5039610b 7819 if (!validate_arg (arg, INTEGER_TYPE))
cf42869d
RS
7820 return NULL_TREE;
7821
7822 /* Optimize for constant argument. */
455f14dd 7823 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
cf42869d
RS
7824 {
7825 HOST_WIDE_INT hi, width, result;
7826 unsigned HOST_WIDE_INT lo;
4a90aeeb 7827 tree type;
cf42869d
RS
7828
7829 type = TREE_TYPE (arg);
7830 width = TYPE_PRECISION (type);
7831 lo = TREE_INT_CST_LOW (arg);
7832
7833 /* Clear all the bits that are beyond the type's precision. */
7834 if (width > HOST_BITS_PER_WIDE_INT)
7835 {
7836 hi = TREE_INT_CST_HIGH (arg);
7837 if (width < 2 * HOST_BITS_PER_WIDE_INT)
7838 hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7839 }
7840 else
7841 {
7842 hi = 0;
7843 if (width < HOST_BITS_PER_WIDE_INT)
7844 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7845 }
7846
7847 switch (DECL_FUNCTION_CODE (fndecl))
7848 {
ea6a6627 7849 CASE_INT_FN (BUILT_IN_FFS):
cf42869d
RS
7850 if (lo != 0)
7851 result = exact_log2 (lo & -lo) + 1;
7852 else if (hi != 0)
7853 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7854 else
7855 result = 0;
7856 break;
7857
ea6a6627 7858 CASE_INT_FN (BUILT_IN_CLZ):
cf42869d
RS
7859 if (hi != 0)
7860 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7861 else if (lo != 0)
7862 result = width - floor_log2 (lo) - 1;
7863 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7864 result = width;
7865 break;
7866
ea6a6627 7867 CASE_INT_FN (BUILT_IN_CTZ):
cf42869d
RS
7868 if (lo != 0)
7869 result = exact_log2 (lo & -lo);
7870 else if (hi != 0)
7871 result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7872 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7873 result = width;
7874 break;
7875
ea6a6627 7876 CASE_INT_FN (BUILT_IN_POPCOUNT):
cf42869d
RS
7877 result = 0;
7878 while (lo)
7879 result++, lo &= lo - 1;
7880 while (hi)
7881 result++, hi &= hi - 1;
7882 break;
7883
ea6a6627 7884 CASE_INT_FN (BUILT_IN_PARITY):
cf42869d
RS
7885 result = 0;
7886 while (lo)
7887 result++, lo &= lo - 1;
7888 while (hi)
7889 result++, hi &= hi - 1;
7890 result &= 1;
7891 break;
7892
7893 default:
298e6adc 7894 gcc_unreachable ();
cf42869d
RS
7895 }
7896
b87e6936 7897 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
cf42869d
RS
7898 }
7899
7900 return NULL_TREE;
7901}
7902
167fa32c
EC
7903/* Fold function call to builtin_bswap and the long and long long
7904 variants. Return NULL_TREE if no simplification can be made. */
7905static tree
5039610b 7906fold_builtin_bswap (tree fndecl, tree arg)
167fa32c 7907{
5039610b
SL
7908 if (! validate_arg (arg, INTEGER_TYPE))
7909 return NULL_TREE;
167fa32c
EC
7910
7911 /* Optimize constant value. */
455f14dd 7912 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
167fa32c
EC
7913 {
7914 HOST_WIDE_INT hi, width, r_hi = 0;
7915 unsigned HOST_WIDE_INT lo, r_lo = 0;
7916 tree type;
7917
7918 type = TREE_TYPE (arg);
7919 width = TYPE_PRECISION (type);
7920 lo = TREE_INT_CST_LOW (arg);
7921 hi = TREE_INT_CST_HIGH (arg);
7922
7923 switch (DECL_FUNCTION_CODE (fndecl))
7924 {
7925 case BUILT_IN_BSWAP32:
7926 case BUILT_IN_BSWAP64:
7927 {
7928 int s;
7929
7930 for (s = 0; s < width; s += 8)
7931 {
7932 int d = width - s - 8;
7933 unsigned HOST_WIDE_INT byte;
7934
7935 if (s < HOST_BITS_PER_WIDE_INT)
7936 byte = (lo >> s) & 0xff;
7937 else
7938 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7939
7940 if (d < HOST_BITS_PER_WIDE_INT)
7941 r_lo |= byte << d;
7942 else
7943 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7944 }
7945 }
7946
7947 break;
7948
7949 default:
7950 gcc_unreachable ();
7951 }
7952
7953 if (width < HOST_BITS_PER_WIDE_INT)
7954 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7955 else
7956 return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7957 }
7958
7959 return NULL_TREE;
7960}
5039610b 7961
f7657db9 7962/* A subroutine of fold_builtin to fold the various logarithmic
cf1491f0
KG
7963 functions. Return NULL_TREE if no simplification can me made.
7964 FUNC is the corresponding MPFR logarithm function. */
f7657db9
KG
7965
7966static tree
db3927fb 7967fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
cf1491f0 7968 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
f7657db9 7969{
5039610b 7970 if (validate_arg (arg, REAL_TYPE))
f7657db9 7971 {
f7657db9 7972 tree type = TREE_TYPE (TREE_TYPE (fndecl));
cf1491f0 7973 tree res;
f7657db9 7974 const enum built_in_function fcode = builtin_mathfn_code (arg);
33521f7d 7975
cf1491f0
KG
7976 /* Calculate the result when the argument is a constant. */
7977 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7978 return res;
7979
f7657db9
KG
7980 /* Special case, optimize logN(expN(x)) = x. */
7981 if (flag_unsafe_math_optimizations
cf1491f0 7982 && ((func == mpfr_log
f7657db9
KG
7983 && (fcode == BUILT_IN_EXP
7984 || fcode == BUILT_IN_EXPF
7985 || fcode == BUILT_IN_EXPL))
cf1491f0 7986 || (func == mpfr_log2
f7657db9
KG
7987 && (fcode == BUILT_IN_EXP2
7988 || fcode == BUILT_IN_EXP2F
7989 || fcode == BUILT_IN_EXP2L))
cf1491f0 7990 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
db3927fb 7991 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
f7657db9 7992
f2f4e976 7993 /* Optimize logN(func()) for various exponential functions. We
c22cacf3
MS
7994 want to determine the value "x" and the power "exponent" in
7995 order to transform logN(x**exponent) into exponent*logN(x). */
f7657db9 7996 if (flag_unsafe_math_optimizations)
c22cacf3 7997 {
f7657db9 7998 tree exponent = 0, x = 0;
33521f7d 7999
f7657db9
KG
8000 switch (fcode)
8001 {
ea6a6627 8002 CASE_FLT_FN (BUILT_IN_EXP):
f7657db9 8003 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
b8698a0f 8004 x = build_real (type, real_value_truncate (TYPE_MODE (type),
9c02cf68 8005 dconst_e ()));
5039610b 8006 exponent = CALL_EXPR_ARG (arg, 0);
f7657db9 8007 break;
ea6a6627 8008 CASE_FLT_FN (BUILT_IN_EXP2):
f7657db9
KG
8009 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8010 x = build_real (type, dconst2);
5039610b 8011 exponent = CALL_EXPR_ARG (arg, 0);
f7657db9 8012 break;
ea6a6627
VR
8013 CASE_FLT_FN (BUILT_IN_EXP10):
8014 CASE_FLT_FN (BUILT_IN_POW10):
f7657db9 8015 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
aefa9d43
KG
8016 {
8017 REAL_VALUE_TYPE dconst10;
8018 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8019 x = build_real (type, dconst10);
8020 }
5039610b 8021 exponent = CALL_EXPR_ARG (arg, 0);
f7657db9 8022 break;
ea6a6627 8023 CASE_FLT_FN (BUILT_IN_SQRT):
f7657db9 8024 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
5039610b 8025 x = CALL_EXPR_ARG (arg, 0);
f7657db9
KG
8026 exponent = build_real (type, dconsthalf);
8027 break;
ea6a6627 8028 CASE_FLT_FN (BUILT_IN_CBRT):
f7657db9 8029 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
5039610b 8030 x = CALL_EXPR_ARG (arg, 0);
f7657db9 8031 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
9c02cf68 8032 dconst_third ()));
f7657db9 8033 break;
ea6a6627 8034 CASE_FLT_FN (BUILT_IN_POW):
f7657db9 8035 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
5039610b
SL
8036 x = CALL_EXPR_ARG (arg, 0);
8037 exponent = CALL_EXPR_ARG (arg, 1);
f7657db9
KG
8038 break;
8039 default:
8040 break;
8041 }
8042
8043 /* Now perform the optimization. */
8044 if (x && exponent)
8045 {
db3927fb
AH
8046 tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8047 return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
f7657db9
KG
8048 }
8049 }
8050 }
8051
5039610b 8052 return NULL_TREE;
f7657db9 8053}
33521f7d 8054
4413d881
KG
8055/* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8056 NULL_TREE if no simplification can be made. */
8057
8058static tree
db3927fb
AH
8059fold_builtin_hypot (location_t loc, tree fndecl,
8060 tree arg0, tree arg1, tree type)
4413d881 8061{
b81e7144 8062 tree res, narg0, narg1;
4413d881 8063
5039610b
SL
8064 if (!validate_arg (arg0, REAL_TYPE)
8065 || !validate_arg (arg1, REAL_TYPE))
4413d881
KG
8066 return NULL_TREE;
8067
8068 /* Calculate the result when the argument is a constant. */
8069 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8070 return res;
b8698a0f 8071
012c5368
KG
8072 /* If either argument to hypot has a negate or abs, strip that off.
8073 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
b81e7144
KG
8074 narg0 = fold_strip_sign_ops (arg0);
8075 narg1 = fold_strip_sign_ops (arg1);
8076 if (narg0 || narg1)
8077 {
b8698a0f 8078 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
5039610b 8079 narg1 ? narg1 : arg1);
012c5368 8080 }
b8698a0f 8081
4413d881
KG
8082 /* If either argument is zero, hypot is fabs of the other. */
8083 if (real_zerop (arg0))
db3927fb 8084 return fold_build1_loc (loc, ABS_EXPR, type, arg1);
4413d881 8085 else if (real_zerop (arg1))
db3927fb 8086 return fold_build1_loc (loc, ABS_EXPR, type, arg0);
b8698a0f 8087
012c5368
KG
8088 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8089 if (flag_unsafe_math_optimizations
8090 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
4413d881 8091 {
b86a760a 8092 const REAL_VALUE_TYPE sqrt2_trunc
9c02cf68 8093 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
db3927fb
AH
8094 return fold_build2_loc (loc, MULT_EXPR, type,
8095 fold_build1_loc (loc, ABS_EXPR, type, arg0),
b86a760a 8096 build_real (type, sqrt2_trunc));
4413d881
KG
8097 }
8098
4413d881
KG
8099 return NULL_TREE;
8100}
8101
8102
667bbbbb
EC
8103/* Fold a builtin function call to pow, powf, or powl. Return
8104 NULL_TREE if no simplification can be made. */
8105static tree
db3927fb 8106fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
667bbbbb 8107{
4413d881 8108 tree res;
667bbbbb 8109
5039610b
SL
8110 if (!validate_arg (arg0, REAL_TYPE)
8111 || !validate_arg (arg1, REAL_TYPE))
667bbbbb
EC
8112 return NULL_TREE;
8113
4413d881
KG
8114 /* Calculate the result when the argument is a constant. */
8115 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8116 return res;
8117
667bbbbb
EC
8118 /* Optimize pow(1.0,y) = 1.0. */
8119 if (real_onep (arg0))
db3927fb 8120 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
667bbbbb
EC
8121
8122 if (TREE_CODE (arg1) == REAL_CST
455f14dd 8123 && !TREE_OVERFLOW (arg1))
667bbbbb 8124 {
e3bb43c0 8125 REAL_VALUE_TYPE cint;
667bbbbb 8126 REAL_VALUE_TYPE c;
e3bb43c0
RS
8127 HOST_WIDE_INT n;
8128
667bbbbb
EC
8129 c = TREE_REAL_CST (arg1);
8130
8131 /* Optimize pow(x,0.0) = 1.0. */
8132 if (REAL_VALUES_EQUAL (c, dconst0))
db3927fb 8133 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
667bbbbb
EC
8134 arg0);
8135
8136 /* Optimize pow(x,1.0) = x. */
8137 if (REAL_VALUES_EQUAL (c, dconst1))
8138 return arg0;
8139
8140 /* Optimize pow(x,-1.0) = 1.0/x. */
8141 if (REAL_VALUES_EQUAL (c, dconstm1))
db3927fb 8142 return fold_build2_loc (loc, RDIV_EXPR, type,
987b67bc 8143 build_real (type, dconst1), arg0);
667bbbbb
EC
8144
8145 /* Optimize pow(x,0.5) = sqrt(x). */
8146 if (flag_unsafe_math_optimizations
8147 && REAL_VALUES_EQUAL (c, dconsthalf))
8148 {
8149 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8150
8151 if (sqrtfn != NULL_TREE)
db3927fb 8152 return build_call_expr_loc (loc, sqrtfn, 1, arg0);
667bbbbb
EC
8153 }
8154
495ed96c
UB
8155 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8156 if (flag_unsafe_math_optimizations)
8157 {
8158 const REAL_VALUE_TYPE dconstroot
9c02cf68 8159 = real_value_truncate (TYPE_MODE (type), dconst_third ());
495ed96c
UB
8160
8161 if (REAL_VALUES_EQUAL (c, dconstroot))
8162 {
8163 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8164 if (cbrtfn != NULL_TREE)
db3927fb 8165 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
495ed96c
UB
8166 }
8167 }
8168
e3bb43c0
RS
8169 /* Check for an integer exponent. */
8170 n = real_to_integer (&c);
8171 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8172 if (real_identical (&c, &cint))
667bbbbb 8173 {
17372f8c
DJ
8174 /* Attempt to evaluate pow at compile-time, unless this should
8175 raise an exception. */
e3bb43c0 8176 if (TREE_CODE (arg0) == REAL_CST
17372f8c
DJ
8177 && !TREE_OVERFLOW (arg0)
8178 && (n > 0
8179 || (!flag_trapping_math && !flag_errno_math)
8180 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
667bbbbb
EC
8181 {
8182 REAL_VALUE_TYPE x;
8183 bool inexact;
8184
8185 x = TREE_REAL_CST (arg0);
8186 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8187 if (flag_unsafe_math_optimizations || !inexact)
8188 return build_real (type, x);
8189 }
e3bb43c0
RS
8190
8191 /* Strip sign ops from even integer powers. */
8192 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8193 {
8194 tree narg0 = fold_strip_sign_ops (arg0);
8195 if (narg0)
db3927fb 8196 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
e3bb43c0 8197 }
667bbbbb
EC
8198 }
8199 }
8200
d86dc303 8201 if (flag_unsafe_math_optimizations)
667bbbbb 8202 {
d86dc303 8203 const enum built_in_function fcode = builtin_mathfn_code (arg0);
667bbbbb 8204
d86dc303
KG
8205 /* Optimize pow(expN(x),y) = expN(x*y). */
8206 if (BUILTIN_EXPONENT_P (fcode))
c22cacf3 8207 {
5039610b
SL
8208 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8209 tree arg = CALL_EXPR_ARG (arg0, 0);
db3927fb
AH
8210 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8211 return build_call_expr_loc (loc, expfn, 1, arg);
d86dc303 8212 }
667bbbbb 8213
d86dc303
KG
8214 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8215 if (BUILTIN_SQRT_P (fcode))
c22cacf3 8216 {
5039610b 8217 tree narg0 = CALL_EXPR_ARG (arg0, 0);
db3927fb 8218 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
987b67bc 8219 build_real (type, dconsthalf));
db3927fb 8220 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
d86dc303
KG
8221 }
8222
8223 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8224 if (BUILTIN_CBRT_P (fcode))
c22cacf3 8225 {
5039610b 8226 tree arg = CALL_EXPR_ARG (arg0, 0);
d86dc303
KG
8227 if (tree_expr_nonnegative_p (arg))
8228 {
8229 const REAL_VALUE_TYPE dconstroot
9c02cf68 8230 = real_value_truncate (TYPE_MODE (type), dconst_third ());
db3927fb 8231 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
987b67bc 8232 build_real (type, dconstroot));
db3927fb 8233 return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
d86dc303
KG
8234 }
8235 }
c22cacf3 8236
776e7174 8237 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */
5039610b
SL
8238 if (fcode == BUILT_IN_POW
8239 || fcode == BUILT_IN_POWF
8240 || fcode == BUILT_IN_POWL)
c22cacf3 8241 {
5039610b 8242 tree arg00 = CALL_EXPR_ARG (arg0, 0);
776e7174
RG
8243 if (tree_expr_nonnegative_p (arg00))
8244 {
8245 tree arg01 = CALL_EXPR_ARG (arg0, 1);
8246 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8247 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8248 }
d86dc303 8249 }
667bbbbb 8250 }
d86dc303 8251
667bbbbb
EC
8252 return NULL_TREE;
8253}
8254
5039610b
SL
8255/* Fold a builtin function call to powi, powif, or powil with argument ARG.
8256 Return NULL_TREE if no simplification can be made. */
ba78d452 8257static tree
db3927fb 8258fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
5039610b 8259 tree arg0, tree arg1, tree type)
ba78d452 8260{
5039610b
SL
8261 if (!validate_arg (arg0, REAL_TYPE)
8262 || !validate_arg (arg1, INTEGER_TYPE))
ba78d452
RG
8263 return NULL_TREE;
8264
8265 /* Optimize pow(1.0,y) = 1.0. */
8266 if (real_onep (arg0))
db3927fb 8267 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
ba78d452
RG
8268
8269 if (host_integerp (arg1, 0))
8270 {
8271 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8272
8273 /* Evaluate powi at compile-time. */
8274 if (TREE_CODE (arg0) == REAL_CST
455f14dd 8275 && !TREE_OVERFLOW (arg0))
ba78d452
RG
8276 {
8277 REAL_VALUE_TYPE x;
8278 x = TREE_REAL_CST (arg0);
8279 real_powi (&x, TYPE_MODE (type), &x, c);
8280 return build_real (type, x);
8281 }
8282
8283 /* Optimize pow(x,0) = 1.0. */
8284 if (c == 0)
db3927fb 8285 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
ba78d452
RG
8286 arg0);
8287
8288 /* Optimize pow(x,1) = x. */
8289 if (c == 1)
8290 return arg0;
8291
8292 /* Optimize pow(x,-1) = 1.0/x. */
8293 if (c == -1)
db3927fb 8294 return fold_build2_loc (loc, RDIV_EXPR, type,
987b67bc 8295 build_real (type, dconst1), arg0);
ba78d452
RG
8296 }
8297
8298 return NULL_TREE;
8299}
8300
f7657db9 8301/* A subroutine of fold_builtin to fold the various exponent
5039610b 8302 functions. Return NULL_TREE if no simplification can be made.
b52dd66c 8303 FUNC is the corresponding MPFR exponent function. */
f7657db9
KG
8304
8305static tree
db3927fb 8306fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
b52dd66c 8307 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
f7657db9 8308{
5039610b 8309 if (validate_arg (arg, REAL_TYPE))
f7657db9 8310 {
f7657db9 8311 tree type = TREE_TYPE (TREE_TYPE (fndecl));
cf1491f0 8312 tree res;
b8698a0f 8313
b52dd66c 8314 /* Calculate the result when the argument is a constant. */
b53fed56 8315 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
b52dd66c 8316 return res;
f7657db9
KG
8317
8318 /* Optimize expN(logN(x)) = x. */
8319 if (flag_unsafe_math_optimizations)
c22cacf3 8320 {
f7657db9
KG
8321 const enum built_in_function fcode = builtin_mathfn_code (arg);
8322
b52dd66c 8323 if ((func == mpfr_exp
f7657db9
KG
8324 && (fcode == BUILT_IN_LOG
8325 || fcode == BUILT_IN_LOGF
8326 || fcode == BUILT_IN_LOGL))
b52dd66c 8327 || (func == mpfr_exp2
f7657db9
KG
8328 && (fcode == BUILT_IN_LOG2
8329 || fcode == BUILT_IN_LOG2F
8330 || fcode == BUILT_IN_LOG2L))
b52dd66c 8331 || (func == mpfr_exp10
f7657db9
KG
8332 && (fcode == BUILT_IN_LOG10
8333 || fcode == BUILT_IN_LOG10F
8334 || fcode == BUILT_IN_LOG10L)))
db3927fb 8335 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
f7657db9
KG
8336 }
8337 }
8338
5039610b 8339 return NULL_TREE;
f7657db9
KG
8340}
8341
599a964a
JJ
8342/* Return true if VAR is a VAR_DECL or a component thereof. */
8343
8344static bool
8345var_decl_component_p (tree var)
8346{
8347 tree inner = var;
8348 while (handled_component_p (inner))
8349 inner = TREE_OPERAND (inner, 0);
8350 return SSA_VAR_P (inner);
8351}
8352
bc038ad5 8353/* Fold function call to builtin memset. Return
5bb650ec
RS
8354 NULL_TREE if no simplification can be made. */
8355
8356static tree
db3927fb
AH
8357fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8358 tree type, bool ignore)
5bb650ec 8359{
255d3827 8360 tree var, ret, etype;
bc038ad5 8361 unsigned HOST_WIDE_INT length, cval;
5bb650ec 8362
5039610b
SL
8363 if (! validate_arg (dest, POINTER_TYPE)
8364 || ! validate_arg (c, INTEGER_TYPE)
8365 || ! validate_arg (len, INTEGER_TYPE))
8366 return NULL_TREE;
5bb650ec 8367
bc038ad5 8368 if (! host_integerp (len, 1))
5039610b 8369 return NULL_TREE;
bc038ad5 8370
5bb650ec
RS
8371 /* If the LEN parameter is zero, return DEST. */
8372 if (integer_zerop (len))
db3927fb 8373 return omit_one_operand_loc (loc, type, dest, c);
5bb650ec 8374
bc038ad5 8375 if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
5039610b 8376 return NULL_TREE;
5bb650ec 8377
bc038ad5
JJ
8378 var = dest;
8379 STRIP_NOPS (var);
8380 if (TREE_CODE (var) != ADDR_EXPR)
5039610b 8381 return NULL_TREE;
bc038ad5
JJ
8382
8383 var = TREE_OPERAND (var, 0);
8384 if (TREE_THIS_VOLATILE (var))
5039610b 8385 return NULL_TREE;
bc038ad5 8386
255d3827
RG
8387 etype = TREE_TYPE (var);
8388 if (TREE_CODE (etype) == ARRAY_TYPE)
8389 etype = TREE_TYPE (etype);
8390
8391 if (!INTEGRAL_TYPE_P (etype)
8392 && !POINTER_TYPE_P (etype))
5039610b 8393 return NULL_TREE;
bc038ad5 8394
599a964a 8395 if (! var_decl_component_p (var))
5039610b 8396 return NULL_TREE;
599a964a 8397
bc038ad5 8398 length = tree_low_cst (len, 1);
255d3827 8399 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
bc038ad5
JJ
8400 || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8401 < (int) length)
5039610b 8402 return NULL_TREE;
bc038ad5
JJ
8403
8404 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
5039610b 8405 return NULL_TREE;
bc038ad5
JJ
8406
8407 if (integer_zerop (c))
8408 cval = 0;
8409 else
8410 {
8411 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
5039610b 8412 return NULL_TREE;
bc038ad5
JJ
8413
8414 cval = tree_low_cst (c, 1);
8415 cval &= 0xff;
8416 cval |= cval << 8;
8417 cval |= cval << 16;
8418 cval |= (cval << 31) << 1;
8419 }
8420
255d3827 8421 ret = build_int_cst_type (etype, cval);
db3927fb
AH
8422 var = build_fold_indirect_ref_loc (loc,
8423 fold_convert_loc (loc,
8424 build_pointer_type (etype),
8425 dest));
255d3827 8426 ret = build2 (MODIFY_EXPR, etype, var, ret);
bc038ad5
JJ
8427 if (ignore)
8428 return ret;
8429
db3927fb 8430 return omit_one_operand_loc (loc, type, dest, ret);
5bb650ec
RS
8431}
8432
bc038ad5 8433/* Fold function call to builtin memset. Return
5bb650ec
RS
8434 NULL_TREE if no simplification can be made. */
8435
8436static tree
db3927fb 8437fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
5bb650ec 8438{
5039610b
SL
8439 if (! validate_arg (dest, POINTER_TYPE)
8440 || ! validate_arg (size, INTEGER_TYPE))
8441 return NULL_TREE;
5bb650ec 8442
bc038ad5 8443 if (!ignore)
5039610b 8444 return NULL_TREE;
c22cacf3 8445
bc038ad5
JJ
8446 /* New argument list transforming bzero(ptr x, int y) to
8447 memset(ptr x, int 0, size_t y). This is done this way
8448 so that if it isn't expanded inline, we fallback to
8449 calling bzero instead of memset. */
8450
db3927fb
AH
8451 return fold_builtin_memset (loc, dest, integer_zero_node,
8452 fold_convert_loc (loc, sizetype, size),
5039610b 8453 void_type_node, ignore);
5bb650ec
RS
8454}
8455
bc038ad5
JJ
8456/* Fold function call to builtin mem{{,p}cpy,move}. Return
8457 NULL_TREE if no simplification can be made.
8458 If ENDP is 0, return DEST (like memcpy).
8459 If ENDP is 1, return DEST+LEN (like mempcpy).
8460 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8461 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8462 (memmove). */
5bb650ec
RS
8463
8464static tree
db3927fb
AH
8465fold_builtin_memory_op (location_t loc, tree dest, tree src,
8466 tree len, tree type, bool ignore, int endp)
5bb650ec 8467{
5039610b 8468 tree destvar, srcvar, expr;
5bb650ec 8469
5039610b
SL
8470 if (! validate_arg (dest, POINTER_TYPE)
8471 || ! validate_arg (src, POINTER_TYPE)
8472 || ! validate_arg (len, INTEGER_TYPE))
8473 return NULL_TREE;
5bb650ec
RS
8474
8475 /* If the LEN parameter is zero, return DEST. */
8476 if (integer_zerop (len))
db3927fb 8477 return omit_one_operand_loc (loc, type, dest, src);
5bb650ec 8478
bc038ad5
JJ
8479 /* If SRC and DEST are the same (and not volatile), return
8480 DEST{,+LEN,+LEN-1}. */
5bb650ec 8481 if (operand_equal_p (src, dest, 0))
bc038ad5
JJ
8482 expr = len;
8483 else
8484 {
a1da787d 8485 tree srctype, desttype;
81f5094d
JJ
8486 int src_align, dest_align;
8487
eaf19122
JH
8488 if (endp == 3)
8489 {
81f5094d
JJ
8490 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8491 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
a1da787d 8492
b8698a0f 8493 /* Both DEST and SRC must be pointer types.
eaf19122
JH
8494 ??? This is what old code did. Is the testing for pointer types
8495 really mandatory?
8496
8497 If either SRC is readonly or length is 1, we can use memcpy. */
64d7685c
JJ
8498 if (!dest_align || !src_align)
8499 return NULL_TREE;
8500 if (readonly_data_expr (src)
8501 || (host_integerp (len, 1)
8502 && (MIN (src_align, dest_align) / BITS_PER_UNIT
8503 >= tree_low_cst (len, 1))))
eaf19122
JH
8504 {
8505 tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8506 if (!fn)
5039610b 8507 return NULL_TREE;
db3927fb 8508 return build_call_expr_loc (loc, fn, 3, dest, src, len);
eaf19122 8509 }
64d7685c
JJ
8510
8511 /* If *src and *dest can't overlap, optimize into memcpy as well. */
63838157
RG
8512 srcvar = build_fold_indirect_ref_loc (loc, src);
8513 destvar = build_fold_indirect_ref_loc (loc, dest);
8514 if (srcvar
8515 && !TREE_THIS_VOLATILE (srcvar)
8516 && destvar
8517 && !TREE_THIS_VOLATILE (destvar))
64d7685c 8518 {
63838157
RG
8519 tree src_base, dest_base, fn;
8520 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8521 HOST_WIDE_INT size = -1;
8522 HOST_WIDE_INT maxsize = -1;
8523
8524 src_base = srcvar;
8525 if (handled_component_p (src_base))
8526 src_base = get_ref_base_and_extent (src_base, &src_offset,
8527 &size, &maxsize);
8528 dest_base = destvar;
8529 if (handled_component_p (dest_base))
8530 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
8531 &size, &maxsize);
8532 if (host_integerp (len, 1))
8533 {
8534 maxsize = tree_low_cst (len, 1);
8535 if (maxsize
8536 > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
8537 maxsize = -1;
8538 else
8539 maxsize *= BITS_PER_UNIT;
8540 }
8541 else
8542 maxsize = -1;
8543 if (SSA_VAR_P (src_base)
8544 && SSA_VAR_P (dest_base))
8545 {
8546 if (operand_equal_p (src_base, dest_base, 0)
8547 && ranges_overlap_p (src_offset, maxsize,
8548 dest_offset, maxsize))
8549 return NULL_TREE;
8550 }
8551 else if (TREE_CODE (src_base) == INDIRECT_REF
8552 && TREE_CODE (dest_base) == INDIRECT_REF)
8553 {
8554 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8555 TREE_OPERAND (dest_base, 0), 0)
8556 || ranges_overlap_p (src_offset, maxsize,
8557 dest_offset, maxsize))
8558 return NULL_TREE;
8559 }
8560 else
8561 return NULL_TREE;
8562
8563 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
64d7685c
JJ
8564 if (!fn)
8565 return NULL_TREE;
db3927fb 8566 return build_call_expr_loc (loc, fn, 3, dest, src, len);
64d7685c 8567 }
5039610b 8568 return NULL_TREE;
eaf19122 8569 }
bc038ad5 8570
a1da787d 8571 if (!host_integerp (len, 0))
5039610b 8572 return NULL_TREE;
a1da787d
JH
8573 /* FIXME:
8574 This logic lose for arguments like (type *)malloc (sizeof (type)),
8575 since we strip the casts of up to VOID return value from malloc.
8576 Perhaps we ought to inherit type from non-VOID argument here? */
8577 STRIP_NOPS (src);
8578 STRIP_NOPS (dest);
255d3827
RG
8579 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
8580 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8581 {
8582 tree tem = TREE_OPERAND (src, 0);
8583 STRIP_NOPS (tem);
8584 if (tem != TREE_OPERAND (src, 0))
8585 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8586 }
8587 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8588 {
8589 tree tem = TREE_OPERAND (dest, 0);
8590 STRIP_NOPS (tem);
8591 if (tem != TREE_OPERAND (dest, 0))
8592 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8593 }
a1da787d 8594 srctype = TREE_TYPE (TREE_TYPE (src));
255d3827 8595 if (srctype
ea5cd5f1
RG
8596 && TREE_CODE (srctype) == ARRAY_TYPE
8597 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
255d3827
RG
8598 {
8599 srctype = TREE_TYPE (srctype);
8600 STRIP_NOPS (src);
8601 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8602 }
a1da787d 8603 desttype = TREE_TYPE (TREE_TYPE (dest));
255d3827 8604 if (desttype
ea5cd5f1
RG
8605 && TREE_CODE (desttype) == ARRAY_TYPE
8606 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
255d3827
RG
8607 {
8608 desttype = TREE_TYPE (desttype);
8609 STRIP_NOPS (dest);
8610 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8611 }
a1da787d
JH
8612 if (!srctype || !desttype
8613 || !TYPE_SIZE_UNIT (srctype)
8614 || !TYPE_SIZE_UNIT (desttype)
8615 || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
493aa551
JJ
8616 || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8617 || TYPE_VOLATILE (srctype)
8618 || TYPE_VOLATILE (desttype))
5039610b 8619 return NULL_TREE;
bc038ad5 8620
81f5094d
JJ
8621 src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8622 dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8623 if (dest_align < (int) TYPE_ALIGN (desttype)
8624 || src_align < (int) TYPE_ALIGN (srctype))
5039610b 8625 return NULL_TREE;
599a964a 8626
a1da787d
JH
8627 if (!ignore)
8628 dest = builtin_save_expr (dest);
bc038ad5 8629
81f5094d
JJ
8630 srcvar = NULL_TREE;
8631 if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8632 {
db3927fb 8633 srcvar = build_fold_indirect_ref_loc (loc, src);
81f5094d 8634 if (TREE_THIS_VOLATILE (srcvar))
493aa551 8635 return NULL_TREE;
71c00b5c 8636 else if (!tree_int_cst_equal (tree_expr_size (srcvar), len))
81f5094d
JJ
8637 srcvar = NULL_TREE;
8638 /* With memcpy, it is possible to bypass aliasing rules, so without
8639 this check i.e. execute/20060930-2.c would be misoptimized,
8640 because it use conflicting alias set to hold argument for the
8641 memcpy call. This check is probably unnecessary with
8642 -fno-strict-aliasing. Similarly for destvar. See also
8643 PR29286. */
8644 else if (!var_decl_component_p (srcvar))
8645 srcvar = NULL_TREE;
8646 }
bc038ad5 8647
81f5094d
JJ
8648 destvar = NULL_TREE;
8649 if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8650 {
db3927fb 8651 destvar = build_fold_indirect_ref_loc (loc, dest);
81f5094d 8652 if (TREE_THIS_VOLATILE (destvar))
493aa551 8653 return NULL_TREE;
71c00b5c 8654 else if (!tree_int_cst_equal (tree_expr_size (destvar), len))
81f5094d
JJ
8655 destvar = NULL_TREE;
8656 else if (!var_decl_component_p (destvar))
8657 destvar = NULL_TREE;
8658 }
8659
8660 if (srcvar == NULL_TREE && destvar == NULL_TREE)
5039610b 8661 return NULL_TREE;
bc038ad5 8662
81f5094d
JJ
8663 if (srcvar == NULL_TREE)
8664 {
8665 tree srcptype;
8666 if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
8667 return NULL_TREE;
8668
493aa551 8669 srctype = build_qualified_type (desttype, 0);
81f5094d
JJ
8670 if (src_align < (int) TYPE_ALIGN (srctype))
8671 {
8672 if (AGGREGATE_TYPE_P (srctype)
8673 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
8674 return NULL_TREE;
8675
8676 srctype = build_variant_type_copy (srctype);
8677 TYPE_ALIGN (srctype) = src_align;
8678 TYPE_USER_ALIGN (srctype) = 1;
8679 TYPE_PACKED (srctype) = 1;
8680 }
8681 srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
db3927fb
AH
8682 src = fold_convert_loc (loc, srcptype, src);
8683 srcvar = build_fold_indirect_ref_loc (loc, src);
81f5094d
JJ
8684 }
8685 else if (destvar == NULL_TREE)
8686 {
8687 tree destptype;
8688 if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
8689 return NULL_TREE;
8690
493aa551 8691 desttype = build_qualified_type (srctype, 0);
81f5094d
JJ
8692 if (dest_align < (int) TYPE_ALIGN (desttype))
8693 {
8694 if (AGGREGATE_TYPE_P (desttype)
8695 || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
8696 return NULL_TREE;
8697
8698 desttype = build_variant_type_copy (desttype);
8699 TYPE_ALIGN (desttype) = dest_align;
8700 TYPE_USER_ALIGN (desttype) = 1;
8701 TYPE_PACKED (desttype) = 1;
8702 }
8703 destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
db3927fb
AH
8704 dest = fold_convert_loc (loc, destptype, dest);
8705 destvar = build_fold_indirect_ref_loc (loc, dest);
81f5094d
JJ
8706 }
8707
a1da787d 8708 if (srctype == desttype
5cd4ec7f 8709 || (gimple_in_ssa_p (cfun)
36618b93 8710 && useless_type_conversion_p (desttype, srctype)))
a1da787d
JH
8711 expr = srcvar;
8712 else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
bc038ad5
JJ
8713 || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8714 && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8715 || POINTER_TYPE_P (TREE_TYPE (destvar))))
db3927fb 8716 expr = fold_convert_loc (loc, TREE_TYPE (destvar), srcvar);
bc038ad5 8717 else
db3927fb
AH
8718 expr = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
8719 TREE_TYPE (destvar), srcvar);
939409af 8720 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
bc038ad5
JJ
8721 }
8722
8723 if (ignore)
8724 return expr;
8725
8726 if (endp == 0 || endp == 3)
db3927fb 8727 return omit_one_operand_loc (loc, type, dest, expr);
bc038ad5
JJ
8728
8729 if (expr == len)
5039610b 8730 expr = NULL_TREE;
bc038ad5
JJ
8731
8732 if (endp == 2)
db3927fb 8733 len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
bc038ad5
JJ
8734 ssize_int (1));
8735
db3927fb
AH
8736 len = fold_convert_loc (loc, sizetype, len);
8737 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8738 dest = fold_convert_loc (loc, type, dest);
bc038ad5 8739 if (expr)
db3927fb 8740 dest = omit_one_operand_loc (loc, type, dest, expr);
bc038ad5
JJ
8741 return dest;
8742}
8743
5039610b
SL
8744/* Fold function call to builtin strcpy with arguments DEST and SRC.
8745 If LEN is not NULL, it represents the length of the string to be
8746 copied. Return NULL_TREE if no simplification can be made. */
5bb650ec 8747
a32e70c3 8748tree
db3927fb 8749fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
5bb650ec 8750{
5039610b 8751 tree fn;
5bb650ec 8752
5039610b
SL
8753 if (!validate_arg (dest, POINTER_TYPE)
8754 || !validate_arg (src, POINTER_TYPE))
8755 return NULL_TREE;
5bb650ec
RS
8756
8757 /* If SRC and DEST are the same (and not volatile), return DEST. */
8758 if (operand_equal_p (src, dest, 0))
db3927fb 8759 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
5bb650ec 8760
efd8f750 8761 if (optimize_function_for_size_p (cfun))
5039610b 8762 return NULL_TREE;
a32e70c3
RS
8763
8764 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8765 if (!fn)
5039610b 8766 return NULL_TREE;
a32e70c3
RS
8767
8768 if (!len)
8769 {
8770 len = c_strlen (src, 1);
8771 if (! len || TREE_SIDE_EFFECTS (len))
5039610b 8772 return NULL_TREE;
a32e70c3
RS
8773 }
8774
db3927fb
AH
8775 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8776 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8777 build_call_expr_loc (loc, fn, 3, dest, src, len));
5bb650ec
RS
8778}
8779
44e10129
MM
8780/* Fold function call to builtin stpcpy with arguments DEST and SRC.
8781 Return NULL_TREE if no simplification can be made. */
8782
8783static tree
8784fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
8785{
8786 tree fn, len, lenp1, call, type;
8787
8788 if (!validate_arg (dest, POINTER_TYPE)
8789 || !validate_arg (src, POINTER_TYPE))
8790 return NULL_TREE;
8791
8792 len = c_strlen (src, 1);
8793 if (!len
8794 || TREE_CODE (len) != INTEGER_CST)
8795 return NULL_TREE;
8796
8797 if (optimize_function_for_size_p (cfun)
8798 /* If length is zero it's small enough. */
8799 && !integer_zerop (len))
8800 return NULL_TREE;
8801
8802 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8803 if (!fn)
8804 return NULL_TREE;
8805
8806 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8807 /* We use dest twice in building our expression. Save it from
8808 multiple expansions. */
8809 dest = builtin_save_expr (dest);
8810 call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
8811
8812 type = TREE_TYPE (TREE_TYPE (fndecl));
8813 len = fold_convert_loc (loc, sizetype, len);
8814 dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8815 dest = fold_convert_loc (loc, type, dest);
8816 dest = omit_one_operand_loc (loc, type, dest, call);
8817 return dest;
8818}
8819
5039610b
SL
8820/* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8821 If SLEN is not NULL, it represents the length of the source string.
8822 Return NULL_TREE if no simplification can be made. */
5bb650ec 8823
a32e70c3 8824tree
db3927fb
AH
8825fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
8826 tree src, tree len, tree slen)
5bb650ec 8827{
5039610b 8828 tree fn;
5bb650ec 8829
5039610b
SL
8830 if (!validate_arg (dest, POINTER_TYPE)
8831 || !validate_arg (src, POINTER_TYPE)
8832 || !validate_arg (len, INTEGER_TYPE))
8833 return NULL_TREE;
5bb650ec
RS
8834
8835 /* If the LEN parameter is zero, return DEST. */
8836 if (integer_zerop (len))
db3927fb 8837 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
5bb650ec 8838
691e2db8
AO
8839 /* We can't compare slen with len as constants below if len is not a
8840 constant. */
8841 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
5039610b 8842 return NULL_TREE;
691e2db8 8843
a32e70c3
RS
8844 if (!slen)
8845 slen = c_strlen (src, 1);
8846
8847 /* Now, we must be passed a constant src ptr parameter. */
8848 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
5039610b 8849 return NULL_TREE;
a32e70c3 8850
db3927fb 8851 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
a32e70c3
RS
8852
8853 /* We do not support simplification of this case, though we do
8854 support it when expanding trees into RTL. */
8855 /* FIXME: generate a call to __builtin_memset. */
8856 if (tree_int_cst_lt (slen, len))
5039610b 8857 return NULL_TREE;
a32e70c3
RS
8858
8859 /* OK transform into builtin memcpy. */
8860 fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8861 if (!fn)
5039610b 8862 return NULL_TREE;
db3927fb
AH
8863 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8864 build_call_expr_loc (loc, fn, 3, dest, src, len));
5bb650ec
RS
8865}
8866
2a5fce6d
PC
8867/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
8868 arguments to the call, and TYPE is its return type.
8869 Return NULL_TREE if no simplification can be made. */
8870
8871static tree
db3927fb 8872fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
2a5fce6d
PC
8873{
8874 if (!validate_arg (arg1, POINTER_TYPE)
8875 || !validate_arg (arg2, INTEGER_TYPE)
8876 || !validate_arg (len, INTEGER_TYPE))
8877 return NULL_TREE;
8878 else
8879 {
8880 const char *p1;
8881
8882 if (TREE_CODE (arg2) != INTEGER_CST
8883 || !host_integerp (len, 1))
8884 return NULL_TREE;
8885
8886 p1 = c_getstr (arg1);
8887 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8888 {
8889 char c;
8890 const char *r;
8891 tree tem;
8892
8893 if (target_char_cast (arg2, &c))
8894 return NULL_TREE;
8895
f883e0a7 8896 r = (char *) memchr (p1, c, tree_low_cst (len, 1));
2a5fce6d
PC
8897
8898 if (r == NULL)
8899 return build_int_cst (TREE_TYPE (arg1), 0);
8900
db3927fb 8901 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
5be014d5 8902 size_int (r - p1));
db3927fb 8903 return fold_convert_loc (loc, type, tem);
2a5fce6d
PC
8904 }
8905 return NULL_TREE;
8906 }
8907}
8908
5039610b
SL
8909/* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8910 Return NULL_TREE if no simplification can be made. */
5bb650ec
RS
8911
8912static tree
db3927fb 8913fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
5bb650ec 8914{
01847e9d 8915 const char *p1, *p2;
5bb650ec 8916
5039610b
SL
8917 if (!validate_arg (arg1, POINTER_TYPE)
8918 || !validate_arg (arg2, POINTER_TYPE)
8919 || !validate_arg (len, INTEGER_TYPE))
8920 return NULL_TREE;
5bb650ec
RS
8921
8922 /* If the LEN parameter is zero, return zero. */
8923 if (integer_zerop (len))
db3927fb 8924 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
01847e9d 8925 arg1, arg2);
5bb650ec
RS
8926
8927 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8928 if (operand_equal_p (arg1, arg2, 0))
db3927fb 8929 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
01847e9d
RS
8930
8931 p1 = c_getstr (arg1);
8932 p2 = c_getstr (arg2);
8933
8934 /* If all arguments are constant, and the value of len is not greater
8935 than the lengths of arg1 and arg2, evaluate at compile-time. */
8936 if (host_integerp (len, 1) && p1 && p2
8937 && compare_tree_int (len, strlen (p1) + 1) <= 0
8938 && compare_tree_int (len, strlen (p2) + 1) <= 0)
8939 {
8940 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8941
8942 if (r > 0)
8943 return integer_one_node;
8944 else if (r < 0)
8945 return integer_minus_one_node;
8946 else
8947 return integer_zero_node;
8948 }
8949
8950 /* If len parameter is one, return an expression corresponding to
8951 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
8952 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8953 {
8954 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
8955 tree cst_uchar_ptr_node
8956 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8957
db3927fb
AH
8958 tree ind1
8959 = fold_convert_loc (loc, integer_type_node,
8960 build1 (INDIRECT_REF, cst_uchar_node,
8961 fold_convert_loc (loc,
8962 cst_uchar_ptr_node,
01847e9d 8963 arg1)));
db3927fb
AH
8964 tree ind2
8965 = fold_convert_loc (loc, integer_type_node,
8966 build1 (INDIRECT_REF, cst_uchar_node,
8967 fold_convert_loc (loc,
8968 cst_uchar_ptr_node,
01847e9d 8969 arg2)));
db3927fb 8970 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
01847e9d 8971 }
5bb650ec 8972
5039610b 8973 return NULL_TREE;
5bb650ec
RS
8974}
8975
5039610b
SL
8976/* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
8977 Return NULL_TREE if no simplification can be made. */
5bb650ec
RS
8978
8979static tree
db3927fb 8980fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
5bb650ec 8981{
5bb650ec
RS
8982 const char *p1, *p2;
8983
5039610b
SL
8984 if (!validate_arg (arg1, POINTER_TYPE)
8985 || !validate_arg (arg2, POINTER_TYPE))
8986 return NULL_TREE;
5bb650ec
RS
8987
8988 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
8989 if (operand_equal_p (arg1, arg2, 0))
01847e9d 8990 return integer_zero_node;
5bb650ec
RS
8991
8992 p1 = c_getstr (arg1);
8993 p2 = c_getstr (arg2);
8994
8995 if (p1 && p2)
8996 {
5bb650ec
RS
8997 const int i = strcmp (p1, p2);
8998 if (i < 0)
01847e9d 8999 return integer_minus_one_node;
5bb650ec 9000 else if (i > 0)
01847e9d 9001 return integer_one_node;
5bb650ec 9002 else
01847e9d
RS
9003 return integer_zero_node;
9004 }
9005
9006 /* If the second arg is "", return *(const unsigned char*)arg1. */
9007 if (p2 && *p2 == '\0')
9008 {
9009 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
9010 tree cst_uchar_ptr_node
9011 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9012
db3927fb
AH
9013 return fold_convert_loc (loc, integer_type_node,
9014 build1 (INDIRECT_REF, cst_uchar_node,
9015 fold_convert_loc (loc,
9016 cst_uchar_ptr_node,
9017 arg1)));
01847e9d
RS
9018 }
9019
9020 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9021 if (p1 && *p1 == '\0')
9022 {
9023 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
9024 tree cst_uchar_ptr_node
9025 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9026
db3927fb
AH
9027 tree temp
9028 = fold_convert_loc (loc, integer_type_node,
9029 build1 (INDIRECT_REF, cst_uchar_node,
9030 fold_convert_loc (loc,
9031 cst_uchar_ptr_node,
01847e9d 9032 arg2)));
db3927fb 9033 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
5bb650ec
RS
9034 }
9035
5039610b 9036 return NULL_TREE;
5bb650ec
RS
9037}
9038
5039610b
SL
9039/* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9040 Return NULL_TREE if no simplification can be made. */
5bb650ec
RS
9041
9042static tree
db3927fb 9043fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
5bb650ec 9044{
5bb650ec
RS
9045 const char *p1, *p2;
9046
5039610b
SL
9047 if (!validate_arg (arg1, POINTER_TYPE)
9048 || !validate_arg (arg2, POINTER_TYPE)
9049 || !validate_arg (len, INTEGER_TYPE))
9050 return NULL_TREE;
5bb650ec
RS
9051
9052 /* If the LEN parameter is zero, return zero. */
9053 if (integer_zerop (len))
db3927fb 9054 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
01847e9d 9055 arg1, arg2);
5bb650ec
RS
9056
9057 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9058 if (operand_equal_p (arg1, arg2, 0))
db3927fb 9059 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
5bb650ec
RS
9060
9061 p1 = c_getstr (arg1);
9062 p2 = c_getstr (arg2);
9063
9064 if (host_integerp (len, 1) && p1 && p2)
9065 {
5bb650ec 9066 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
01847e9d
RS
9067 if (i > 0)
9068 return integer_one_node;
9069 else if (i < 0)
9070 return integer_minus_one_node;
5bb650ec 9071 else
01847e9d
RS
9072 return integer_zero_node;
9073 }
9074
9075 /* If the second arg is "", and the length is greater than zero,
9076 return *(const unsigned char*)arg1. */
9077 if (p2 && *p2 == '\0'
9078 && TREE_CODE (len) == INTEGER_CST
9079 && tree_int_cst_sgn (len) == 1)
9080 {
9081 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
9082 tree cst_uchar_ptr_node
9083 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9084
db3927fb
AH
9085 return fold_convert_loc (loc, integer_type_node,
9086 build1 (INDIRECT_REF, cst_uchar_node,
9087 fold_convert_loc (loc,
9088 cst_uchar_ptr_node,
9089 arg1)));
01847e9d
RS
9090 }
9091
9092 /* If the first arg is "", and the length is greater than zero,
9093 return -*(const unsigned char*)arg2. */
9094 if (p1 && *p1 == '\0'
9095 && TREE_CODE (len) == INTEGER_CST
9096 && tree_int_cst_sgn (len) == 1)
9097 {
9098 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
9099 tree cst_uchar_ptr_node
9100 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9101
db3927fb
AH
9102 tree temp = fold_convert_loc (loc, integer_type_node,
9103 build1 (INDIRECT_REF, cst_uchar_node,
9104 fold_convert_loc (loc,
9105 cst_uchar_ptr_node,
9106 arg2)));
9107 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
01847e9d
RS
9108 }
9109
9110 /* If len parameter is one, return an expression corresponding to
9111 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9112 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9113 {
9114 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
baab454a
UW
9115 tree cst_uchar_ptr_node
9116 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9117
db3927fb
AH
9118 tree ind1 = fold_convert_loc (loc, integer_type_node,
9119 build1 (INDIRECT_REF, cst_uchar_node,
9120 fold_convert_loc (loc,
9121 cst_uchar_ptr_node,
9122 arg1)));
9123 tree ind2 = fold_convert_loc (loc, integer_type_node,
9124 build1 (INDIRECT_REF, cst_uchar_node,
9125 fold_convert_loc (loc,
9126 cst_uchar_ptr_node,
9127 arg2)));
9128 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
5bb650ec
RS
9129 }
9130
5039610b 9131 return NULL_TREE;
5bb650ec
RS
9132}
9133
5039610b
SL
9134/* Fold function call to builtin signbit, signbitf or signbitl with argument
9135 ARG. Return NULL_TREE if no simplification can be made. */
ef79730c
RS
9136
9137static tree
db3927fb 9138fold_builtin_signbit (location_t loc, tree arg, tree type)
ef79730c 9139{
5039610b 9140 tree temp;
ef79730c 9141
5039610b 9142 if (!validate_arg (arg, REAL_TYPE))
ef79730c
RS
9143 return NULL_TREE;
9144
ef79730c
RS
9145 /* If ARG is a compile-time constant, determine the result. */
9146 if (TREE_CODE (arg) == REAL_CST
455f14dd 9147 && !TREE_OVERFLOW (arg))
ef79730c
RS
9148 {
9149 REAL_VALUE_TYPE c;
9150
9151 c = TREE_REAL_CST (arg);
9152 temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
db3927fb 9153 return fold_convert_loc (loc, type, temp);
ef79730c
RS
9154 }
9155
9156 /* If ARG is non-negative, the result is always zero. */
9157 if (tree_expr_nonnegative_p (arg))
db3927fb 9158 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
ef79730c
RS
9159
9160 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9161 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
db3927fb 9162 return fold_build2_loc (loc, LT_EXPR, type, arg,
987b67bc 9163 build_real (TREE_TYPE (arg), dconst0));
ef79730c
RS
9164
9165 return NULL_TREE;
9166}
9167
5039610b
SL
9168/* Fold function call to builtin copysign, copysignf or copysignl with
9169 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9170 be made. */
67057c53
RS
9171
9172static tree
db3927fb
AH
9173fold_builtin_copysign (location_t loc, tree fndecl,
9174 tree arg1, tree arg2, tree type)
67057c53 9175{
5039610b 9176 tree tem;
67057c53 9177
5039610b
SL
9178 if (!validate_arg (arg1, REAL_TYPE)
9179 || !validate_arg (arg2, REAL_TYPE))
67057c53
RS
9180 return NULL_TREE;
9181
67057c53
RS
9182 /* copysign(X,X) is X. */
9183 if (operand_equal_p (arg1, arg2, 0))
db3927fb 9184 return fold_convert_loc (loc, type, arg1);
67057c53
RS
9185
9186 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9187 if (TREE_CODE (arg1) == REAL_CST
9188 && TREE_CODE (arg2) == REAL_CST
455f14dd
RS
9189 && !TREE_OVERFLOW (arg1)
9190 && !TREE_OVERFLOW (arg2))
67057c53
RS
9191 {
9192 REAL_VALUE_TYPE c1, c2;
9193
9194 c1 = TREE_REAL_CST (arg1);
9195 c2 = TREE_REAL_CST (arg2);
8acb1b3d 9196 /* c1.sign := c2.sign. */
67057c53
RS
9197 real_copysign (&c1, &c2);
9198 return build_real (type, c1);
67057c53
RS
9199 }
9200
9201 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9202 Remember to evaluate Y for side-effects. */
9203 if (tree_expr_nonnegative_p (arg2))
db3927fb
AH
9204 return omit_one_operand_loc (loc, type,
9205 fold_build1_loc (loc, ABS_EXPR, type, arg1),
67057c53
RS
9206 arg2);
9207
e3bb43c0
RS
9208 /* Strip sign changing operations for the first argument. */
9209 tem = fold_strip_sign_ops (arg1);
9210 if (tem)
db3927fb 9211 return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
e3bb43c0 9212
67057c53
RS
9213 return NULL_TREE;
9214}
9215
5039610b 9216/* Fold a call to builtin isascii with argument ARG. */
df0785d6
KG
9217
9218static tree
db3927fb 9219fold_builtin_isascii (location_t loc, tree arg)
df0785d6 9220{
5039610b
SL
9221 if (!validate_arg (arg, INTEGER_TYPE))
9222 return NULL_TREE;
df0785d6
KG
9223 else
9224 {
9225 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
6728ee79
MM
9226 arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9227 build_int_cst (NULL_TREE,
9228 ~ (unsigned HOST_WIDE_INT) 0x7f));
db3927fb 9229 return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
5cdc4a26 9230 arg, integer_zero_node);
df0785d6
KG
9231 }
9232}
9233
5039610b 9234/* Fold a call to builtin toascii with argument ARG. */
df0785d6
KG
9235
9236static tree
db3927fb 9237fold_builtin_toascii (location_t loc, tree arg)
df0785d6 9238{
5039610b
SL
9239 if (!validate_arg (arg, INTEGER_TYPE))
9240 return NULL_TREE;
b8698a0f 9241
5039610b 9242 /* Transform toascii(c) -> (c & 0x7f). */
db3927fb 9243 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
5039610b 9244 build_int_cst (NULL_TREE, 0x7f));
df0785d6
KG
9245}
9246
5039610b 9247/* Fold a call to builtin isdigit with argument ARG. */
61218d19
KG
9248
9249static tree
db3927fb 9250fold_builtin_isdigit (location_t loc, tree arg)
61218d19 9251{
5039610b
SL
9252 if (!validate_arg (arg, INTEGER_TYPE))
9253 return NULL_TREE;
61218d19
KG
9254 else
9255 {
9256 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
c5ff069d
ZW
9257 /* According to the C standard, isdigit is unaffected by locale.
9258 However, it definitely is affected by the target character set. */
c5ff069d
ZW
9259 unsigned HOST_WIDE_INT target_digit0
9260 = lang_hooks.to_target_charset ('0');
9261
9262 if (target_digit0 == 0)
9263 return NULL_TREE;
9264
db3927fb 9265 arg = fold_convert_loc (loc, unsigned_type_node, arg);
6728ee79
MM
9266 arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9267 build_int_cst (unsigned_type_node, target_digit0));
db3927fb 9268 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
5cdc4a26 9269 build_int_cst (unsigned_type_node, 9));
61218d19
KG
9270 }
9271}
ef79730c 9272
5039610b 9273/* Fold a call to fabs, fabsf or fabsl with argument ARG. */
9655d83b
RS
9274
9275static tree
db3927fb 9276fold_builtin_fabs (location_t loc, tree arg, tree type)
9655d83b 9277{
5039610b
SL
9278 if (!validate_arg (arg, REAL_TYPE))
9279 return NULL_TREE;
9655d83b 9280
db3927fb 9281 arg = fold_convert_loc (loc, type, arg);
9655d83b
RS
9282 if (TREE_CODE (arg) == REAL_CST)
9283 return fold_abs_const (arg, type);
db3927fb 9284 return fold_build1_loc (loc, ABS_EXPR, type, arg);
9655d83b
RS
9285}
9286
5039610b 9287/* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
9655d83b
RS
9288
9289static tree
db3927fb 9290fold_builtin_abs (location_t loc, tree arg, tree type)
9655d83b 9291{
5039610b
SL
9292 if (!validate_arg (arg, INTEGER_TYPE))
9293 return NULL_TREE;
9655d83b 9294
db3927fb 9295 arg = fold_convert_loc (loc, type, arg);
9655d83b
RS
9296 if (TREE_CODE (arg) == INTEGER_CST)
9297 return fold_abs_const (arg, type);
db3927fb 9298 return fold_build1_loc (loc, ABS_EXPR, type, arg);
9655d83b
RS
9299}
9300
b64d949c
KG
9301/* Fold a call to builtin fmin or fmax. */
9302
9303static tree
db3927fb
AH
9304fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9305 tree type, bool max)
b64d949c 9306{
5039610b 9307 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
b64d949c 9308 {
b64d949c
KG
9309 /* Calculate the result when the argument is a constant. */
9310 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9311
9312 if (res)
9313 return res;
9314
a8e3bad4
KG
9315 /* If either argument is NaN, return the other one. Avoid the
9316 transformation if we get (and honor) a signalling NaN. Using
9317 omit_one_operand() ensures we create a non-lvalue. */
9318 if (TREE_CODE (arg0) == REAL_CST
9319 && real_isnan (&TREE_REAL_CST (arg0))
9320 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9321 || ! TREE_REAL_CST (arg0).signalling))
db3927fb 9322 return omit_one_operand_loc (loc, type, arg1, arg0);
a8e3bad4
KG
9323 if (TREE_CODE (arg1) == REAL_CST
9324 && real_isnan (&TREE_REAL_CST (arg1))
9325 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9326 || ! TREE_REAL_CST (arg1).signalling))
db3927fb 9327 return omit_one_operand_loc (loc, type, arg0, arg1);
a8e3bad4 9328
b64d949c
KG
9329 /* Transform fmin/fmax(x,x) -> x. */
9330 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
db3927fb 9331 return omit_one_operand_loc (loc, type, arg0, arg1);
b8698a0f 9332
b64d949c
KG
9333 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9334 functions to return the numeric arg if the other one is NaN.
9335 These tree codes don't honor that, so only transform if
9336 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9337 handled, so we don't have to worry about it either. */
9338 if (flag_finite_math_only)
db3927fb
AH
9339 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9340 fold_convert_loc (loc, type, arg0),
9341 fold_convert_loc (loc, type, arg1));
b64d949c
KG
9342 }
9343 return NULL_TREE;
9344}
9345
527cab20
KG
9346/* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9347
9348static tree
db3927fb 9349fold_builtin_carg (location_t loc, tree arg, tree type)
527cab20 9350{
c128599a
KG
9351 if (validate_arg (arg, COMPLEX_TYPE)
9352 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
527cab20
KG
9353 {
9354 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
b8698a0f 9355
527cab20
KG
9356 if (atan2_fn)
9357 {
5039610b 9358 tree new_arg = builtin_save_expr (arg);
db3927fb
AH
9359 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9360 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9361 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
527cab20
KG
9362 }
9363 }
b8698a0f 9364
527cab20
KG
9365 return NULL_TREE;
9366}
9367
6351a719
KG
9368/* Fold a call to builtin logb/ilogb. */
9369
9370static tree
db3927fb 9371fold_builtin_logb (location_t loc, tree arg, tree rettype)
6351a719
KG
9372{
9373 if (! validate_arg (arg, REAL_TYPE))
9374 return NULL_TREE;
b8698a0f 9375
6351a719 9376 STRIP_NOPS (arg);
b8698a0f 9377
6351a719
KG
9378 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9379 {
9380 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
b8698a0f 9381
6351a719
KG
9382 switch (value->cl)
9383 {
9384 case rvc_nan:
9385 case rvc_inf:
9386 /* If arg is Inf or NaN and we're logb, return it. */
9387 if (TREE_CODE (rettype) == REAL_TYPE)
db3927fb 9388 return fold_convert_loc (loc, rettype, arg);
6351a719
KG
9389 /* Fall through... */
9390 case rvc_zero:
9391 /* Zero may set errno and/or raise an exception for logb, also
9392 for ilogb we don't know FP_ILOGB0. */
9393 return NULL_TREE;
9394 case rvc_normal:
9395 /* For normal numbers, proceed iff radix == 2. In GCC,
9396 normalized significands are in the range [0.5, 1.0). We
9397 want the exponent as if they were [1.0, 2.0) so get the
9398 exponent and subtract 1. */
9399 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
db3927fb
AH
9400 return fold_convert_loc (loc, rettype,
9401 build_int_cst (NULL_TREE,
9402 REAL_EXP (value)-1));
6351a719
KG
9403 break;
9404 }
9405 }
b8698a0f 9406
6351a719
KG
9407 return NULL_TREE;
9408}
9409
9410/* Fold a call to builtin significand, if radix == 2. */
9411
9412static tree
db3927fb 9413fold_builtin_significand (location_t loc, tree arg, tree rettype)
6351a719
KG
9414{
9415 if (! validate_arg (arg, REAL_TYPE))
9416 return NULL_TREE;
b8698a0f 9417
6351a719 9418 STRIP_NOPS (arg);
b8698a0f 9419
6351a719
KG
9420 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9421 {
9422 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
b8698a0f 9423
6351a719
KG
9424 switch (value->cl)
9425 {
9426 case rvc_zero:
9427 case rvc_nan:
9428 case rvc_inf:
9429 /* If arg is +-0, +-Inf or +-NaN, then return it. */
db3927fb 9430 return fold_convert_loc (loc, rettype, arg);
6351a719
KG
9431 case rvc_normal:
9432 /* For normal numbers, proceed iff radix == 2. */
9433 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9434 {
9435 REAL_VALUE_TYPE result = *value;
9436 /* In GCC, normalized significands are in the range [0.5,
9437 1.0). We want them to be [1.0, 2.0) so set the
9438 exponent to 1. */
9439 SET_REAL_EXP (&result, 1);
9440 return build_real (rettype, result);
9441 }
9442 break;
9443 }
9444 }
b8698a0f 9445
6351a719
KG
9446 return NULL_TREE;
9447}
9448
7a2a25ab
KG
9449/* Fold a call to builtin frexp, we can assume the base is 2. */
9450
9451static tree
db3927fb 9452fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
7a2a25ab
KG
9453{
9454 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9455 return NULL_TREE;
b8698a0f 9456
7a2a25ab 9457 STRIP_NOPS (arg0);
b8698a0f 9458
7a2a25ab
KG
9459 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9460 return NULL_TREE;
b8698a0f 9461
db3927fb 9462 arg1 = build_fold_indirect_ref_loc (loc, arg1);
7a2a25ab
KG
9463
9464 /* Proceed if a valid pointer type was passed in. */
9465 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9466 {
9467 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9468 tree frac, exp;
b8698a0f 9469
7a2a25ab
KG
9470 switch (value->cl)
9471 {
9472 case rvc_zero:
9473 /* For +-0, return (*exp = 0, +-0). */
9474 exp = integer_zero_node;
9475 frac = arg0;
9476 break;
9477 case rvc_nan:
9478 case rvc_inf:
9479 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
db3927fb 9480 return omit_one_operand_loc (loc, rettype, arg0, arg1);
7a2a25ab
KG
9481 case rvc_normal:
9482 {
9483 /* Since the frexp function always expects base 2, and in
9484 GCC normalized significands are already in the range
9485 [0.5, 1.0), we have exactly what frexp wants. */
9486 REAL_VALUE_TYPE frac_rvt = *value;
9487 SET_REAL_EXP (&frac_rvt, 0);
9488 frac = build_real (rettype, frac_rvt);
9489 exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9490 }
9491 break;
9492 default:
9493 gcc_unreachable ();
9494 }
b8698a0f 9495
7a2a25ab 9496 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
db3927fb 9497 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
7a2a25ab 9498 TREE_SIDE_EFFECTS (arg1) = 1;
db3927fb 9499 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
7a2a25ab
KG
9500 }
9501
9502 return NULL_TREE;
9503}
9504
2b5e5642
KG
9505/* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9506 then we can assume the base is two. If it's false, then we have to
9507 check the mode of the TYPE parameter in certain cases. */
9508
9509static tree
db3927fb
AH
9510fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9511 tree type, bool ldexp)
2b5e5642
KG
9512{
9513 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9514 {
9515 STRIP_NOPS (arg0);
9516 STRIP_NOPS (arg1);
9517
9518 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9519 if (real_zerop (arg0) || integer_zerop (arg1)
9520 || (TREE_CODE (arg0) == REAL_CST
4c8c70e0 9521 && !real_isfinite (&TREE_REAL_CST (arg0))))
db3927fb 9522 return omit_one_operand_loc (loc, type, arg0, arg1);
b8698a0f 9523
2b5e5642
KG
9524 /* If both arguments are constant, then try to evaluate it. */
9525 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9526 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9527 && host_integerp (arg1, 0))
9528 {
9529 /* Bound the maximum adjustment to twice the range of the
9530 mode's valid exponents. Use abs to ensure the range is
9531 positive as a sanity check. */
b8698a0f 9532 const long max_exp_adj = 2 *
2b5e5642
KG
9533 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9534 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9535
9536 /* Get the user-requested adjustment. */
9537 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
b8698a0f 9538
2b5e5642
KG
9539 /* The requested adjustment must be inside this range. This
9540 is a preliminary cap to avoid things like overflow, we
9541 may still fail to compute the result for other reasons. */
9542 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9543 {
9544 REAL_VALUE_TYPE initial_result;
b8698a0f 9545
2b5e5642
KG
9546 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9547
9548 /* Ensure we didn't overflow. */
9549 if (! real_isinf (&initial_result))
9550 {
9551 const REAL_VALUE_TYPE trunc_result
9552 = real_value_truncate (TYPE_MODE (type), initial_result);
b8698a0f 9553
2b5e5642
KG
9554 /* Only proceed if the target mode can hold the
9555 resulting value. */
9556 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9557 return build_real (type, trunc_result);
9558 }
9559 }
9560 }
9561 }
9562
9563 return NULL_TREE;
9564}
9565
3d577eaf
KG
9566/* Fold a call to builtin modf. */
9567
9568static tree
db3927fb 9569fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
3d577eaf
KG
9570{
9571 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9572 return NULL_TREE;
b8698a0f 9573
3d577eaf 9574 STRIP_NOPS (arg0);
b8698a0f 9575
3d577eaf
KG
9576 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9577 return NULL_TREE;
b8698a0f 9578
db3927fb 9579 arg1 = build_fold_indirect_ref_loc (loc, arg1);
3d577eaf
KG
9580
9581 /* Proceed if a valid pointer type was passed in. */
9582 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9583 {
9584 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9585 REAL_VALUE_TYPE trunc, frac;
9586
9587 switch (value->cl)
9588 {
9589 case rvc_nan:
9590 case rvc_zero:
9591 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9592 trunc = frac = *value;
9593 break;
9594 case rvc_inf:
9595 /* For +-Inf, return (*arg1 = arg0, +-0). */
9596 frac = dconst0;
9597 frac.sign = value->sign;
9598 trunc = *value;
9599 break;
9600 case rvc_normal:
9601 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9602 real_trunc (&trunc, VOIDmode, value);
9603 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9604 /* If the original number was negative and already
9605 integral, then the fractional part is -0.0. */
9606 if (value->sign && frac.cl == rvc_zero)
9607 frac.sign = value->sign;
9608 break;
9609 }
b8698a0f 9610
3d577eaf 9611 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
db3927fb 9612 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
3d577eaf
KG
9613 build_real (rettype, trunc));
9614 TREE_SIDE_EFFECTS (arg1) = 1;
db3927fb 9615 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
3d577eaf
KG
9616 build_real (rettype, frac));
9617 }
b8698a0f 9618
3d577eaf
KG
9619 return NULL_TREE;
9620}
9621
44e10129
MM
9622/* Given a location LOC, an interclass builtin function decl FNDECL
9623 and its single argument ARG, return an folded expression computing
9624 the same, or NULL_TREE if we either couldn't or didn't want to fold
9625 (the latter happen if there's an RTL instruction available). */
9626
9627static tree
9628fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9629{
9630 enum machine_mode mode;
9631
9632 if (!validate_arg (arg, REAL_TYPE))
9633 return NULL_TREE;
9634
9635 if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9636 return NULL_TREE;
9637
9638 mode = TYPE_MODE (TREE_TYPE (arg));
9639
9640 /* If there is no optab, try generic code. */
9641 switch (DECL_FUNCTION_CODE (fndecl))
9642 {
9643 tree result;
9644
9645 CASE_FLT_FN (BUILT_IN_ISINF):
9646 {
9647 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
9648 tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
9649 tree const type = TREE_TYPE (arg);
9650 REAL_VALUE_TYPE r;
9651 char buf[128];
9652
9653 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9654 real_from_string (&r, buf);
9655 result = build_call_expr (isgr_fn, 2,
9656 fold_build1_loc (loc, ABS_EXPR, type, arg),
9657 build_real (type, r));
9658 return result;
9659 }
9660 CASE_FLT_FN (BUILT_IN_FINITE):
9661 case BUILT_IN_ISFINITE:
9662 {
9663 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
9664 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9665 tree const type = TREE_TYPE (arg);
9666 REAL_VALUE_TYPE r;
9667 char buf[128];
9668
9669 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9670 real_from_string (&r, buf);
9671 result = build_call_expr (isle_fn, 2,
9672 fold_build1_loc (loc, ABS_EXPR, type, arg),
9673 build_real (type, r));
9674 /*result = fold_build2_loc (loc, UNGT_EXPR,
9675 TREE_TYPE (TREE_TYPE (fndecl)),
9676 fold_build1_loc (loc, ABS_EXPR, type, arg),
9677 build_real (type, r));
9678 result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9679 TREE_TYPE (TREE_TYPE (fndecl)),
9680 result);*/
9681 return result;
9682 }
9683 case BUILT_IN_ISNORMAL:
9684 {
9685 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9686 islessequal(fabs(x),DBL_MAX). */
9687 tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9688 tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
9689 tree const type = TREE_TYPE (arg);
9690 REAL_VALUE_TYPE rmax, rmin;
9691 char buf[128];
9692
9693 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9694 real_from_string (&rmax, buf);
9695 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9696 real_from_string (&rmin, buf);
9697 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9698 result = build_call_expr (isle_fn, 2, arg,
9699 build_real (type, rmax));
9700 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9701 build_call_expr (isge_fn, 2, arg,
9702 build_real (type, rmin)));
9703 return result;
9704 }
9705 default:
9706 break;
9707 }
9708
9709 return NULL_TREE;
9710}
9711
64a9295a 9712/* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
5039610b 9713 ARG is the argument for the call. */
64a9295a
PB
9714
9715static tree
db3927fb 9716fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
64a9295a 9717{
64a9295a 9718 tree type = TREE_TYPE (TREE_TYPE (fndecl));
64a9295a
PB
9719 REAL_VALUE_TYPE r;
9720
5039610b 9721 if (!validate_arg (arg, REAL_TYPE))
83322951 9722 return NULL_TREE;
64a9295a 9723
64a9295a
PB
9724 switch (builtin_index)
9725 {
9726 case BUILT_IN_ISINF:
27d7d042 9727 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
db3927fb 9728 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
64a9295a
PB
9729
9730 if (TREE_CODE (arg) == REAL_CST)
9731 {
9732 r = TREE_REAL_CST (arg);
9733 if (real_isinf (&r))
9734 return real_compare (GT_EXPR, &r, &dconst0)
9735 ? integer_one_node : integer_minus_one_node;
9736 else
9737 return integer_zero_node;
9738 }
9739
9740 return NULL_TREE;
9741
05f41289
KG
9742 case BUILT_IN_ISINF_SIGN:
9743 {
9744 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9745 /* In a boolean context, GCC will fold the inner COND_EXPR to
9746 1. So e.g. "if (isinf_sign(x))" would be folded to just
9747 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9748 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9749 tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9750 tree tmp = NULL_TREE;
9751
9752 arg = builtin_save_expr (arg);
9753
9754 if (signbit_fn && isinf_fn)
9755 {
db3927fb
AH
9756 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
9757 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
05f41289 9758
db3927fb 9759 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
05f41289 9760 signbit_call, integer_zero_node);
db3927fb 9761 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
05f41289 9762 isinf_call, integer_zero_node);
b8698a0f 9763
db3927fb 9764 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
05f41289 9765 integer_minus_one_node, integer_one_node);
db3927fb
AH
9766 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9767 isinf_call, tmp,
05f41289
KG
9768 integer_zero_node);
9769 }
9770
9771 return tmp;
9772 }
9773
0c8d3c2b 9774 case BUILT_IN_ISFINITE:
27d7d042
RG
9775 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9776 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
db3927fb 9777 return omit_one_operand_loc (loc, type, integer_one_node, arg);
64a9295a
PB
9778
9779 if (TREE_CODE (arg) == REAL_CST)
9780 {
9781 r = TREE_REAL_CST (arg);
4c8c70e0 9782 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
64a9295a
PB
9783 }
9784
9785 return NULL_TREE;
9786
9787 case BUILT_IN_ISNAN:
27d7d042 9788 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
db3927fb 9789 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
64a9295a
PB
9790
9791 if (TREE_CODE (arg) == REAL_CST)
9792 {
9793 r = TREE_REAL_CST (arg);
9794 return real_isnan (&r) ? integer_one_node : integer_zero_node;
9795 }
9796
9797 arg = builtin_save_expr (arg);
db3927fb 9798 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
64a9295a
PB
9799
9800 default:
298e6adc 9801 gcc_unreachable ();
64a9295a
PB
9802 }
9803}
9804
3bf5906b
KG
9805/* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9806 This builtin will generate code to return the appropriate floating
9807 point classification depending on the value of the floating point
9808 number passed in. The possible return values must be supplied as
32101f99 9809 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
3bf5906b
KG
9810 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
9811 one floating point argument which is "type generic". */
9812
9813static tree
db3927fb 9814fold_builtin_fpclassify (location_t loc, tree exp)
3bf5906b 9815{
32101f99
KG
9816 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9817 arg, type, res, tmp;
3bf5906b
KG
9818 enum machine_mode mode;
9819 REAL_VALUE_TYPE r;
9820 char buf[128];
b8698a0f 9821
3bf5906b
KG
9822 /* Verify the required arguments in the original call. */
9823 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9824 INTEGER_TYPE, INTEGER_TYPE,
9825 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9826 return NULL_TREE;
b8698a0f 9827
3bf5906b 9828 fp_nan = CALL_EXPR_ARG (exp, 0);
32101f99 9829 fp_infinite = CALL_EXPR_ARG (exp, 1);
3bf5906b
KG
9830 fp_normal = CALL_EXPR_ARG (exp, 2);
9831 fp_subnormal = CALL_EXPR_ARG (exp, 3);
9832 fp_zero = CALL_EXPR_ARG (exp, 4);
9833 arg = CALL_EXPR_ARG (exp, 5);
9834 type = TREE_TYPE (arg);
9835 mode = TYPE_MODE (type);
db3927fb 9836 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
3bf5906b 9837
b8698a0f 9838 /* fpclassify(x) ->
3bf5906b 9839 isnan(x) ? FP_NAN :
32101f99 9840 (fabs(x) == Inf ? FP_INFINITE :
3bf5906b
KG
9841 (fabs(x) >= DBL_MIN ? FP_NORMAL :
9842 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
b8698a0f 9843
db3927fb 9844 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
3bf5906b 9845 build_real (type, dconst0));
db3927fb
AH
9846 res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9847 tmp, fp_zero, fp_subnormal);
3bf5906b
KG
9848
9849 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9850 real_from_string (&r, buf);
db3927fb
AH
9851 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
9852 arg, build_real (type, r));
9853 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
b8698a0f 9854
3bf5906b
KG
9855 if (HONOR_INFINITIES (mode))
9856 {
9857 real_inf (&r);
db3927fb 9858 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
3bf5906b 9859 build_real (type, r));
db3927fb
AH
9860 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
9861 fp_infinite, res);
3bf5906b
KG
9862 }
9863
9864 if (HONOR_NANS (mode))
9865 {
db3927fb
AH
9866 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
9867 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
3bf5906b 9868 }
b8698a0f 9869
3bf5906b
KG
9870 return res;
9871}
9872
08039bd8 9873/* Fold a call to an unordered comparison function such as
a35da91f 9874 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
5039610b 9875 being called and ARG0 and ARG1 are the arguments for the call.
64a9295a
PB
9876 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9877 the opposite of the desired result. UNORDERED_CODE is used
9878 for modes that can hold NaNs and ORDERED_CODE is used for
9879 the rest. */
08039bd8
RS
9880
9881static tree
db3927fb 9882fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
08039bd8
RS
9883 enum tree_code unordered_code,
9884 enum tree_code ordered_code)
9885{
14f661f1 9886 tree type = TREE_TYPE (TREE_TYPE (fndecl));
08039bd8 9887 enum tree_code code;
1aeaea8d
GK
9888 tree type0, type1;
9889 enum tree_code code0, code1;
9890 tree cmp_type = NULL_TREE;
08039bd8 9891
1aeaea8d
GK
9892 type0 = TREE_TYPE (arg0);
9893 type1 = TREE_TYPE (arg1);
c22cacf3 9894
1aeaea8d
GK
9895 code0 = TREE_CODE (type0);
9896 code1 = TREE_CODE (type1);
c22cacf3 9897
1aeaea8d
GK
9898 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9899 /* Choose the wider of two real types. */
9900 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9901 ? type0 : type1;
9902 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9903 cmp_type = type0;
9904 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9905 cmp_type = type1;
c22cacf3 9906
db3927fb
AH
9907 arg0 = fold_convert_loc (loc, cmp_type, arg0);
9908 arg1 = fold_convert_loc (loc, cmp_type, arg1);
14f661f1
RS
9909
9910 if (unordered_code == UNORDERED_EXPR)
9911 {
27d7d042 9912 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
db3927fb
AH
9913 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
9914 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
14f661f1 9915 }
08039bd8 9916
27d7d042
RG
9917 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9918 : ordered_code;
db3927fb
AH
9919 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
9920 fold_build2_loc (loc, code, type, arg0, arg1));
08039bd8
RS
9921}
9922
5039610b
SL
9923/* Fold a call to built-in function FNDECL with 0 arguments.
9924 IGNORE is true if the result of the function call is ignored. This
9925 function returns NULL_TREE if no simplification was possible. */
b0b3afb2 9926
6de9cd9a 9927static tree
db3927fb 9928fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
b0b3afb2 9929{
c0a47a61 9930 tree type = TREE_TYPE (TREE_TYPE (fndecl));
5039610b 9931 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
a0d2281e 9932 switch (fcode)
b0b3afb2 9933 {
5039610b
SL
9934 CASE_FLT_FN (BUILT_IN_INF):
9935 case BUILT_IN_INFD32:
9936 case BUILT_IN_INFD64:
9937 case BUILT_IN_INFD128:
db3927fb 9938 return fold_builtin_inf (loc, type, true);
d3147f64 9939
5039610b 9940 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
db3927fb 9941 return fold_builtin_inf (loc, type, false);
d3147f64 9942
5039610b
SL
9943 case BUILT_IN_CLASSIFY_TYPE:
9944 return fold_builtin_classify_type (NULL_TREE);
d3147f64 9945
5039610b
SL
9946 default:
9947 break;
9948 }
9949 return NULL_TREE;
9950}
d3147f64 9951
5039610b
SL
9952/* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9953 IGNORE is true if the result of the function call is ignored. This
9954 function returns NULL_TREE if no simplification was possible. */
d3147f64 9955
5039610b 9956static tree
db3927fb 9957fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
5039610b
SL
9958{
9959 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9960 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9961 switch (fcode)
9962 {
d3147f64 9963
b0b3afb2 9964 case BUILT_IN_CONSTANT_P:
d3147f64 9965 {
5039610b 9966 tree val = fold_builtin_constant_p (arg0);
d3147f64 9967
d3147f64
EC
9968 /* Gimplification will pull the CALL_EXPR for the builtin out of
9969 an if condition. When not optimizing, we'll not CSE it back.
9970 To avoid link error types of regressions, return false now. */
9971 if (!val && !optimize)
9972 val = integer_zero_node;
9973
9974 return val;
9975 }
b0b3afb2 9976
ad82abb8 9977 case BUILT_IN_CLASSIFY_TYPE:
5039610b 9978 return fold_builtin_classify_type (arg0);
ad82abb8 9979
b0b3afb2 9980 case BUILT_IN_STRLEN:
db3927fb 9981 return fold_builtin_strlen (loc, arg0);
b0b3afb2 9982
ea6a6627 9983 CASE_FLT_FN (BUILT_IN_FABS):
db3927fb 9984 return fold_builtin_fabs (loc, arg0, type);
9655d83b
RS
9985
9986 case BUILT_IN_ABS:
9987 case BUILT_IN_LABS:
9988 case BUILT_IN_LLABS:
9989 case BUILT_IN_IMAXABS:
db3927fb 9990 return fold_builtin_abs (loc, arg0, type);
07bae5ad 9991
ea6a6627 9992 CASE_FLT_FN (BUILT_IN_CONJ):
c128599a 9993 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 9994 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
db3927fb 9995 return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
5039610b 9996 break;
aa6c7c3a 9997
ea6a6627 9998 CASE_FLT_FN (BUILT_IN_CREAL):
c128599a 9999 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10000 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
db3927fb 10001 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
5039610b 10002 break;
aa6c7c3a 10003
ea6a6627 10004 CASE_FLT_FN (BUILT_IN_CIMAG):
376da68e
KG
10005 if (validate_arg (arg0, COMPLEX_TYPE)
10006 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
db3927fb 10007 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
5039610b 10008 break;
aa6c7c3a 10009
4b26d10b 10010 CASE_FLT_FN (BUILT_IN_CCOS):
db3927fb 10011 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
b8698a0f 10012
4b26d10b 10013 CASE_FLT_FN (BUILT_IN_CCOSH):
db3927fb 10014 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
b8698a0f 10015
c128599a
KG
10016#ifdef HAVE_mpc
10017 CASE_FLT_FN (BUILT_IN_CSIN):
10018 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10019 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a 10020 return do_mpc_arg1 (arg0, type, mpc_sin);
5039610b 10021 break;
b8698a0f 10022
c128599a
KG
10023 CASE_FLT_FN (BUILT_IN_CSINH):
10024 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10025 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a
KG
10026 return do_mpc_arg1 (arg0, type, mpc_sinh);
10027 break;
b8698a0f 10028
c128599a
KG
10029 CASE_FLT_FN (BUILT_IN_CTAN):
10030 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10031 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a
KG
10032 return do_mpc_arg1 (arg0, type, mpc_tan);
10033 break;
b8698a0f 10034
c128599a
KG
10035 CASE_FLT_FN (BUILT_IN_CTANH):
10036 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10037 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a
KG
10038 return do_mpc_arg1 (arg0, type, mpc_tanh);
10039 break;
b8698a0f 10040
c128599a
KG
10041 CASE_FLT_FN (BUILT_IN_CLOG):
10042 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10043 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a
KG
10044 return do_mpc_arg1 (arg0, type, mpc_log);
10045 break;
b8698a0f 10046
c128599a
KG
10047 CASE_FLT_FN (BUILT_IN_CSQRT):
10048 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10049 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
c128599a
KG
10050 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10051 break;
b8698a0f 10052
7610abd8
KG
10053#ifdef HAVE_mpc_arc
10054 CASE_FLT_FN (BUILT_IN_CASIN):
10055 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10056 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10057 return do_mpc_arg1 (arg0, type, mpc_asin);
10058 break;
b8698a0f 10059
7610abd8
KG
10060 CASE_FLT_FN (BUILT_IN_CACOS):
10061 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10062 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10063 return do_mpc_arg1 (arg0, type, mpc_acos);
10064 break;
b8698a0f 10065
7610abd8
KG
10066 CASE_FLT_FN (BUILT_IN_CATAN):
10067 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10068 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10069 return do_mpc_arg1 (arg0, type, mpc_atan);
10070 break;
b8698a0f 10071
7610abd8
KG
10072 CASE_FLT_FN (BUILT_IN_CASINH):
10073 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10074 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10075 return do_mpc_arg1 (arg0, type, mpc_asinh);
10076 break;
b8698a0f 10077
7610abd8
KG
10078 CASE_FLT_FN (BUILT_IN_CACOSH):
10079 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10080 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10081 return do_mpc_arg1 (arg0, type, mpc_acosh);
10082 break;
b8698a0f 10083
7610abd8
KG
10084 CASE_FLT_FN (BUILT_IN_CATANH):
10085 if (validate_arg (arg0, COMPLEX_TYPE)
b8698a0f 10086 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
7610abd8
KG
10087 return do_mpc_arg1 (arg0, type, mpc_atanh);
10088 break;
10089#endif /* HAVE_mpc_arc */
10090#endif /* HAVE_mpc */
b8698a0f 10091
ea6a6627 10092 CASE_FLT_FN (BUILT_IN_CABS):
db3927fb 10093 return fold_builtin_cabs (loc, arg0, type, fndecl);
07bae5ad 10094
527cab20 10095 CASE_FLT_FN (BUILT_IN_CARG):
db3927fb 10096 return fold_builtin_carg (loc, arg0, type);
527cab20 10097
ea6a6627 10098 CASE_FLT_FN (BUILT_IN_SQRT):
db3927fb 10099 return fold_builtin_sqrt (loc, arg0, type);
4977bab6 10100
ea6a6627 10101 CASE_FLT_FN (BUILT_IN_CBRT):
db3927fb 10102 return fold_builtin_cbrt (loc, arg0, type);
e19f6bde 10103
b53fed56 10104 CASE_FLT_FN (BUILT_IN_ASIN):
5039610b
SL
10105 if (validate_arg (arg0, REAL_TYPE))
10106 return do_mpfr_arg1 (arg0, type, mpfr_asin,
b53fed56
KG
10107 &dconstm1, &dconst1, true);
10108 break;
10109
10110 CASE_FLT_FN (BUILT_IN_ACOS):
5039610b
SL
10111 if (validate_arg (arg0, REAL_TYPE))
10112 return do_mpfr_arg1 (arg0, type, mpfr_acos,
b53fed56
KG
10113 &dconstm1, &dconst1, true);
10114 break;
10115
10116 CASE_FLT_FN (BUILT_IN_ATAN):
5039610b
SL
10117 if (validate_arg (arg0, REAL_TYPE))
10118 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
b53fed56
KG
10119 break;
10120
10121 CASE_FLT_FN (BUILT_IN_ASINH):
5039610b
SL
10122 if (validate_arg (arg0, REAL_TYPE))
10123 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
b53fed56
KG
10124 break;
10125
10126 CASE_FLT_FN (BUILT_IN_ACOSH):
5039610b
SL
10127 if (validate_arg (arg0, REAL_TYPE))
10128 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
b53fed56
KG
10129 &dconst1, NULL, true);
10130 break;
10131
10132 CASE_FLT_FN (BUILT_IN_ATANH):
5039610b
SL
10133 if (validate_arg (arg0, REAL_TYPE))
10134 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
b53fed56
KG
10135 &dconstm1, &dconst1, false);
10136 break;
10137
ea6a6627 10138 CASE_FLT_FN (BUILT_IN_SIN):
5039610b
SL
10139 if (validate_arg (arg0, REAL_TYPE))
10140 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
b53fed56 10141 break;
03f2ea93 10142
ea6a6627 10143 CASE_FLT_FN (BUILT_IN_COS):
db3927fb 10144 return fold_builtin_cos (loc, arg0, type, fndecl);
03f2ea93 10145
b53fed56 10146 CASE_FLT_FN (BUILT_IN_TAN):
5039610b 10147 return fold_builtin_tan (arg0, type);
75c7c595 10148
28f4586b 10149 CASE_FLT_FN (BUILT_IN_CEXP):
db3927fb 10150 return fold_builtin_cexp (loc, arg0, type);
28f4586b 10151
75c7c595 10152 CASE_FLT_FN (BUILT_IN_CEXPI):
5039610b
SL
10153 if (validate_arg (arg0, REAL_TYPE))
10154 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10155 break;
b68bcfff 10156
b53fed56 10157 CASE_FLT_FN (BUILT_IN_SINH):
5039610b
SL
10158 if (validate_arg (arg0, REAL_TYPE))
10159 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
b53fed56
KG
10160 break;
10161
10162 CASE_FLT_FN (BUILT_IN_COSH):
db3927fb 10163 return fold_builtin_cosh (loc, arg0, type, fndecl);
b53fed56
KG
10164
10165 CASE_FLT_FN (BUILT_IN_TANH):
5039610b
SL
10166 if (validate_arg (arg0, REAL_TYPE))
10167 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
b53fed56
KG
10168 break;
10169
cf1491f0 10170 CASE_FLT_FN (BUILT_IN_ERF):
5039610b
SL
10171 if (validate_arg (arg0, REAL_TYPE))
10172 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
cf1491f0
KG
10173 break;
10174
10175 CASE_FLT_FN (BUILT_IN_ERFC):
5039610b
SL
10176 if (validate_arg (arg0, REAL_TYPE))
10177 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
cf1491f0
KG
10178 break;
10179
61fb309f 10180 CASE_FLT_FN (BUILT_IN_TGAMMA):
5039610b
SL
10181 if (validate_arg (arg0, REAL_TYPE))
10182 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
61fb309f 10183 break;
b8698a0f 10184
ea6a6627 10185 CASE_FLT_FN (BUILT_IN_EXP):
db3927fb 10186 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
67057c53 10187
ea6a6627 10188 CASE_FLT_FN (BUILT_IN_EXP2):
db3927fb 10189 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
67057c53 10190
ea6a6627
VR
10191 CASE_FLT_FN (BUILT_IN_EXP10):
10192 CASE_FLT_FN (BUILT_IN_POW10):
db3927fb 10193 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
67057c53 10194
cf1491f0 10195 CASE_FLT_FN (BUILT_IN_EXPM1):
5039610b
SL
10196 if (validate_arg (arg0, REAL_TYPE))
10197 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
cf1491f0 10198 break;
b8698a0f 10199
ea6a6627 10200 CASE_FLT_FN (BUILT_IN_LOG):
db3927fb 10201 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
67057c53 10202
ea6a6627 10203 CASE_FLT_FN (BUILT_IN_LOG2):
db3927fb 10204 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
67057c53 10205
ea6a6627 10206 CASE_FLT_FN (BUILT_IN_LOG10):
db3927fb 10207 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
cf1491f0
KG
10208
10209 CASE_FLT_FN (BUILT_IN_LOG1P):
5039610b
SL
10210 if (validate_arg (arg0, REAL_TYPE))
10211 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
cf1491f0
KG
10212 &dconstm1, NULL, false);
10213 break;
4977bab6 10214
550b3187
KG
10215 CASE_FLT_FN (BUILT_IN_J0):
10216 if (validate_arg (arg0, REAL_TYPE))
10217 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10218 NULL, NULL, 0);
10219 break;
10220
10221 CASE_FLT_FN (BUILT_IN_J1):
10222 if (validate_arg (arg0, REAL_TYPE))
10223 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10224 NULL, NULL, 0);
10225 break;
fd2ef596
KG
10226
10227 CASE_FLT_FN (BUILT_IN_Y0):
10228 if (validate_arg (arg0, REAL_TYPE))
10229 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10230 &dconst0, NULL, false);
10231 break;
10232
10233 CASE_FLT_FN (BUILT_IN_Y1):
10234 if (validate_arg (arg0, REAL_TYPE))
10235 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10236 &dconst0, NULL, false);
10237 break;
550b3187 10238
ea6a6627 10239 CASE_FLT_FN (BUILT_IN_NAN):
9a8ce21f
JG
10240 case BUILT_IN_NAND32:
10241 case BUILT_IN_NAND64:
10242 case BUILT_IN_NAND128:
5039610b 10243 return fold_builtin_nan (arg0, type, true);
1472e41c 10244
ea6a6627 10245 CASE_FLT_FN (BUILT_IN_NANS):
5039610b 10246 return fold_builtin_nan (arg0, type, false);
1472e41c 10247
ea6a6627 10248 CASE_FLT_FN (BUILT_IN_FLOOR):
db3927fb 10249 return fold_builtin_floor (loc, fndecl, arg0);
0a9530a9 10250
ea6a6627 10251 CASE_FLT_FN (BUILT_IN_CEIL):
db3927fb 10252 return fold_builtin_ceil (loc, fndecl, arg0);
0a9530a9 10253
ea6a6627 10254 CASE_FLT_FN (BUILT_IN_TRUNC):
db3927fb 10255 return fold_builtin_trunc (loc, fndecl, arg0);
0a9530a9 10256
ea6a6627 10257 CASE_FLT_FN (BUILT_IN_ROUND):
db3927fb 10258 return fold_builtin_round (loc, fndecl, arg0);
25348c94 10259
ea6a6627
VR
10260 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10261 CASE_FLT_FN (BUILT_IN_RINT):
db3927fb 10262 return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
27a6aa72 10263
ea6a6627
VR
10264 CASE_FLT_FN (BUILT_IN_LCEIL):
10265 CASE_FLT_FN (BUILT_IN_LLCEIL):
10266 CASE_FLT_FN (BUILT_IN_LFLOOR):
10267 CASE_FLT_FN (BUILT_IN_LLFLOOR):
c22cacf3 10268 CASE_FLT_FN (BUILT_IN_LROUND):
ea6a6627 10269 CASE_FLT_FN (BUILT_IN_LLROUND):
db3927fb 10270 return fold_builtin_int_roundingfn (loc, fndecl, arg0);
3bf05748 10271
ea6a6627
VR
10272 CASE_FLT_FN (BUILT_IN_LRINT):
10273 CASE_FLT_FN (BUILT_IN_LLRINT):
db3927fb 10274 return fold_fixed_mathfn (loc, fndecl, arg0);
ca3df643 10275
167fa32c
EC
10276 case BUILT_IN_BSWAP32:
10277 case BUILT_IN_BSWAP64:
5039610b 10278 return fold_builtin_bswap (fndecl, arg0);
167fa32c 10279
ea6a6627
VR
10280 CASE_INT_FN (BUILT_IN_FFS):
10281 CASE_INT_FN (BUILT_IN_CLZ):
10282 CASE_INT_FN (BUILT_IN_CTZ):
10283 CASE_INT_FN (BUILT_IN_POPCOUNT):
10284 CASE_INT_FN (BUILT_IN_PARITY):
5039610b 10285 return fold_builtin_bitop (fndecl, arg0);
5bb650ec 10286
ea6a6627 10287 CASE_FLT_FN (BUILT_IN_SIGNBIT):
db3927fb 10288 return fold_builtin_signbit (loc, arg0, type);
ef79730c 10289
6351a719 10290 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
db3927fb 10291 return fold_builtin_significand (loc, arg0, type);
6351a719
KG
10292
10293 CASE_FLT_FN (BUILT_IN_ILOGB):
10294 CASE_FLT_FN (BUILT_IN_LOGB):
db3927fb 10295 return fold_builtin_logb (loc, arg0, type);
6351a719 10296
df0785d6 10297 case BUILT_IN_ISASCII:
db3927fb 10298 return fold_builtin_isascii (loc, arg0);
df0785d6
KG
10299
10300 case BUILT_IN_TOASCII:
db3927fb 10301 return fold_builtin_toascii (loc, arg0);
df0785d6 10302
61218d19 10303 case BUILT_IN_ISDIGIT:
db3927fb 10304 return fold_builtin_isdigit (loc, arg0);
67057c53 10305
ea6a6627 10306 CASE_FLT_FN (BUILT_IN_FINITE):
9a8ce21f
JG
10307 case BUILT_IN_FINITED32:
10308 case BUILT_IN_FINITED64:
10309 case BUILT_IN_FINITED128:
0c8d3c2b 10310 case BUILT_IN_ISFINITE:
44e10129
MM
10311 {
10312 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10313 if (ret)
10314 return ret;
10315 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10316 }
64a9295a 10317
ea6a6627 10318 CASE_FLT_FN (BUILT_IN_ISINF):
9a8ce21f
JG
10319 case BUILT_IN_ISINFD32:
10320 case BUILT_IN_ISINFD64:
10321 case BUILT_IN_ISINFD128:
44e10129
MM
10322 {
10323 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10324 if (ret)
10325 return ret;
10326 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10327 }
10328
10329 case BUILT_IN_ISNORMAL:
10330 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
64a9295a 10331
05f41289 10332 case BUILT_IN_ISINF_SIGN:
db3927fb 10333 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
05f41289 10334
ea6a6627 10335 CASE_FLT_FN (BUILT_IN_ISNAN):
9a8ce21f
JG
10336 case BUILT_IN_ISNAND32:
10337 case BUILT_IN_ISNAND64:
10338 case BUILT_IN_ISNAND128:
db3927fb 10339 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
5039610b
SL
10340
10341 case BUILT_IN_PRINTF:
10342 case BUILT_IN_PRINTF_UNLOCKED:
10343 case BUILT_IN_VPRINTF:
db3927fb 10344 return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
5039610b
SL
10345
10346 default:
10347 break;
10348 }
10349
10350 return NULL_TREE;
10351
10352}
10353
10354/* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10355 IGNORE is true if the result of the function call is ignored. This
10356 function returns NULL_TREE if no simplification was possible. */
10357
10358static tree
db3927fb 10359fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
5039610b
SL
10360{
10361 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10362 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10363
10364 switch (fcode)
10365 {
550b3187
KG
10366 CASE_FLT_FN (BUILT_IN_JN):
10367 if (validate_arg (arg0, INTEGER_TYPE)
10368 && validate_arg (arg1, REAL_TYPE))
10369 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10370 break;
fd2ef596
KG
10371
10372 CASE_FLT_FN (BUILT_IN_YN):
10373 if (validate_arg (arg0, INTEGER_TYPE)
10374 && validate_arg (arg1, REAL_TYPE))
10375 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10376 &dconst0, false);
10377 break;
ea91f957
KG
10378
10379 CASE_FLT_FN (BUILT_IN_DREM):
10380 CASE_FLT_FN (BUILT_IN_REMAINDER):
10381 if (validate_arg (arg0, REAL_TYPE)
10382 && validate_arg(arg1, REAL_TYPE))
10383 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10384 break;
752b7d38
KG
10385
10386 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10387 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10388 if (validate_arg (arg0, REAL_TYPE)
10389 && validate_arg(arg1, POINTER_TYPE))
10390 return do_mpfr_lgamma_r (arg0, arg1, type);
10391 break;
5039610b
SL
10392
10393 CASE_FLT_FN (BUILT_IN_ATAN2):
10394 if (validate_arg (arg0, REAL_TYPE)
10395 && validate_arg(arg1, REAL_TYPE))
10396 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10397 break;
10398
10399 CASE_FLT_FN (BUILT_IN_FDIM):
10400 if (validate_arg (arg0, REAL_TYPE)
10401 && validate_arg(arg1, REAL_TYPE))
10402 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10403 break;
10404
10405 CASE_FLT_FN (BUILT_IN_HYPOT):
db3927fb 10406 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
5039610b 10407
a41d064d
KG
10408#ifdef HAVE_mpc_pow
10409 CASE_FLT_FN (BUILT_IN_CPOW):
10410 if (validate_arg (arg0, COMPLEX_TYPE)
10411 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10412 && validate_arg (arg1, COMPLEX_TYPE)
b8698a0f 10413 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
ca75b926 10414 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
a41d064d
KG
10415 break;
10416#endif
10417
2b5e5642 10418 CASE_FLT_FN (BUILT_IN_LDEXP):
db3927fb 10419 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
2b5e5642
KG
10420 CASE_FLT_FN (BUILT_IN_SCALBN):
10421 CASE_FLT_FN (BUILT_IN_SCALBLN):
db3927fb
AH
10422 return fold_builtin_load_exponent (loc, arg0, arg1,
10423 type, /*ldexp=*/false);
2b5e5642 10424
7a2a25ab 10425 CASE_FLT_FN (BUILT_IN_FREXP):
db3927fb 10426 return fold_builtin_frexp (loc, arg0, arg1, type);
7a2a25ab 10427
3d577eaf 10428 CASE_FLT_FN (BUILT_IN_MODF):
db3927fb 10429 return fold_builtin_modf (loc, arg0, arg1, type);
3d577eaf 10430
5039610b 10431 case BUILT_IN_BZERO:
db3927fb 10432 return fold_builtin_bzero (loc, arg0, arg1, ignore);
5039610b
SL
10433
10434 case BUILT_IN_FPUTS:
db3927fb 10435 return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
5039610b
SL
10436
10437 case BUILT_IN_FPUTS_UNLOCKED:
db3927fb 10438 return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
5039610b
SL
10439
10440 case BUILT_IN_STRSTR:
db3927fb 10441 return fold_builtin_strstr (loc, arg0, arg1, type);
5039610b
SL
10442
10443 case BUILT_IN_STRCAT:
db3927fb 10444 return fold_builtin_strcat (loc, arg0, arg1);
5039610b
SL
10445
10446 case BUILT_IN_STRSPN:
db3927fb 10447 return fold_builtin_strspn (loc, arg0, arg1);
5039610b
SL
10448
10449 case BUILT_IN_STRCSPN:
db3927fb 10450 return fold_builtin_strcspn (loc, arg0, arg1);
5039610b
SL
10451
10452 case BUILT_IN_STRCHR:
10453 case BUILT_IN_INDEX:
db3927fb 10454 return fold_builtin_strchr (loc, arg0, arg1, type);
5039610b
SL
10455
10456 case BUILT_IN_STRRCHR:
10457 case BUILT_IN_RINDEX:
db3927fb 10458 return fold_builtin_strrchr (loc, arg0, arg1, type);
5039610b
SL
10459
10460 case BUILT_IN_STRCPY:
db3927fb 10461 return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
5039610b 10462
0d2a6e08
JJ
10463 case BUILT_IN_STPCPY:
10464 if (ignore)
10465 {
10466 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10467 if (!fn)
10468 break;
10469
db3927fb 10470 return build_call_expr_loc (loc, fn, 2, arg0, arg1);
0d2a6e08 10471 }
44e10129
MM
10472 else
10473 return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
0d2a6e08
JJ
10474 break;
10475
5039610b 10476 case BUILT_IN_STRCMP:
db3927fb 10477 return fold_builtin_strcmp (loc, arg0, arg1);
5039610b
SL
10478
10479 case BUILT_IN_STRPBRK:
db3927fb 10480 return fold_builtin_strpbrk (loc, arg0, arg1, type);
5039610b
SL
10481
10482 case BUILT_IN_EXPECT:
db3927fb 10483 return fold_builtin_expect (loc, arg0, arg1);
5039610b
SL
10484
10485 CASE_FLT_FN (BUILT_IN_POW):
db3927fb 10486 return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
5039610b
SL
10487
10488 CASE_FLT_FN (BUILT_IN_POWI):
db3927fb 10489 return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
5039610b
SL
10490
10491 CASE_FLT_FN (BUILT_IN_COPYSIGN):
db3927fb 10492 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
5039610b
SL
10493
10494 CASE_FLT_FN (BUILT_IN_FMIN):
db3927fb 10495 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
5039610b
SL
10496
10497 CASE_FLT_FN (BUILT_IN_FMAX):
db3927fb 10498 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
64a9295a 10499
08039bd8 10500 case BUILT_IN_ISGREATER:
db3927fb
AH
10501 return fold_builtin_unordered_cmp (loc, fndecl,
10502 arg0, arg1, UNLE_EXPR, LE_EXPR);
08039bd8 10503 case BUILT_IN_ISGREATEREQUAL:
db3927fb
AH
10504 return fold_builtin_unordered_cmp (loc, fndecl,
10505 arg0, arg1, UNLT_EXPR, LT_EXPR);
08039bd8 10506 case BUILT_IN_ISLESS:
db3927fb
AH
10507 return fold_builtin_unordered_cmp (loc, fndecl,
10508 arg0, arg1, UNGE_EXPR, GE_EXPR);
08039bd8 10509 case BUILT_IN_ISLESSEQUAL:
db3927fb
AH
10510 return fold_builtin_unordered_cmp (loc, fndecl,
10511 arg0, arg1, UNGT_EXPR, GT_EXPR);
08039bd8 10512 case BUILT_IN_ISLESSGREATER:
db3927fb
AH
10513 return fold_builtin_unordered_cmp (loc, fndecl,
10514 arg0, arg1, UNEQ_EXPR, EQ_EXPR);
08039bd8 10515 case BUILT_IN_ISUNORDERED:
db3927fb
AH
10516 return fold_builtin_unordered_cmp (loc, fndecl,
10517 arg0, arg1, UNORDERED_EXPR,
a35da91f 10518 NOP_EXPR);
08039bd8 10519
d3147f64
EC
10520 /* We do the folding for va_start in the expander. */
10521 case BUILT_IN_VA_START:
10522 break;
a32e70c3 10523
5039610b 10524 case BUILT_IN_SPRINTF:
db3927fb 10525 return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
5039610b 10526
10a0d495 10527 case BUILT_IN_OBJECT_SIZE:
5039610b 10528 return fold_builtin_object_size (arg0, arg1);
10a0d495
JJ
10529
10530 case BUILT_IN_PRINTF:
10531 case BUILT_IN_PRINTF_UNLOCKED:
10532 case BUILT_IN_VPRINTF:
db3927fb 10533 return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
5039610b 10534
10a0d495
JJ
10535 case BUILT_IN_PRINTF_CHK:
10536 case BUILT_IN_VPRINTF_CHK:
5039610b
SL
10537 if (!validate_arg (arg0, INTEGER_TYPE)
10538 || TREE_SIDE_EFFECTS (arg0))
10539 return NULL_TREE;
10540 else
db3927fb
AH
10541 return fold_builtin_printf (loc, fndecl,
10542 arg1, NULL_TREE, ignore, fcode);
5039610b 10543 break;
10a0d495
JJ
10544
10545 case BUILT_IN_FPRINTF:
10546 case BUILT_IN_FPRINTF_UNLOCKED:
10547 case BUILT_IN_VFPRINTF:
db3927fb 10548 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
5039610b
SL
10549 ignore, fcode);
10550
10551 default:
10552 break;
10553 }
10554 return NULL_TREE;
10555}
10556
10557/* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10558 and ARG2. IGNORE is true if the result of the function call is ignored.
10559 This function returns NULL_TREE if no simplification was possible. */
10560
10561static tree
db3927fb
AH
10562fold_builtin_3 (location_t loc, tree fndecl,
10563 tree arg0, tree arg1, tree arg2, bool ignore)
5039610b
SL
10564{
10565 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10566 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10567 switch (fcode)
10568 {
10569
10570 CASE_FLT_FN (BUILT_IN_SINCOS):
db3927fb 10571 return fold_builtin_sincos (loc, arg0, arg1, arg2);
5039610b
SL
10572
10573 CASE_FLT_FN (BUILT_IN_FMA):
10574 if (validate_arg (arg0, REAL_TYPE)
10575 && validate_arg(arg1, REAL_TYPE)
10576 && validate_arg(arg2, REAL_TYPE))
10577 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10578 break;
10579
ea91f957
KG
10580 CASE_FLT_FN (BUILT_IN_REMQUO):
10581 if (validate_arg (arg0, REAL_TYPE)
10582 && validate_arg(arg1, REAL_TYPE)
10583 && validate_arg(arg2, POINTER_TYPE))
10584 return do_mpfr_remquo (arg0, arg1, arg2);
10585 break;
ea91f957 10586
5039610b 10587 case BUILT_IN_MEMSET:
db3927fb 10588 return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
5039610b
SL
10589
10590 case BUILT_IN_BCOPY:
db3927fb
AH
10591 return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10592 void_type_node, true, /*endp=*/3);
5039610b
SL
10593
10594 case BUILT_IN_MEMCPY:
db3927fb
AH
10595 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10596 type, ignore, /*endp=*/0);
5039610b
SL
10597
10598 case BUILT_IN_MEMPCPY:
db3927fb
AH
10599 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10600 type, ignore, /*endp=*/1);
5039610b
SL
10601
10602 case BUILT_IN_MEMMOVE:
db3927fb
AH
10603 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10604 type, ignore, /*endp=*/3);
5039610b
SL
10605
10606 case BUILT_IN_STRNCAT:
db3927fb 10607 return fold_builtin_strncat (loc, arg0, arg1, arg2);
5039610b
SL
10608
10609 case BUILT_IN_STRNCPY:
db3927fb 10610 return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
5039610b
SL
10611
10612 case BUILT_IN_STRNCMP:
db3927fb 10613 return fold_builtin_strncmp (loc, arg0, arg1, arg2);
5039610b 10614
2a5fce6d 10615 case BUILT_IN_MEMCHR:
db3927fb 10616 return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
2a5fce6d 10617
5039610b
SL
10618 case BUILT_IN_BCMP:
10619 case BUILT_IN_MEMCMP:
db3927fb 10620 return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
5039610b
SL
10621
10622 case BUILT_IN_SPRINTF:
db3927fb 10623 return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
5039610b
SL
10624
10625 case BUILT_IN_STRCPY_CHK:
10626 case BUILT_IN_STPCPY_CHK:
db3927fb 10627 return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
5039610b
SL
10628 ignore, fcode);
10629
10630 case BUILT_IN_STRCAT_CHK:
db3927fb 10631 return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
5039610b
SL
10632
10633 case BUILT_IN_PRINTF_CHK:
10634 case BUILT_IN_VPRINTF_CHK:
10635 if (!validate_arg (arg0, INTEGER_TYPE)
10636 || TREE_SIDE_EFFECTS (arg0))
10637 return NULL_TREE;
10638 else
db3927fb 10639 return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
5039610b
SL
10640 break;
10641
10642 case BUILT_IN_FPRINTF:
10643 case BUILT_IN_FPRINTF_UNLOCKED:
10644 case BUILT_IN_VFPRINTF:
db3927fb
AH
10645 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10646 ignore, fcode);
5039610b 10647
10a0d495
JJ
10648 case BUILT_IN_FPRINTF_CHK:
10649 case BUILT_IN_VFPRINTF_CHK:
5039610b
SL
10650 if (!validate_arg (arg1, INTEGER_TYPE)
10651 || TREE_SIDE_EFFECTS (arg1))
10652 return NULL_TREE;
10653 else
db3927fb 10654 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
5039610b 10655 ignore, fcode);
10a0d495 10656
b0b3afb2
BS
10657 default:
10658 break;
10659 }
5039610b
SL
10660 return NULL_TREE;
10661}
b0b3afb2 10662
5039610b
SL
10663/* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10664 ARG2, and ARG3. IGNORE is true if the result of the function call is
10665 ignored. This function returns NULL_TREE if no simplification was
10666 possible. */
b8698a0f 10667
5039610b 10668static tree
db3927fb
AH
10669fold_builtin_4 (location_t loc, tree fndecl,
10670 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
5039610b
SL
10671{
10672 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10673
10674 switch (fcode)
10675 {
10676 case BUILT_IN_MEMCPY_CHK:
10677 case BUILT_IN_MEMPCPY_CHK:
10678 case BUILT_IN_MEMMOVE_CHK:
10679 case BUILT_IN_MEMSET_CHK:
db3927fb 10680 return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
5039610b
SL
10681 NULL_TREE, ignore,
10682 DECL_FUNCTION_CODE (fndecl));
10683
10684 case BUILT_IN_STRNCPY_CHK:
db3927fb 10685 return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE);
5039610b
SL
10686
10687 case BUILT_IN_STRNCAT_CHK:
db3927fb 10688 return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
5039610b
SL
10689
10690 case BUILT_IN_FPRINTF_CHK:
10691 case BUILT_IN_VFPRINTF_CHK:
10692 if (!validate_arg (arg1, INTEGER_TYPE)
10693 || TREE_SIDE_EFFECTS (arg1))
10694 return NULL_TREE;
10695 else
db3927fb 10696 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
5039610b
SL
10697 ignore, fcode);
10698 break;
10699
10700 default:
10701 break;
10702 }
10703 return NULL_TREE;
10704}
10705
10706/* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
10707 arguments, where NARGS <= 4. IGNORE is true if the result of the
10708 function call is ignored. This function returns NULL_TREE if no
10709 simplification was possible. Note that this only folds builtins with
10710 fixed argument patterns. Foldings that do varargs-to-varargs
10711 transformations, or that match calls with more than 4 arguments,
10712 need to be handled with fold_builtin_varargs instead. */
b8698a0f 10713
5039610b 10714#define MAX_ARGS_TO_FOLD_BUILTIN 4
b8698a0f 10715
5039610b 10716static tree
db3927fb 10717fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
5039610b
SL
10718{
10719 tree ret = NULL_TREE;
f4577fcd 10720
5039610b
SL
10721 switch (nargs)
10722 {
10723 case 0:
db3927fb 10724 ret = fold_builtin_0 (loc, fndecl, ignore);
5039610b
SL
10725 break;
10726 case 1:
db3927fb 10727 ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
5039610b
SL
10728 break;
10729 case 2:
db3927fb 10730 ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
5039610b
SL
10731 break;
10732 case 3:
db3927fb 10733 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
5039610b
SL
10734 break;
10735 case 4:
db3927fb 10736 ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
5039610b
SL
10737 ignore);
10738 break;
10739 default:
10740 break;
10741 }
10742 if (ret)
10743 {
726a989a 10744 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
db3927fb 10745 SET_EXPR_LOCATION (ret, loc);
5039610b
SL
10746 TREE_NO_WARNING (ret) = 1;
10747 return ret;
10748 }
10749 return NULL_TREE;
10750}
10751
10752/* Builtins with folding operations that operate on "..." arguments
10753 need special handling; we need to store the arguments in a convenient
10754 data structure before attempting any folding. Fortunately there are
10755 only a few builtins that fall into this category. FNDECL is the
10756 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10757 result of the function call is ignored. */
10758
10759static tree
db3927fb
AH
10760fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
10761 bool ignore ATTRIBUTE_UNUSED)
5039610b
SL
10762{
10763 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10764 tree ret = NULL_TREE;
10765
10766 switch (fcode)
10767 {
10768 case BUILT_IN_SPRINTF_CHK:
10769 case BUILT_IN_VSPRINTF_CHK:
db3927fb 10770 ret = fold_builtin_sprintf_chk (loc, exp, fcode);
5039610b
SL
10771 break;
10772
10773 case BUILT_IN_SNPRINTF_CHK:
10774 case BUILT_IN_VSNPRINTF_CHK:
db3927fb 10775 ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
3bf5906b
KG
10776 break;
10777
10778 case BUILT_IN_FPCLASSIFY:
db3927fb 10779 ret = fold_builtin_fpclassify (loc, exp);
3bf5906b 10780 break;
5039610b
SL
10781
10782 default:
10783 break;
10784 }
10785 if (ret)
10786 {
10787 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
db3927fb 10788 SET_EXPR_LOCATION (ret, loc);
5039610b
SL
10789 TREE_NO_WARNING (ret) = 1;
10790 return ret;
10791 }
10792 return NULL_TREE;
b0b3afb2 10793}
6385a28f 10794
0889e9bc
JJ
10795/* Return true if FNDECL shouldn't be folded right now.
10796 If a built-in function has an inline attribute always_inline
10797 wrapper, defer folding it after always_inline functions have
10798 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
10799 might not be performed. */
10800
10801static bool
10802avoid_folding_inline_builtin (tree fndecl)
10803{
10804 return (DECL_DECLARED_INLINE_P (fndecl)
10805 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
10806 && cfun
10807 && !cfun->always_inline_functions_inlined
10808 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
10809}
10810
6de9cd9a 10811/* A wrapper function for builtin folding that prevents warnings for
caf93cb0 10812 "statement without effect" and the like, caused by removing the
6de9cd9a
DN
10813 call node earlier than the warning is generated. */
10814
10815tree
db3927fb 10816fold_call_expr (location_t loc, tree exp, bool ignore)
6de9cd9a 10817{
5039610b
SL
10818 tree ret = NULL_TREE;
10819 tree fndecl = get_callee_fndecl (exp);
10820 if (fndecl
10821 && TREE_CODE (fndecl) == FUNCTION_DECL
6ef5231b
JJ
10822 && DECL_BUILT_IN (fndecl)
10823 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10824 yet. Defer folding until we see all the arguments
10825 (after inlining). */
10826 && !CALL_EXPR_VA_ARG_PACK (exp))
10827 {
10828 int nargs = call_expr_nargs (exp);
10829
10830 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10831 instead last argument is __builtin_va_arg_pack (). Defer folding
10832 even in that case, until arguments are finalized. */
10833 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10834 {
10835 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10836 if (fndecl2
10837 && TREE_CODE (fndecl2) == FUNCTION_DECL
10838 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10839 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10840 return NULL_TREE;
10841 }
10842
0889e9bc
JJ
10843 if (avoid_folding_inline_builtin (fndecl))
10844 return NULL_TREE;
10845
5039610b
SL
10846 /* FIXME: Don't use a list in this interface. */
10847 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10848 return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10849 else
10850 {
5039610b
SL
10851 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10852 {
10853 tree *args = CALL_EXPR_ARGP (exp);
db3927fb 10854 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
5039610b
SL
10855 }
10856 if (!ret)
db3927fb 10857 ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
5039610b 10858 if (ret)
db3927fb 10859 return ret;
5039610b 10860 }
6de9cd9a 10861 }
5039610b
SL
10862 return NULL_TREE;
10863}
b8698a0f 10864
5039610b
SL
10865/* Conveniently construct a function call expression. FNDECL names the
10866 function to be called and ARGLIST is a TREE_LIST of arguments. */
b8698a0f 10867
5039610b 10868tree
db3927fb 10869build_function_call_expr (location_t loc, tree fndecl, tree arglist)
5039610b
SL
10870{
10871 tree fntype = TREE_TYPE (fndecl);
10872 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
94a0dd7b
SL
10873 int n = list_length (arglist);
10874 tree *argarray = (tree *) alloca (n * sizeof (tree));
10875 int i;
db3927fb 10876
94a0dd7b
SL
10877 for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10878 argarray[i] = TREE_VALUE (arglist);
db3927fb 10879 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
5039610b
SL
10880}
10881
10882/* Conveniently construct a function call expression. FNDECL names the
10883 function to be called, N is the number of arguments, and the "..."
10884 parameters are the argument expressions. */
b8698a0f 10885
5039610b 10886tree
db3927fb 10887build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
5039610b
SL
10888{
10889 va_list ap;
5039610b
SL
10890 tree fntype = TREE_TYPE (fndecl);
10891 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
94a0dd7b
SL
10892 tree *argarray = (tree *) alloca (n * sizeof (tree));
10893 int i;
5039610b
SL
10894
10895 va_start (ap, n);
94a0dd7b
SL
10896 for (i = 0; i < n; i++)
10897 argarray[i] = va_arg (ap, tree);
5039610b 10898 va_end (ap);
db3927fb 10899 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
6de9cd9a
DN
10900}
10901
5039610b 10902/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
94a0dd7b 10903 N arguments are passed in the array ARGARRAY. */
4977bab6
ZW
10904
10905tree
db3927fb 10906fold_builtin_call_array (location_t loc, tree type,
94a0dd7b
SL
10907 tree fn,
10908 int n,
10909 tree *argarray)
6385a28f 10910{
5039610b
SL
10911 tree ret = NULL_TREE;
10912 int i;
10913 tree exp;
10914
10915 if (TREE_CODE (fn) == ADDR_EXPR)
10916 {
10917 tree fndecl = TREE_OPERAND (fn, 0);
10918 if (TREE_CODE (fndecl) == FUNCTION_DECL
10919 && DECL_BUILT_IN (fndecl))
10920 {
6ef5231b
JJ
10921 /* If last argument is __builtin_va_arg_pack (), arguments to this
10922 function are not finalized yet. Defer folding until they are. */
10923 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10924 {
10925 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10926 if (fndecl2
10927 && TREE_CODE (fndecl2) == FUNCTION_DECL
10928 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10929 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
db3927fb 10930 return build_call_array_loc (loc, type, fn, n, argarray);
6ef5231b 10931 }
0889e9bc 10932 if (avoid_folding_inline_builtin (fndecl))
db3927fb 10933 return build_call_array_loc (loc, type, fn, n, argarray);
5039610b
SL
10934 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10935 {
10936 tree arglist = NULL_TREE;
94a0dd7b
SL
10937 for (i = n - 1; i >= 0; i--)
10938 arglist = tree_cons (NULL_TREE, argarray[i], arglist);
5039610b
SL
10939 ret = targetm.fold_builtin (fndecl, arglist, false);
10940 if (ret)
10941 return ret;
db3927fb 10942 return build_call_array_loc (loc, type, fn, n, argarray);
5039610b
SL
10943 }
10944 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10945 {
10946 /* First try the transformations that don't require consing up
10947 an exp. */
db3927fb 10948 ret = fold_builtin_n (loc, fndecl, argarray, n, false);
5039610b
SL
10949 if (ret)
10950 return ret;
10951 }
10952
10953 /* If we got this far, we need to build an exp. */
db3927fb
AH
10954 exp = build_call_array_loc (loc, type, fn, n, argarray);
10955 ret = fold_builtin_varargs (loc, fndecl, exp, false);
5039610b
SL
10956 return ret ? ret : exp;
10957 }
10958 }
10959
db3927fb 10960 return build_call_array_loc (loc, type, fn, n, argarray);
5039610b
SL
10961}
10962
10963/* Construct a new CALL_EXPR using the tail of the argument list of EXP
10964 along with N new arguments specified as the "..." parameters. SKIP
10965 is the number of arguments in EXP to be omitted. This function is used
10966 to do varargs-to-varargs transformations. */
10967
10968static tree
db3927fb 10969rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
5039610b
SL
10970{
10971 int oldnargs = call_expr_nargs (exp);
10972 int nargs = oldnargs - skip + n;
10973 tree fntype = TREE_TYPE (fndecl);
10974 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10975 tree *buffer;
10976
10977 if (n > 0)
10978 {
10979 int i, j;
10980 va_list ap;
6385a28f 10981
f883e0a7 10982 buffer = XALLOCAVEC (tree, nargs);
5039610b
SL
10983 va_start (ap, n);
10984 for (i = 0; i < n; i++)
10985 buffer[i] = va_arg (ap, tree);
10986 va_end (ap);
10987 for (j = skip; j < oldnargs; j++, i++)
10988 buffer[i] = CALL_EXPR_ARG (exp, j);
10989 }
b8698a0f 10990 else
5039610b
SL
10991 buffer = CALL_EXPR_ARGP (exp) + skip;
10992
db3927fb 10993 return fold (build_call_array_loc (loc, TREE_TYPE (exp), fn, nargs, buffer));
5039610b
SL
10994}
10995
10996/* Validate a single argument ARG against a tree code CODE representing
10997 a type. */
b8698a0f 10998
5039610b 10999static bool
fa233e34 11000validate_arg (const_tree arg, enum tree_code code)
5039610b
SL
11001{
11002 if (!arg)
11003 return false;
11004 else if (code == POINTER_TYPE)
11005 return POINTER_TYPE_P (TREE_TYPE (arg));
4cd8e76f
RG
11006 else if (code == INTEGER_TYPE)
11007 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
5039610b 11008 return code == TREE_CODE (TREE_TYPE (arg));
6385a28f 11009}
019fa094 11010
726a989a
RB
11011/* This function validates the types of a function call argument list
11012 against a specified list of tree_codes. If the last specifier is a 0,
11013 that represents an ellipses, otherwise the last specifier must be a
11014 VOID_TYPE.
11015
11016 This is the GIMPLE version of validate_arglist. Eventually we want to
11017 completely convert builtins.c to work from GIMPLEs and the tree based
11018 validate_arglist will then be removed. */
11019
11020bool
11021validate_gimple_arglist (const_gimple call, ...)
11022{
11023 enum tree_code code;
11024 bool res = 0;
11025 va_list ap;
11026 const_tree arg;
11027 size_t i;
11028
11029 va_start (ap, call);
11030 i = 0;
11031
11032 do
11033 {
72b5577d 11034 code = (enum tree_code) va_arg (ap, int);
726a989a
RB
11035 switch (code)
11036 {
11037 case 0:
11038 /* This signifies an ellipses, any further arguments are all ok. */
11039 res = true;
11040 goto end;
11041 case VOID_TYPE:
11042 /* This signifies an endlink, if no arguments remain, return
11043 true, otherwise return false. */
11044 res = (i == gimple_call_num_args (call));
11045 goto end;
11046 default:
11047 /* If no parameters remain or the parameter's code does not
11048 match the specified code, return false. Otherwise continue
11049 checking any remaining arguments. */
11050 arg = gimple_call_arg (call, i++);
11051 if (!validate_arg (arg, code))
11052 goto end;
11053 break;
11054 }
11055 }
11056 while (1);
11057
11058 /* We need gotos here since we can only have one VA_CLOSE in a
11059 function. */
11060 end: ;
11061 va_end (ap);
11062
11063 return res;
11064}
11065
019fa094 11066/* This function validates the types of a function call argument list
5039610b
SL
11067 against a specified list of tree_codes. If the last specifier is a 0,
11068 that represents an ellipses, otherwise the last specifier must be a
11069 VOID_TYPE. */
5197bd50 11070
5039610b 11071bool
fa233e34 11072validate_arglist (const_tree callexpr, ...)
019fa094 11073{
019fa094 11074 enum tree_code code;
5039610b 11075 bool res = 0;
e34d07f2 11076 va_list ap;
fa233e34
KG
11077 const_call_expr_arg_iterator iter;
11078 const_tree arg;
4682ae04 11079
5039610b 11080 va_start (ap, callexpr);
fa233e34 11081 init_const_call_expr_arg_iterator (callexpr, &iter);
019fa094 11082
5ab2f7b7 11083 do
019fa094 11084 {
72b5577d 11085 code = (enum tree_code) va_arg (ap, int);
5ab2f7b7
KH
11086 switch (code)
11087 {
11088 case 0:
11089 /* This signifies an ellipses, any further arguments are all ok. */
5039610b 11090 res = true;
5ab2f7b7
KH
11091 goto end;
11092 case VOID_TYPE:
11093 /* This signifies an endlink, if no arguments remain, return
11094 true, otherwise return false. */
fa233e34 11095 res = !more_const_call_expr_args_p (&iter);
5ab2f7b7
KH
11096 goto end;
11097 default:
11098 /* If no parameters remain or the parameter's code does not
11099 match the specified code, return false. Otherwise continue
11100 checking any remaining arguments. */
fa233e34 11101 arg = next_const_call_expr_arg (&iter);
5039610b 11102 if (!validate_arg (arg, code))
5ab2f7b7
KH
11103 goto end;
11104 break;
11105 }
019fa094 11106 }
5ab2f7b7 11107 while (1);
7a75edb7
AJ
11108
11109 /* We need gotos here since we can only have one VA_CLOSE in a
11110 function. */
11111 end: ;
e34d07f2 11112 va_end (ap);
7a75edb7
AJ
11113
11114 return res;
019fa094 11115}
f6155fda 11116
f6155fda
SS
11117/* Default target-specific builtin expander that does nothing. */
11118
11119rtx
4682ae04
AJ
11120default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11121 rtx target ATTRIBUTE_UNUSED,
11122 rtx subtarget ATTRIBUTE_UNUSED,
11123 enum machine_mode mode ATTRIBUTE_UNUSED,
11124 int ignore ATTRIBUTE_UNUSED)
f6155fda
SS
11125{
11126 return NULL_RTX;
11127}
34ee7f82 11128
7dc61d6c
KG
11129/* Returns true is EXP represents data that would potentially reside
11130 in a readonly section. */
11131
11132static bool
11133readonly_data_expr (tree exp)
11134{
11135 STRIP_NOPS (exp);
11136
aef0afc4
UW
11137 if (TREE_CODE (exp) != ADDR_EXPR)
11138 return false;
11139
11140 exp = get_base_address (TREE_OPERAND (exp, 0));
11141 if (!exp)
11142 return false;
11143
11144 /* Make sure we call decl_readonly_section only for trees it
11145 can handle (since it returns true for everything it doesn't
11146 understand). */
caf93cb0 11147 if (TREE_CODE (exp) == STRING_CST
aef0afc4
UW
11148 || TREE_CODE (exp) == CONSTRUCTOR
11149 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11150 return decl_readonly_section (exp, 0);
7dc61d6c
KG
11151 else
11152 return false;
11153}
6de9cd9a 11154
5039610b
SL
11155/* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11156 to the call, and TYPE is its return type.
6de9cd9a 11157
5039610b 11158 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11159 simplified form of the call as a tree.
11160
11161 The simplified form may be a constant or other expression which
11162 computes the same value, but in a more efficient manner (including
11163 calls to other builtin functions).
11164
11165 The call may contain arguments which need to be evaluated, but
11166 which are not useful to determine the result of the call. In
11167 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11168 COMPOUND_EXPR will be an argument which must be evaluated.
11169 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11170 COMPOUND_EXPR in the chain will contain the tree for the simplified
11171 form of the builtin function call. */
11172
11173static tree
db3927fb 11174fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
6de9cd9a 11175{
5039610b
SL
11176 if (!validate_arg (s1, POINTER_TYPE)
11177 || !validate_arg (s2, POINTER_TYPE))
11178 return NULL_TREE;
6de9cd9a
DN
11179 else
11180 {
6de9cd9a
DN
11181 tree fn;
11182 const char *p1, *p2;
11183
11184 p2 = c_getstr (s2);
11185 if (p2 == NULL)
5039610b 11186 return NULL_TREE;
6de9cd9a
DN
11187
11188 p1 = c_getstr (s1);
11189 if (p1 != NULL)
11190 {
11191 const char *r = strstr (p1, p2);
5fcfe0b2 11192 tree tem;
6de9cd9a 11193
6de9cd9a 11194 if (r == NULL)
5212068f 11195 return build_int_cst (TREE_TYPE (s1), 0);
b953ebd6
RS
11196
11197 /* Return an offset into the constant string argument. */
db3927fb 11198 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
5be014d5 11199 s1, size_int (r - p1));
db3927fb 11200 return fold_convert_loc (loc, type, tem);
6de9cd9a
DN
11201 }
11202
817f9ef2
JW
11203 /* The argument is const char *, and the result is char *, so we need
11204 a type conversion here to avoid a warning. */
6de9cd9a 11205 if (p2[0] == '\0')
db3927fb 11206 return fold_convert_loc (loc, type, s1);
6de9cd9a
DN
11207
11208 if (p2[1] != '\0')
5039610b 11209 return NULL_TREE;
6de9cd9a
DN
11210
11211 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11212 if (!fn)
5039610b 11213 return NULL_TREE;
6de9cd9a
DN
11214
11215 /* New argument list transforming strstr(s1, s2) to
11216 strchr(s1, s2[0]). */
db3927fb 11217 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
6de9cd9a
DN
11218 }
11219}
11220
5039610b
SL
11221/* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11222 the call, and TYPE is its return type.
6de9cd9a 11223
5039610b 11224 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11225 simplified form of the call as a tree.
11226
11227 The simplified form may be a constant or other expression which
11228 computes the same value, but in a more efficient manner (including
11229 calls to other builtin functions).
11230
11231 The call may contain arguments which need to be evaluated, but
11232 which are not useful to determine the result of the call. In
11233 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11234 COMPOUND_EXPR will be an argument which must be evaluated.
11235 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11236 COMPOUND_EXPR in the chain will contain the tree for the simplified
11237 form of the builtin function call. */
11238
11239static tree
db3927fb 11240fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
6de9cd9a 11241{
5039610b
SL
11242 if (!validate_arg (s1, POINTER_TYPE)
11243 || !validate_arg (s2, INTEGER_TYPE))
11244 return NULL_TREE;
6de9cd9a
DN
11245 else
11246 {
6de9cd9a
DN
11247 const char *p1;
11248
11249 if (TREE_CODE (s2) != INTEGER_CST)
5039610b 11250 return NULL_TREE;
6de9cd9a
DN
11251
11252 p1 = c_getstr (s1);
11253 if (p1 != NULL)
11254 {
11255 char c;
11256 const char *r;
5fcfe0b2 11257 tree tem;
6de9cd9a
DN
11258
11259 if (target_char_cast (s2, &c))
5039610b 11260 return NULL_TREE;
6de9cd9a
DN
11261
11262 r = strchr (p1, c);
11263
11264 if (r == NULL)
5212068f 11265 return build_int_cst (TREE_TYPE (s1), 0);
6de9cd9a
DN
11266
11267 /* Return an offset into the constant string argument. */
db3927fb 11268 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
5be014d5 11269 s1, size_int (r - p1));
db3927fb 11270 return fold_convert_loc (loc, type, tem);
6de9cd9a 11271 }
5039610b 11272 return NULL_TREE;
6de9cd9a
DN
11273 }
11274}
11275
5039610b
SL
11276/* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11277 the call, and TYPE is its return type.
6de9cd9a 11278
5039610b 11279 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11280 simplified form of the call as a tree.
11281
11282 The simplified form may be a constant or other expression which
11283 computes the same value, but in a more efficient manner (including
11284 calls to other builtin functions).
11285
11286 The call may contain arguments which need to be evaluated, but
11287 which are not useful to determine the result of the call. In
11288 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11289 COMPOUND_EXPR will be an argument which must be evaluated.
11290 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11291 COMPOUND_EXPR in the chain will contain the tree for the simplified
11292 form of the builtin function call. */
11293
11294static tree
db3927fb 11295fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
6de9cd9a 11296{
5039610b
SL
11297 if (!validate_arg (s1, POINTER_TYPE)
11298 || !validate_arg (s2, INTEGER_TYPE))
11299 return NULL_TREE;
6de9cd9a
DN
11300 else
11301 {
6de9cd9a
DN
11302 tree fn;
11303 const char *p1;
11304
11305 if (TREE_CODE (s2) != INTEGER_CST)
5039610b 11306 return NULL_TREE;
6de9cd9a
DN
11307
11308 p1 = c_getstr (s1);
11309 if (p1 != NULL)
11310 {
11311 char c;
11312 const char *r;
5fcfe0b2 11313 tree tem;
6de9cd9a
DN
11314
11315 if (target_char_cast (s2, &c))
5039610b 11316 return NULL_TREE;
6de9cd9a
DN
11317
11318 r = strrchr (p1, c);
11319
11320 if (r == NULL)
5212068f 11321 return build_int_cst (TREE_TYPE (s1), 0);
6de9cd9a
DN
11322
11323 /* Return an offset into the constant string argument. */
db3927fb 11324 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
5be014d5 11325 s1, size_int (r - p1));
db3927fb 11326 return fold_convert_loc (loc, type, tem);
6de9cd9a
DN
11327 }
11328
11329 if (! integer_zerop (s2))
5039610b 11330 return NULL_TREE;
6de9cd9a
DN
11331
11332 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11333 if (!fn)
5039610b 11334 return NULL_TREE;
6de9cd9a
DN
11335
11336 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
db3927fb 11337 return build_call_expr_loc (loc, fn, 2, s1, s2);
6de9cd9a
DN
11338 }
11339}
11340
5039610b
SL
11341/* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11342 to the call, and TYPE is its return type.
6de9cd9a 11343
5039610b 11344 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11345 simplified form of the call as a tree.
11346
11347 The simplified form may be a constant or other expression which
11348 computes the same value, but in a more efficient manner (including
11349 calls to other builtin functions).
11350
11351 The call may contain arguments which need to be evaluated, but
11352 which are not useful to determine the result of the call. In
11353 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11354 COMPOUND_EXPR will be an argument which must be evaluated.
11355 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11356 COMPOUND_EXPR in the chain will contain the tree for the simplified
11357 form of the builtin function call. */
11358
11359static tree
db3927fb 11360fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
6de9cd9a 11361{
5039610b
SL
11362 if (!validate_arg (s1, POINTER_TYPE)
11363 || !validate_arg (s2, POINTER_TYPE))
11364 return NULL_TREE;
6de9cd9a
DN
11365 else
11366 {
6de9cd9a
DN
11367 tree fn;
11368 const char *p1, *p2;
11369
11370 p2 = c_getstr (s2);
11371 if (p2 == NULL)
5039610b 11372 return NULL_TREE;
6de9cd9a
DN
11373
11374 p1 = c_getstr (s1);
11375 if (p1 != NULL)
11376 {
11377 const char *r = strpbrk (p1, p2);
5fcfe0b2 11378 tree tem;
6de9cd9a
DN
11379
11380 if (r == NULL)
5212068f 11381 return build_int_cst (TREE_TYPE (s1), 0);
6de9cd9a
DN
11382
11383 /* Return an offset into the constant string argument. */
db3927fb 11384 tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
5be014d5 11385 s1, size_int (r - p1));
db3927fb 11386 return fold_convert_loc (loc, type, tem);
6de9cd9a
DN
11387 }
11388
11389 if (p2[0] == '\0')
d6dc556b
RS
11390 /* strpbrk(x, "") == NULL.
11391 Evaluate and ignore s1 in case it had side-effects. */
db3927fb 11392 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
6de9cd9a
DN
11393
11394 if (p2[1] != '\0')
5039610b 11395 return NULL_TREE; /* Really call strpbrk. */
6de9cd9a
DN
11396
11397 fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11398 if (!fn)
5039610b 11399 return NULL_TREE;
6de9cd9a
DN
11400
11401 /* New argument list transforming strpbrk(s1, s2) to
11402 strchr(s1, s2[0]). */
db3927fb 11403 return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
6de9cd9a
DN
11404 }
11405}
11406
5039610b
SL
11407/* Simplify a call to the strcat builtin. DST and SRC are the arguments
11408 to the call.
6de9cd9a 11409
5039610b 11410 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11411 simplified form of the call as a tree.
11412
11413 The simplified form may be a constant or other expression which
11414 computes the same value, but in a more efficient manner (including
11415 calls to other builtin functions).
11416
11417 The call may contain arguments which need to be evaluated, but
11418 which are not useful to determine the result of the call. In
11419 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11420 COMPOUND_EXPR will be an argument which must be evaluated.
11421 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11422 COMPOUND_EXPR in the chain will contain the tree for the simplified
11423 form of the builtin function call. */
11424
11425static tree
db3927fb 11426fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
6de9cd9a 11427{
5039610b
SL
11428 if (!validate_arg (dst, POINTER_TYPE)
11429 || !validate_arg (src, POINTER_TYPE))
11430 return NULL_TREE;
6de9cd9a
DN
11431 else
11432 {
6de9cd9a
DN
11433 const char *p = c_getstr (src);
11434
11435 /* If the string length is zero, return the dst parameter. */
11436 if (p && *p == '\0')
11437 return dst;
11438
44e10129
MM
11439 if (optimize_insn_for_speed_p ())
11440 {
11441 /* See if we can store by pieces into (dst + strlen(dst)). */
11442 tree newdst, call;
11443 tree strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11444 tree strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11445
11446 if (!strlen_fn || !strcpy_fn)
11447 return NULL_TREE;
11448
11449 /* If we don't have a movstr we don't want to emit an strcpy
11450 call. We have to do that if the length of the source string
11451 isn't computable (in that case we can use memcpy probably
b8698a0f 11452 later expanding to a sequence of mov instructions). If we
44e10129
MM
11453 have movstr instructions we can emit strcpy calls. */
11454 if (!HAVE_movstr)
11455 {
11456 tree len = c_strlen (src, 1);
11457 if (! len || TREE_SIDE_EFFECTS (len))
11458 return NULL_TREE;
11459 }
11460
11461 /* Stabilize the argument list. */
11462 dst = builtin_save_expr (dst);
11463
11464 /* Create strlen (dst). */
11465 newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11466 /* Create (dst p+ strlen (dst)). */
11467
11468 newdst = fold_build2_loc (loc, POINTER_PLUS_EXPR,
11469 TREE_TYPE (dst), dst, newdst);
11470 newdst = builtin_save_expr (newdst);
11471
11472 call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11473 return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11474 }
5039610b 11475 return NULL_TREE;
6de9cd9a
DN
11476 }
11477}
11478
5039610b
SL
11479/* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11480 arguments to the call.
6de9cd9a 11481
5039610b 11482 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11483 simplified form of the call as a tree.
11484
11485 The simplified form may be a constant or other expression which
11486 computes the same value, but in a more efficient manner (including
11487 calls to other builtin functions).
11488
11489 The call may contain arguments which need to be evaluated, but
11490 which are not useful to determine the result of the call. In
11491 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11492 COMPOUND_EXPR will be an argument which must be evaluated.
11493 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11494 COMPOUND_EXPR in the chain will contain the tree for the simplified
11495 form of the builtin function call. */
11496
11497static tree
db3927fb 11498fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
6de9cd9a 11499{
5039610b
SL
11500 if (!validate_arg (dst, POINTER_TYPE)
11501 || !validate_arg (src, POINTER_TYPE)
11502 || !validate_arg (len, INTEGER_TYPE))
11503 return NULL_TREE;
6de9cd9a
DN
11504 else
11505 {
6de9cd9a
DN
11506 const char *p = c_getstr (src);
11507
11508 /* If the requested length is zero, or the src parameter string
10a0d495 11509 length is zero, return the dst parameter. */
6de9cd9a 11510 if (integer_zerop (len) || (p && *p == '\0'))
db3927fb 11511 return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
6de9cd9a
DN
11512
11513 /* If the requested len is greater than or equal to the string
c22cacf3 11514 length, call strcat. */
6de9cd9a
DN
11515 if (TREE_CODE (len) == INTEGER_CST && p
11516 && compare_tree_int (len, strlen (p)) >= 0)
11517 {
6de9cd9a
DN
11518 tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11519
11520 /* If the replacement _DECL isn't initialized, don't do the
11521 transformation. */
11522 if (!fn)
5039610b 11523 return NULL_TREE;
6de9cd9a 11524
db3927fb 11525 return build_call_expr_loc (loc, fn, 2, dst, src);
6de9cd9a 11526 }
5039610b 11527 return NULL_TREE;
6de9cd9a
DN
11528 }
11529}
11530
5039610b
SL
11531/* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11532 to the call.
6de9cd9a 11533
5039610b 11534 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11535 simplified form of the call as a tree.
11536
11537 The simplified form may be a constant or other expression which
11538 computes the same value, but in a more efficient manner (including
11539 calls to other builtin functions).
11540
11541 The call may contain arguments which need to be evaluated, but
11542 which are not useful to determine the result of the call. In
11543 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11544 COMPOUND_EXPR will be an argument which must be evaluated.
11545 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11546 COMPOUND_EXPR in the chain will contain the tree for the simplified
11547 form of the builtin function call. */
11548
11549static tree
db3927fb 11550fold_builtin_strspn (location_t loc, tree s1, tree s2)
6de9cd9a 11551{
5039610b
SL
11552 if (!validate_arg (s1, POINTER_TYPE)
11553 || !validate_arg (s2, POINTER_TYPE))
11554 return NULL_TREE;
6de9cd9a
DN
11555 else
11556 {
6de9cd9a
DN
11557 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11558
11559 /* If both arguments are constants, evaluate at compile-time. */
11560 if (p1 && p2)
11561 {
11562 const size_t r = strspn (p1, p2);
11563 return size_int (r);
11564 }
11565
5039610b 11566 /* If either argument is "", return NULL_TREE. */
6de9cd9a 11567 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
08039bd8
RS
11568 /* Evaluate and ignore both arguments in case either one has
11569 side-effects. */
db3927fb 11570 return omit_two_operands_loc (loc, size_type_node, size_zero_node,
08039bd8 11571 s1, s2);
5039610b 11572 return NULL_TREE;
6de9cd9a
DN
11573 }
11574}
11575
5039610b
SL
11576/* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11577 to the call.
6de9cd9a 11578
5039610b 11579 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11580 simplified form of the call as a tree.
11581
11582 The simplified form may be a constant or other expression which
11583 computes the same value, but in a more efficient manner (including
11584 calls to other builtin functions).
11585
11586 The call may contain arguments which need to be evaluated, but
11587 which are not useful to determine the result of the call. In
11588 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11589 COMPOUND_EXPR will be an argument which must be evaluated.
11590 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11591 COMPOUND_EXPR in the chain will contain the tree for the simplified
11592 form of the builtin function call. */
11593
11594static tree
db3927fb 11595fold_builtin_strcspn (location_t loc, tree s1, tree s2)
6de9cd9a 11596{
5039610b
SL
11597 if (!validate_arg (s1, POINTER_TYPE)
11598 || !validate_arg (s2, POINTER_TYPE))
11599 return NULL_TREE;
6de9cd9a
DN
11600 else
11601 {
6de9cd9a
DN
11602 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11603
11604 /* If both arguments are constants, evaluate at compile-time. */
11605 if (p1 && p2)
11606 {
11607 const size_t r = strcspn (p1, p2);
11608 return size_int (r);
11609 }
11610
5039610b 11611 /* If the first argument is "", return NULL_TREE. */
6de9cd9a
DN
11612 if (p1 && *p1 == '\0')
11613 {
11614 /* Evaluate and ignore argument s2 in case it has
11615 side-effects. */
db3927fb 11616 return omit_one_operand_loc (loc, size_type_node,
002bd9f0 11617 size_zero_node, s2);
6de9cd9a
DN
11618 }
11619
11620 /* If the second argument is "", return __builtin_strlen(s1). */
11621 if (p2 && *p2 == '\0')
11622 {
5039610b 11623 tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
6de9cd9a
DN
11624
11625 /* If the replacement _DECL isn't initialized, don't do the
11626 transformation. */
11627 if (!fn)
5039610b 11628 return NULL_TREE;
6de9cd9a 11629
db3927fb 11630 return build_call_expr_loc (loc, fn, 1, s1);
6de9cd9a 11631 }
5039610b 11632 return NULL_TREE;
6de9cd9a
DN
11633 }
11634}
11635
5039610b
SL
11636/* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11637 to the call. IGNORE is true if the value returned
a32e70c3
RS
11638 by the builtin will be ignored. UNLOCKED is true is true if this
11639 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11640 the known length of the string. Return NULL_TREE if no simplification
11641 was possible. */
6de9cd9a
DN
11642
11643tree
db3927fb
AH
11644fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11645 bool ignore, bool unlocked, tree len)
6de9cd9a 11646{
7e7b53aa
KG
11647 /* If we're using an unlocked function, assume the other unlocked
11648 functions exist explicitly. */
11649 tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
6de9cd9a 11650 : implicit_built_in_decls[BUILT_IN_FPUTC];
7e7b53aa 11651 tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
6de9cd9a
DN
11652 : implicit_built_in_decls[BUILT_IN_FWRITE];
11653
625a3439
KG
11654 /* If the return value is used, don't do the transformation. */
11655 if (!ignore)
5039610b 11656 return NULL_TREE;
6de9cd9a
DN
11657
11658 /* Verify the arguments in the original call. */
5039610b
SL
11659 if (!validate_arg (arg0, POINTER_TYPE)
11660 || !validate_arg (arg1, POINTER_TYPE))
11661 return NULL_TREE;
6de9cd9a 11662
a32e70c3 11663 if (! len)
5039610b 11664 len = c_strlen (arg0, 0);
6de9cd9a
DN
11665
11666 /* Get the length of the string passed to fputs. If the length
11667 can't be determined, punt. */
11668 if (!len
11669 || TREE_CODE (len) != INTEGER_CST)
5039610b 11670 return NULL_TREE;
6de9cd9a
DN
11671
11672 switch (compare_tree_int (len, 1))
11673 {
11674 case -1: /* length is 0, delete the call entirely . */
db3927fb
AH
11675 return omit_one_operand_loc (loc, integer_type_node,
11676 integer_zero_node, arg1);;
d6dc556b 11677
6de9cd9a
DN
11678 case 0: /* length is 1, call fputc. */
11679 {
5039610b 11680 const char *p = c_getstr (arg0);
6de9cd9a
DN
11681
11682 if (p != NULL)
11683 {
5039610b 11684 if (fn_fputc)
db3927fb 11685 return build_call_expr_loc (loc, fn_fputc, 2,
5039610b
SL
11686 build_int_cst (NULL_TREE, p[0]), arg1);
11687 else
11688 return NULL_TREE;
6de9cd9a
DN
11689 }
11690 }
11691 /* FALLTHROUGH */
11692 case 1: /* length is greater than 1, call fwrite. */
11693 {
9cf737f8 11694 /* If optimizing for size keep fputs. */
efd8f750 11695 if (optimize_function_for_size_p (cfun))
5039610b 11696 return NULL_TREE;
6de9cd9a
DN
11697 /* New argument list transforming fputs(string, stream) to
11698 fwrite(string, 1, len, stream). */
5039610b 11699 if (fn_fwrite)
db3927fb
AH
11700 return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
11701 size_one_node, len, arg1);
5039610b
SL
11702 else
11703 return NULL_TREE;
6de9cd9a
DN
11704 }
11705 default:
298e6adc 11706 gcc_unreachable ();
6de9cd9a 11707 }
5039610b 11708 return NULL_TREE;
6de9cd9a
DN
11709}
11710
5039610b 11711/* Fold the next_arg or va_start call EXP. Returns true if there was an error
2efcfa4e
AP
11712 produced. False otherwise. This is done so that we don't output the error
11713 or warning twice or three times. */
726a989a 11714
2efcfa4e 11715bool
5039610b 11716fold_builtin_next_arg (tree exp, bool va_start_p)
6de9cd9a
DN
11717{
11718 tree fntype = TREE_TYPE (current_function_decl);
5039610b
SL
11719 int nargs = call_expr_nargs (exp);
11720 tree arg;
6de9cd9a
DN
11721
11722 if (TYPE_ARG_TYPES (fntype) == 0
11723 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11724 == void_type_node))
2efcfa4e
AP
11725 {
11726 error ("%<va_start%> used in function with fixed args");
11727 return true;
11728 }
5039610b
SL
11729
11730 if (va_start_p)
8870e212 11731 {
5039610b
SL
11732 if (va_start_p && (nargs != 2))
11733 {
11734 error ("wrong number of arguments to function %<va_start%>");
11735 return true;
11736 }
11737 arg = CALL_EXPR_ARG (exp, 1);
8870e212
JJ
11738 }
11739 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11740 when we checked the arguments and if needed issued a warning. */
5039610b 11741 else
6de9cd9a 11742 {
5039610b
SL
11743 if (nargs == 0)
11744 {
11745 /* Evidently an out of date version of <stdarg.h>; can't validate
11746 va_start's second argument, but can still work as intended. */
11747 warning (0, "%<__builtin_next_arg%> called without an argument");
11748 return true;
11749 }
11750 else if (nargs > 1)
c22cacf3 11751 {
5039610b 11752 error ("wrong number of arguments to function %<__builtin_next_arg%>");
c22cacf3
MS
11753 return true;
11754 }
5039610b
SL
11755 arg = CALL_EXPR_ARG (exp, 0);
11756 }
11757
4e3825db
MM
11758 if (TREE_CODE (arg) == SSA_NAME)
11759 arg = SSA_NAME_VAR (arg);
11760
5039610b 11761 /* We destructively modify the call to be __builtin_va_start (ap, 0)
b8698a0f 11762 or __builtin_next_arg (0) the first time we see it, after checking
5039610b
SL
11763 the arguments and if needed issuing a warning. */
11764 if (!integer_zerop (arg))
11765 {
11766 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8870e212 11767
6de9cd9a
DN
11768 /* Strip off all nops for the sake of the comparison. This
11769 is not quite the same as STRIP_NOPS. It does more.
11770 We must also strip off INDIRECT_EXPR for C++ reference
11771 parameters. */
1043771b 11772 while (CONVERT_EXPR_P (arg)
6de9cd9a
DN
11773 || TREE_CODE (arg) == INDIRECT_REF)
11774 arg = TREE_OPERAND (arg, 0);
11775 if (arg != last_parm)
c22cacf3 11776 {
118f3b19
KH
11777 /* FIXME: Sometimes with the tree optimizers we can get the
11778 not the last argument even though the user used the last
11779 argument. We just warn and set the arg to be the last
11780 argument so that we will get wrong-code because of
11781 it. */
d4ee4d25 11782 warning (0, "second parameter of %<va_start%> not last named argument");
2efcfa4e 11783 }
2985f531
MLI
11784
11785 /* Undefined by C99 7.15.1.4p4 (va_start):
11786 "If the parameter parmN is declared with the register storage
11787 class, with a function or array type, or with a type that is
11788 not compatible with the type that results after application of
11789 the default argument promotions, the behavior is undefined."
11790 */
11791 else if (DECL_REGISTER (arg))
11792 warning (0, "undefined behaviour when second parameter of "
11793 "%<va_start%> is declared with %<register%> storage");
11794
8870e212 11795 /* We want to verify the second parameter just once before the tree
c22cacf3
MS
11796 optimizers are run and then avoid keeping it in the tree,
11797 as otherwise we could warn even for correct code like:
11798 void foo (int i, ...)
11799 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
5039610b
SL
11800 if (va_start_p)
11801 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11802 else
11803 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
2efcfa4e
AP
11804 }
11805 return false;
6de9cd9a
DN
11806}
11807
11808
5039610b
SL
11809/* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11810 ORIG may be null if this is a 2-argument call. We don't attempt to
11811 simplify calls with more than 3 arguments.
6de9cd9a 11812
5039610b 11813 Return NULL_TREE if no simplification was possible, otherwise return the
6de9cd9a
DN
11814 simplified form of the call as a tree. If IGNORED is true, it means that
11815 the caller does not use the returned value of the function. */
11816
11817static tree
db3927fb
AH
11818fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
11819 tree orig, int ignored)
6de9cd9a 11820{
5039610b 11821 tree call, retval;
6de9cd9a
DN
11822 const char *fmt_str = NULL;
11823
11824 /* Verify the required arguments in the original call. We deal with two
11825 types of sprintf() calls: 'sprintf (str, fmt)' and
11826 'sprintf (dest, "%s", orig)'. */
5039610b
SL
11827 if (!validate_arg (dest, POINTER_TYPE)
11828 || !validate_arg (fmt, POINTER_TYPE))
11829 return NULL_TREE;
11830 if (orig && !validate_arg (orig, POINTER_TYPE))
6de9cd9a 11831 return NULL_TREE;
6de9cd9a
DN
11832
11833 /* Check whether the format is a literal string constant. */
11834 fmt_str = c_getstr (fmt);
11835 if (fmt_str == NULL)
11836 return NULL_TREE;
11837
11838 call = NULL_TREE;
11839 retval = NULL_TREE;
11840
62e5bf5d 11841 if (!init_target_chars ())
5039610b 11842 return NULL_TREE;
000ba23d 11843
6de9cd9a 11844 /* If the format doesn't contain % args or %%, use strcpy. */
000ba23d 11845 if (strchr (fmt_str, target_percent) == NULL)
6de9cd9a
DN
11846 {
11847 tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11848
11849 if (!fn)
11850 return NULL_TREE;
11851
6b01cd54 11852 /* Don't optimize sprintf (buf, "abc", ptr++). */
5039610b 11853 if (orig)
6b01cd54
JJ
11854 return NULL_TREE;
11855
6de9cd9a
DN
11856 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11857 'format' is known to contain no % formats. */
db3927fb 11858 call = build_call_expr_loc (loc, fn, 2, dest, fmt);
6de9cd9a 11859 if (!ignored)
7d60be94 11860 retval = build_int_cst (NULL_TREE, strlen (fmt_str));
6de9cd9a
DN
11861 }
11862
11863 /* If the format is "%s", use strcpy if the result isn't used. */
000ba23d 11864 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
6de9cd9a 11865 {
5039610b 11866 tree fn;
6de9cd9a
DN
11867 fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11868
11869 if (!fn)
11870 return NULL_TREE;
11871
6b01cd54 11872 /* Don't crash on sprintf (str1, "%s"). */
5039610b 11873 if (!orig)
6b01cd54
JJ
11874 return NULL_TREE;
11875
6de9cd9a 11876 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
6de9cd9a
DN
11877 if (!ignored)
11878 {
11879 retval = c_strlen (orig, 1);
11880 if (!retval || TREE_CODE (retval) != INTEGER_CST)
11881 return NULL_TREE;
11882 }
db3927fb 11883 call = build_call_expr_loc (loc, fn, 2, dest, orig);
6de9cd9a
DN
11884 }
11885
11886 if (call && retval)
11887 {
db3927fb
AH
11888 retval = fold_convert_loc
11889 (loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
6de9cd9a 11890 retval);
d6dc556b 11891 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
6de9cd9a
DN
11892 }
11893 else
11894 return call;
11895}
10a0d495 11896
5039610b 11897/* Expand a call EXP to __builtin_object_size. */
10a0d495
JJ
11898
11899rtx
11900expand_builtin_object_size (tree exp)
11901{
11902 tree ost;
11903 int object_size_type;
11904 tree fndecl = get_callee_fndecl (exp);
10a0d495 11905
5039610b 11906 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10a0d495 11907 {
c94ed7a1
JJ
11908 error ("%Kfirst argument of %D must be a pointer, second integer constant",
11909 exp, fndecl);
10a0d495
JJ
11910 expand_builtin_trap ();
11911 return const0_rtx;
11912 }
11913
5039610b 11914 ost = CALL_EXPR_ARG (exp, 1);
10a0d495
JJ
11915 STRIP_NOPS (ost);
11916
11917 if (TREE_CODE (ost) != INTEGER_CST
11918 || tree_int_cst_sgn (ost) < 0
11919 || compare_tree_int (ost, 3) > 0)
11920 {
c94ed7a1
JJ
11921 error ("%Klast argument of %D is not integer constant between 0 and 3",
11922 exp, fndecl);
10a0d495
JJ
11923 expand_builtin_trap ();
11924 return const0_rtx;
11925 }
11926
11927 object_size_type = tree_low_cst (ost, 0);
11928
11929 return object_size_type < 2 ? constm1_rtx : const0_rtx;
11930}
11931
11932/* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11933 FCODE is the BUILT_IN_* to use.
5039610b 11934 Return NULL_RTX if we failed; the caller should emit a normal call,
10a0d495
JJ
11935 otherwise try to get the result in TARGET, if convenient (and in
11936 mode MODE if that's convenient). */
11937
11938static rtx
11939expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11940 enum built_in_function fcode)
11941{
10a0d495
JJ
11942 tree dest, src, len, size;
11943
5039610b 11944 if (!validate_arglist (exp,
10a0d495
JJ
11945 POINTER_TYPE,
11946 fcode == BUILT_IN_MEMSET_CHK
11947 ? INTEGER_TYPE : POINTER_TYPE,
11948 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
5039610b 11949 return NULL_RTX;
10a0d495 11950
5039610b
SL
11951 dest = CALL_EXPR_ARG (exp, 0);
11952 src = CALL_EXPR_ARG (exp, 1);
11953 len = CALL_EXPR_ARG (exp, 2);
11954 size = CALL_EXPR_ARG (exp, 3);
10a0d495
JJ
11955
11956 if (! host_integerp (size, 1))
5039610b 11957 return NULL_RTX;
10a0d495
JJ
11958
11959 if (host_integerp (len, 1) || integer_all_onesp (size))
11960 {
11961 tree fn;
11962
11963 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11964 {
9bd9f738
RG
11965 warning_at (tree_nonartificial_location (exp),
11966 0, "%Kcall to %D will always overflow destination buffer",
11967 exp, get_callee_fndecl (exp));
5039610b 11968 return NULL_RTX;
10a0d495
JJ
11969 }
11970
10a0d495
JJ
11971 fn = NULL_TREE;
11972 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11973 mem{cpy,pcpy,move,set} is available. */
11974 switch (fcode)
11975 {
11976 case BUILT_IN_MEMCPY_CHK:
11977 fn = built_in_decls[BUILT_IN_MEMCPY];
11978 break;
11979 case BUILT_IN_MEMPCPY_CHK:
11980 fn = built_in_decls[BUILT_IN_MEMPCPY];
11981 break;
11982 case BUILT_IN_MEMMOVE_CHK:
11983 fn = built_in_decls[BUILT_IN_MEMMOVE];
11984 break;
11985 case BUILT_IN_MEMSET_CHK:
11986 fn = built_in_decls[BUILT_IN_MEMSET];
11987 break;
11988 default:
11989 break;
11990 }
11991
11992 if (! fn)
5039610b 11993 return NULL_RTX;
10a0d495 11994
44e10129
MM
11995 fn = build_call_nofold (fn, 3, dest, src, len);
11996 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
11997 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10a0d495
JJ
11998 return expand_expr (fn, target, mode, EXPAND_NORMAL);
11999 }
12000 else if (fcode == BUILT_IN_MEMSET_CHK)
5039610b 12001 return NULL_RTX;
10a0d495
JJ
12002 else
12003 {
12004 unsigned int dest_align
12005 = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12006
12007 /* If DEST is not a pointer type, call the normal function. */
12008 if (dest_align == 0)
5039610b 12009 return NULL_RTX;
10a0d495
JJ
12010
12011 /* If SRC and DEST are the same (and not volatile), do nothing. */
12012 if (operand_equal_p (src, dest, 0))
12013 {
12014 tree expr;
12015
12016 if (fcode != BUILT_IN_MEMPCPY_CHK)
12017 {
12018 /* Evaluate and ignore LEN in case it has side-effects. */
12019 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12020 return expand_expr (dest, target, mode, EXPAND_NORMAL);
12021 }
12022
5be014d5 12023 expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
10a0d495
JJ
12024 return expand_expr (expr, target, mode, EXPAND_NORMAL);
12025 }
12026
12027 /* __memmove_chk special case. */
12028 if (fcode == BUILT_IN_MEMMOVE_CHK)
12029 {
12030 unsigned int src_align
12031 = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12032
12033 if (src_align == 0)
5039610b 12034 return NULL_RTX;
10a0d495
JJ
12035
12036 /* If src is categorized for a readonly section we can use
12037 normal __memcpy_chk. */
12038 if (readonly_data_expr (src))
12039 {
12040 tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12041 if (!fn)
5039610b 12042 return NULL_RTX;
44e10129
MM
12043 fn = build_call_nofold (fn, 4, dest, src, len, size);
12044 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12045 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10a0d495
JJ
12046 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12047 }
12048 }
5039610b 12049 return NULL_RTX;
10a0d495
JJ
12050 }
12051}
12052
12053/* Emit warning if a buffer overflow is detected at compile time. */
12054
12055static void
12056maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12057{
5039610b 12058 int is_strlen = 0;
10a0d495 12059 tree len, size;
9bd9f738 12060 location_t loc = tree_nonartificial_location (exp);
10a0d495
JJ
12061
12062 switch (fcode)
12063 {
12064 case BUILT_IN_STRCPY_CHK:
12065 case BUILT_IN_STPCPY_CHK:
12066 /* For __strcat_chk the warning will be emitted only if overflowing
12067 by at least strlen (dest) + 1 bytes. */
12068 case BUILT_IN_STRCAT_CHK:
5039610b
SL
12069 len = CALL_EXPR_ARG (exp, 1);
12070 size = CALL_EXPR_ARG (exp, 2);
10a0d495
JJ
12071 is_strlen = 1;
12072 break;
1c2fc017 12073 case BUILT_IN_STRNCAT_CHK:
10a0d495 12074 case BUILT_IN_STRNCPY_CHK:
5039610b
SL
12075 len = CALL_EXPR_ARG (exp, 2);
12076 size = CALL_EXPR_ARG (exp, 3);
10a0d495
JJ
12077 break;
12078 case BUILT_IN_SNPRINTF_CHK:
12079 case BUILT_IN_VSNPRINTF_CHK:
5039610b
SL
12080 len = CALL_EXPR_ARG (exp, 1);
12081 size = CALL_EXPR_ARG (exp, 3);
10a0d495
JJ
12082 break;
12083 default:
12084 gcc_unreachable ();
12085 }
12086
10a0d495
JJ
12087 if (!len || !size)
12088 return;
12089
10a0d495
JJ
12090 if (! host_integerp (size, 1) || integer_all_onesp (size))
12091 return;
12092
12093 if (is_strlen)
12094 {
12095 len = c_strlen (len, 1);
12096 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12097 return;
12098 }
1c2fc017
JJ
12099 else if (fcode == BUILT_IN_STRNCAT_CHK)
12100 {
5039610b 12101 tree src = CALL_EXPR_ARG (exp, 1);
1c2fc017
JJ
12102 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12103 return;
12104 src = c_strlen (src, 1);
12105 if (! src || ! host_integerp (src, 1))
12106 {
9bd9f738
RG
12107 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12108 exp, get_callee_fndecl (exp));
1c2fc017
JJ
12109 return;
12110 }
12111 else if (tree_int_cst_lt (src, size))
12112 return;
12113 }
10a0d495
JJ
12114 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12115 return;
12116
9bd9f738
RG
12117 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12118 exp, get_callee_fndecl (exp));
10a0d495
JJ
12119}
12120
12121/* Emit warning if a buffer overflow is detected at compile time
12122 in __sprintf_chk/__vsprintf_chk calls. */
12123
12124static void
12125maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12126{
451409e4 12127 tree size, len, fmt;
10a0d495 12128 const char *fmt_str;
5039610b 12129 int nargs = call_expr_nargs (exp);
10a0d495
JJ
12130
12131 /* Verify the required arguments in the original call. */
b8698a0f 12132
5039610b 12133 if (nargs < 4)
10a0d495 12134 return;
5039610b
SL
12135 size = CALL_EXPR_ARG (exp, 2);
12136 fmt = CALL_EXPR_ARG (exp, 3);
10a0d495
JJ
12137
12138 if (! host_integerp (size, 1) || integer_all_onesp (size))
12139 return;
12140
12141 /* Check whether the format is a literal string constant. */
12142 fmt_str = c_getstr (fmt);
12143 if (fmt_str == NULL)
12144 return;
12145
62e5bf5d 12146 if (!init_target_chars ())
000ba23d
KG
12147 return;
12148
10a0d495 12149 /* If the format doesn't contain % args or %%, we know its size. */
000ba23d 12150 if (strchr (fmt_str, target_percent) == 0)
10a0d495
JJ
12151 len = build_int_cstu (size_type_node, strlen (fmt_str));
12152 /* If the format is "%s" and first ... argument is a string literal,
12153 we know it too. */
5039610b
SL
12154 else if (fcode == BUILT_IN_SPRINTF_CHK
12155 && strcmp (fmt_str, target_percent_s) == 0)
10a0d495
JJ
12156 {
12157 tree arg;
12158
5039610b 12159 if (nargs < 5)
10a0d495 12160 return;
5039610b 12161 arg = CALL_EXPR_ARG (exp, 4);
10a0d495
JJ
12162 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12163 return;
12164
12165 len = c_strlen (arg, 1);
12166 if (!len || ! host_integerp (len, 1))
12167 return;
12168 }
12169 else
12170 return;
12171
12172 if (! tree_int_cst_lt (len, size))
9bd9f738
RG
12173 warning_at (tree_nonartificial_location (exp),
12174 0, "%Kcall to %D will always overflow destination buffer",
12175 exp, get_callee_fndecl (exp));
10a0d495
JJ
12176}
12177
f9555f40
JJ
12178/* Emit warning if a free is called with address of a variable. */
12179
12180static void
12181maybe_emit_free_warning (tree exp)
12182{
12183 tree arg = CALL_EXPR_ARG (exp, 0);
12184
12185 STRIP_NOPS (arg);
12186 if (TREE_CODE (arg) != ADDR_EXPR)
12187 return;
12188
12189 arg = get_base_address (TREE_OPERAND (arg, 0));
12190 if (arg == NULL || INDIRECT_REF_P (arg))
12191 return;
12192
12193 if (SSA_VAR_P (arg))
9bd9f738
RG
12194 warning_at (tree_nonartificial_location (exp),
12195 0, "%Kattempt to free a non-heap object %qD", exp, arg);
f9555f40 12196 else
9bd9f738
RG
12197 warning_at (tree_nonartificial_location (exp),
12198 0, "%Kattempt to free a non-heap object", exp);
f9555f40
JJ
12199}
12200
5039610b
SL
12201/* Fold a call to __builtin_object_size with arguments PTR and OST,
12202 if possible. */
10a0d495
JJ
12203
12204tree
5039610b 12205fold_builtin_object_size (tree ptr, tree ost)
10a0d495 12206{
5039610b 12207 tree ret = NULL_TREE;
10a0d495
JJ
12208 int object_size_type;
12209
5039610b
SL
12210 if (!validate_arg (ptr, POINTER_TYPE)
12211 || !validate_arg (ost, INTEGER_TYPE))
12212 return NULL_TREE;
10a0d495 12213
10a0d495
JJ
12214 STRIP_NOPS (ost);
12215
12216 if (TREE_CODE (ost) != INTEGER_CST
12217 || tree_int_cst_sgn (ost) < 0
12218 || compare_tree_int (ost, 3) > 0)
5039610b 12219 return NULL_TREE;
10a0d495
JJ
12220
12221 object_size_type = tree_low_cst (ost, 0);
12222
12223 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12224 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12225 and (size_t) 0 for types 2 and 3. */
12226 if (TREE_SIDE_EFFECTS (ptr))
2ac7cbb5 12227 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
10a0d495
JJ
12228
12229 if (TREE_CODE (ptr) == ADDR_EXPR)
12230 ret = build_int_cstu (size_type_node,
2ac7cbb5 12231 compute_builtin_object_size (ptr, object_size_type));
10a0d495
JJ
12232
12233 else if (TREE_CODE (ptr) == SSA_NAME)
12234 {
12235 unsigned HOST_WIDE_INT bytes;
12236
12237 /* If object size is not known yet, delay folding until
12238 later. Maybe subsequent passes will help determining
12239 it. */
12240 bytes = compute_builtin_object_size (ptr, object_size_type);
12241 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12242 ? -1 : 0))
12243 ret = build_int_cstu (size_type_node, bytes);
12244 }
12245
12246 if (ret)
12247 {
2ac7cbb5
RG
12248 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12249 HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12250 if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12251 ret = NULL_TREE;
10a0d495
JJ
12252 }
12253
12254 return ret;
12255}
12256
12257/* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
5039610b 12258 DEST, SRC, LEN, and SIZE are the arguments to the call.
10a0d495
JJ
12259 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12260 code of the builtin. If MAXLEN is not NULL, it is maximum length
12261 passed as third argument. */
12262
12263tree
db3927fb 12264fold_builtin_memory_chk (location_t loc, tree fndecl,
5039610b
SL
12265 tree dest, tree src, tree len, tree size,
12266 tree maxlen, bool ignore,
10a0d495
JJ
12267 enum built_in_function fcode)
12268{
5039610b 12269 tree fn;
10a0d495 12270
5039610b
SL
12271 if (!validate_arg (dest, POINTER_TYPE)
12272 || !validate_arg (src,
12273 (fcode == BUILT_IN_MEMSET_CHK
12274 ? INTEGER_TYPE : POINTER_TYPE))
12275 || !validate_arg (len, INTEGER_TYPE)
12276 || !validate_arg (size, INTEGER_TYPE))
12277 return NULL_TREE;
10a0d495
JJ
12278
12279 /* If SRC and DEST are the same (and not volatile), return DEST
12280 (resp. DEST+LEN for __mempcpy_chk). */
12281 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12282 {
12283 if (fcode != BUILT_IN_MEMPCPY_CHK)
db3927fb
AH
12284 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12285 dest, len);
10a0d495
JJ
12286 else
12287 {
db3927fb
AH
12288 tree temp = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest),
12289 dest, len);
12290 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
10a0d495
JJ
12291 }
12292 }
12293
12294 if (! host_integerp (size, 1))
5039610b 12295 return NULL_TREE;
10a0d495
JJ
12296
12297 if (! integer_all_onesp (size))
12298 {
12299 if (! host_integerp (len, 1))
12300 {
12301 /* If LEN is not constant, try MAXLEN too.
12302 For MAXLEN only allow optimizing into non-_ocs function
12303 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12304 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12305 {
12306 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12307 {
12308 /* (void) __mempcpy_chk () can be optimized into
12309 (void) __memcpy_chk (). */
12310 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12311 if (!fn)
5039610b 12312 return NULL_TREE;
10a0d495 12313
db3927fb 12314 return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
10a0d495 12315 }
5039610b 12316 return NULL_TREE;
10a0d495 12317 }
10a0d495 12318 }
f28d3046
JJ
12319 else
12320 maxlen = len;
10a0d495 12321
f28d3046 12322 if (tree_int_cst_lt (size, maxlen))
5039610b 12323 return NULL_TREE;
10a0d495
JJ
12324 }
12325
10a0d495
JJ
12326 fn = NULL_TREE;
12327 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12328 mem{cpy,pcpy,move,set} is available. */
12329 switch (fcode)
12330 {
12331 case BUILT_IN_MEMCPY_CHK:
12332 fn = built_in_decls[BUILT_IN_MEMCPY];
12333 break;
12334 case BUILT_IN_MEMPCPY_CHK:
12335 fn = built_in_decls[BUILT_IN_MEMPCPY];
12336 break;
12337 case BUILT_IN_MEMMOVE_CHK:
12338 fn = built_in_decls[BUILT_IN_MEMMOVE];
12339 break;
12340 case BUILT_IN_MEMSET_CHK:
12341 fn = built_in_decls[BUILT_IN_MEMSET];
12342 break;
12343 default:
12344 break;
12345 }
12346
12347 if (!fn)
5039610b 12348 return NULL_TREE;
10a0d495 12349
db3927fb 12350 return build_call_expr_loc (loc, fn, 3, dest, src, len);
10a0d495
JJ
12351}
12352
12353/* Fold a call to the __st[rp]cpy_chk builtin.
5039610b
SL
12354 DEST, SRC, and SIZE are the arguments to the call.
12355 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
10a0d495
JJ
12356 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12357 strings passed as second argument. */
12358
12359tree
db3927fb
AH
12360fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12361 tree src, tree size,
5039610b 12362 tree maxlen, bool ignore,
10a0d495
JJ
12363 enum built_in_function fcode)
12364{
5039610b 12365 tree len, fn;
10a0d495 12366
5039610b
SL
12367 if (!validate_arg (dest, POINTER_TYPE)
12368 || !validate_arg (src, POINTER_TYPE)
12369 || !validate_arg (size, INTEGER_TYPE))
12370 return NULL_TREE;
10a0d495
JJ
12371
12372 /* If SRC and DEST are the same (and not volatile), return DEST. */
12373 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
db3927fb 12374 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
c22cacf3 12375
10a0d495 12376 if (! host_integerp (size, 1))
5039610b 12377 return NULL_TREE;
10a0d495
JJ
12378
12379 if (! integer_all_onesp (size))
12380 {
12381 len = c_strlen (src, 1);
12382 if (! len || ! host_integerp (len, 1))
12383 {
12384 /* If LEN is not constant, try MAXLEN too.
12385 For MAXLEN only allow optimizing into non-_ocs function
12386 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12387 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12388 {
12389 if (fcode == BUILT_IN_STPCPY_CHK)
12390 {
12391 if (! ignore)
5039610b 12392 return NULL_TREE;
10a0d495
JJ
12393
12394 /* If return value of __stpcpy_chk is ignored,
12395 optimize into __strcpy_chk. */
12396 fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12397 if (!fn)
5039610b 12398 return NULL_TREE;
10a0d495 12399
db3927fb 12400 return build_call_expr_loc (loc, fn, 3, dest, src, size);
10a0d495
JJ
12401 }
12402
12403 if (! len || TREE_SIDE_EFFECTS (len))
5039610b 12404 return NULL_TREE;
10a0d495
JJ
12405
12406 /* If c_strlen returned something, but not a constant,
12407 transform __strcpy_chk into __memcpy_chk. */
12408 fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12409 if (!fn)
5039610b 12410 return NULL_TREE;
10a0d495 12411
db3927fb
AH
12412 len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
12413 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12414 build_call_expr_loc (loc, fn, 4,
12415 dest, src, len, size));
10a0d495 12416 }
10a0d495 12417 }
f28d3046
JJ
12418 else
12419 maxlen = len;
12420
12421 if (! tree_int_cst_lt (maxlen, size))
5039610b 12422 return NULL_TREE;
10a0d495
JJ
12423 }
12424
10a0d495
JJ
12425 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12426 fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12427 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12428 if (!fn)
5039610b 12429 return NULL_TREE;
10a0d495 12430
db3927fb 12431 return build_call_expr_loc (loc, fn, 2, dest, src);
10a0d495
JJ
12432}
12433
5039610b
SL
12434/* Fold a call to the __strncpy_chk builtin. DEST, SRC, LEN, and SIZE
12435 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12436 length passed as third argument. */
10a0d495
JJ
12437
12438tree
db3927fb
AH
12439fold_builtin_strncpy_chk (location_t loc, tree dest, tree src,
12440 tree len, tree size, tree maxlen)
10a0d495 12441{
5039610b 12442 tree fn;
10a0d495 12443
5039610b
SL
12444 if (!validate_arg (dest, POINTER_TYPE)
12445 || !validate_arg (src, POINTER_TYPE)
12446 || !validate_arg (len, INTEGER_TYPE)
12447 || !validate_arg (size, INTEGER_TYPE))
12448 return NULL_TREE;
10a0d495
JJ
12449
12450 if (! host_integerp (size, 1))
5039610b 12451 return NULL_TREE;
10a0d495
JJ
12452
12453 if (! integer_all_onesp (size))
12454 {
12455 if (! host_integerp (len, 1))
12456 {
12457 /* If LEN is not constant, try MAXLEN too.
12458 For MAXLEN only allow optimizing into non-_ocs function
12459 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12460 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
5039610b 12461 return NULL_TREE;
10a0d495 12462 }
f28d3046
JJ
12463 else
12464 maxlen = len;
10a0d495 12465
f28d3046 12466 if (tree_int_cst_lt (size, maxlen))
5039610b 12467 return NULL_TREE;
10a0d495
JJ
12468 }
12469
10a0d495
JJ
12470 /* If __builtin_strncpy_chk is used, assume strncpy is available. */
12471 fn = built_in_decls[BUILT_IN_STRNCPY];
12472 if (!fn)
5039610b 12473 return NULL_TREE;
10a0d495 12474
db3927fb 12475 return build_call_expr_loc (loc, fn, 3, dest, src, len);
10a0d495
JJ
12476}
12477
5039610b
SL
12478/* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12479 are the arguments to the call. */
10a0d495
JJ
12480
12481static tree
db3927fb
AH
12482fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12483 tree src, tree size)
10a0d495 12484{
5039610b 12485 tree fn;
10a0d495
JJ
12486 const char *p;
12487
5039610b
SL
12488 if (!validate_arg (dest, POINTER_TYPE)
12489 || !validate_arg (src, POINTER_TYPE)
12490 || !validate_arg (size, INTEGER_TYPE))
12491 return NULL_TREE;
10a0d495
JJ
12492
12493 p = c_getstr (src);
12494 /* If the SRC parameter is "", return DEST. */
12495 if (p && *p == '\0')
db3927fb 12496 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10a0d495
JJ
12497
12498 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
5039610b 12499 return NULL_TREE;
10a0d495
JJ
12500
12501 /* If __builtin_strcat_chk is used, assume strcat is available. */
12502 fn = built_in_decls[BUILT_IN_STRCAT];
12503 if (!fn)
5039610b 12504 return NULL_TREE;
10a0d495 12505
db3927fb 12506 return build_call_expr_loc (loc, fn, 2, dest, src);
10a0d495
JJ
12507}
12508
5039610b
SL
12509/* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12510 LEN, and SIZE. */
10a0d495
JJ
12511
12512static tree
db3927fb 12513fold_builtin_strncat_chk (location_t loc, tree fndecl,
5039610b 12514 tree dest, tree src, tree len, tree size)
10a0d495 12515{
5039610b 12516 tree fn;
10a0d495
JJ
12517 const char *p;
12518
5039610b
SL
12519 if (!validate_arg (dest, POINTER_TYPE)
12520 || !validate_arg (src, POINTER_TYPE)
12521 || !validate_arg (size, INTEGER_TYPE)
12522 || !validate_arg (size, INTEGER_TYPE))
12523 return NULL_TREE;
10a0d495
JJ
12524
12525 p = c_getstr (src);
12526 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
12527 if (p && *p == '\0')
db3927fb 12528 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10a0d495 12529 else if (integer_zerop (len))
db3927fb 12530 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10a0d495
JJ
12531
12532 if (! host_integerp (size, 1))
5039610b 12533 return NULL_TREE;
10a0d495
JJ
12534
12535 if (! integer_all_onesp (size))
12536 {
12537 tree src_len = c_strlen (src, 1);
12538 if (src_len
12539 && host_integerp (src_len, 1)
12540 && host_integerp (len, 1)
12541 && ! tree_int_cst_lt (len, src_len))
12542 {
12543 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
12544 fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12545 if (!fn)
5039610b 12546 return NULL_TREE;
10a0d495 12547
db3927fb 12548 return build_call_expr_loc (loc, fn, 3, dest, src, size);
10a0d495 12549 }
5039610b 12550 return NULL_TREE;
10a0d495
JJ
12551 }
12552
10a0d495
JJ
12553 /* If __builtin_strncat_chk is used, assume strncat is available. */
12554 fn = built_in_decls[BUILT_IN_STRNCAT];
12555 if (!fn)
5039610b 12556 return NULL_TREE;
10a0d495 12557
db3927fb 12558 return build_call_expr_loc (loc, fn, 3, dest, src, len);
10a0d495
JJ
12559}
12560
5039610b 12561/* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
10a0d495
JJ
12562 a normal call should be emitted rather than expanding the function
12563 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
12564
12565static tree
db3927fb
AH
12566fold_builtin_sprintf_chk (location_t loc, tree exp,
12567 enum built_in_function fcode)
10a0d495
JJ
12568{
12569 tree dest, size, len, fn, fmt, flag;
12570 const char *fmt_str;
5039610b 12571 int nargs = call_expr_nargs (exp);
10a0d495
JJ
12572
12573 /* Verify the required arguments in the original call. */
5039610b
SL
12574 if (nargs < 4)
12575 return NULL_TREE;
12576 dest = CALL_EXPR_ARG (exp, 0);
12577 if (!validate_arg (dest, POINTER_TYPE))
12578 return NULL_TREE;
12579 flag = CALL_EXPR_ARG (exp, 1);
12580 if (!validate_arg (flag, INTEGER_TYPE))
12581 return NULL_TREE;
12582 size = CALL_EXPR_ARG (exp, 2);
12583 if (!validate_arg (size, INTEGER_TYPE))
12584 return NULL_TREE;
12585 fmt = CALL_EXPR_ARG (exp, 3);
12586 if (!validate_arg (fmt, POINTER_TYPE))
12587 return NULL_TREE;
10a0d495
JJ
12588
12589 if (! host_integerp (size, 1))
5039610b 12590 return NULL_TREE;
10a0d495
JJ
12591
12592 len = NULL_TREE;
12593
62e5bf5d 12594 if (!init_target_chars ())
5039610b 12595 return NULL_TREE;
000ba23d 12596
10a0d495
JJ
12597 /* Check whether the format is a literal string constant. */
12598 fmt_str = c_getstr (fmt);
12599 if (fmt_str != NULL)
12600 {
12601 /* If the format doesn't contain % args or %%, we know the size. */
000ba23d 12602 if (strchr (fmt_str, target_percent) == 0)
10a0d495 12603 {
5039610b 12604 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
10a0d495
JJ
12605 len = build_int_cstu (size_type_node, strlen (fmt_str));
12606 }
12607 /* If the format is "%s" and first ... argument is a string literal,
12608 we know the size too. */
5039610b
SL
12609 else if (fcode == BUILT_IN_SPRINTF_CHK
12610 && strcmp (fmt_str, target_percent_s) == 0)
10a0d495
JJ
12611 {
12612 tree arg;
12613
5039610b 12614 if (nargs == 5)
10a0d495 12615 {
5039610b
SL
12616 arg = CALL_EXPR_ARG (exp, 4);
12617 if (validate_arg (arg, POINTER_TYPE))
10a0d495
JJ
12618 {
12619 len = c_strlen (arg, 1);
12620 if (! len || ! host_integerp (len, 1))
12621 len = NULL_TREE;
12622 }
12623 }
12624 }
12625 }
12626
12627 if (! integer_all_onesp (size))
12628 {
12629 if (! len || ! tree_int_cst_lt (len, size))
5039610b 12630 return NULL_TREE;
10a0d495
JJ
12631 }
12632
12633 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12634 or if format doesn't contain % chars or is "%s". */
12635 if (! integer_zerop (flag))
12636 {
12637 if (fmt_str == NULL)
5039610b
SL
12638 return NULL_TREE;
12639 if (strchr (fmt_str, target_percent) != NULL
12640 && strcmp (fmt_str, target_percent_s))
12641 return NULL_TREE;
10a0d495
JJ
12642 }
12643
10a0d495
JJ
12644 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
12645 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12646 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12647 if (!fn)
5039610b 12648 return NULL_TREE;
10a0d495 12649
db3927fb 12650 return rewrite_call_expr (loc, exp, 4, fn, 2, dest, fmt);
10a0d495
JJ
12651}
12652
5039610b 12653/* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
10a0d495
JJ
12654 a normal call should be emitted rather than expanding the function
12655 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
12656 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
12657 passed as second argument. */
12658
12659tree
db3927fb 12660fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
10a0d495
JJ
12661 enum built_in_function fcode)
12662{
12663 tree dest, size, len, fn, fmt, flag;
12664 const char *fmt_str;
12665
12666 /* Verify the required arguments in the original call. */
5039610b
SL
12667 if (call_expr_nargs (exp) < 5)
12668 return NULL_TREE;
12669 dest = CALL_EXPR_ARG (exp, 0);
12670 if (!validate_arg (dest, POINTER_TYPE))
12671 return NULL_TREE;
12672 len = CALL_EXPR_ARG (exp, 1);
12673 if (!validate_arg (len, INTEGER_TYPE))
12674 return NULL_TREE;
12675 flag = CALL_EXPR_ARG (exp, 2);
12676 if (!validate_arg (flag, INTEGER_TYPE))
12677 return NULL_TREE;
12678 size = CALL_EXPR_ARG (exp, 3);
12679 if (!validate_arg (size, INTEGER_TYPE))
12680 return NULL_TREE;
12681 fmt = CALL_EXPR_ARG (exp, 4);
12682 if (!validate_arg (fmt, POINTER_TYPE))
12683 return NULL_TREE;
10a0d495
JJ
12684
12685 if (! host_integerp (size, 1))
5039610b 12686 return NULL_TREE;
10a0d495
JJ
12687
12688 if (! integer_all_onesp (size))
12689 {
12690 if (! host_integerp (len, 1))
12691 {
12692 /* If LEN is not constant, try MAXLEN too.
12693 For MAXLEN only allow optimizing into non-_ocs function
12694 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12695 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
5039610b 12696 return NULL_TREE;
10a0d495 12697 }
f28d3046
JJ
12698 else
12699 maxlen = len;
10a0d495 12700
f28d3046 12701 if (tree_int_cst_lt (size, maxlen))
5039610b 12702 return NULL_TREE;
10a0d495
JJ
12703 }
12704
62e5bf5d 12705 if (!init_target_chars ())
5039610b 12706 return NULL_TREE;
000ba23d 12707
10a0d495
JJ
12708 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12709 or if format doesn't contain % chars or is "%s". */
12710 if (! integer_zerop (flag))
12711 {
12712 fmt_str = c_getstr (fmt);
12713 if (fmt_str == NULL)
5039610b
SL
12714 return NULL_TREE;
12715 if (strchr (fmt_str, target_percent) != NULL
12716 && strcmp (fmt_str, target_percent_s))
12717 return NULL_TREE;
10a0d495
JJ
12718 }
12719
10a0d495
JJ
12720 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12721 available. */
12722 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12723 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12724 if (!fn)
5039610b 12725 return NULL_TREE;
10a0d495 12726
db3927fb 12727 return rewrite_call_expr (loc, exp, 5, fn, 3, dest, len, fmt);
10a0d495
JJ
12728}
12729
12730/* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
5039610b
SL
12731 FMT and ARG are the arguments to the call; we don't fold cases with
12732 more than 2 arguments, and ARG may be null if this is a 1-argument case.
10a0d495 12733
5039610b 12734 Return NULL_TREE if no simplification was possible, otherwise return the
10a0d495
JJ
12735 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12736 code of the function to be simplified. */
12737
12738static tree
db3927fb
AH
12739fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
12740 tree arg, bool ignore,
10a0d495
JJ
12741 enum built_in_function fcode)
12742{
5039610b 12743 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
10a0d495
JJ
12744 const char *fmt_str = NULL;
12745
12746 /* If the return value is used, don't do the transformation. */
12747 if (! ignore)
5039610b 12748 return NULL_TREE;
10a0d495
JJ
12749
12750 /* Verify the required arguments in the original call. */
5039610b
SL
12751 if (!validate_arg (fmt, POINTER_TYPE))
12752 return NULL_TREE;
10a0d495
JJ
12753
12754 /* Check whether the format is a literal string constant. */
12755 fmt_str = c_getstr (fmt);
12756 if (fmt_str == NULL)
12757 return NULL_TREE;
12758
12759 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12760 {
7e7b53aa
KG
12761 /* If we're using an unlocked function, assume the other
12762 unlocked functions exist explicitly. */
12763 fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12764 fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10a0d495
JJ
12765 }
12766 else
12767 {
12768 fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12769 fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12770 }
12771
62e5bf5d 12772 if (!init_target_chars ())
5039610b 12773 return NULL_TREE;
c22cacf3 12774
5039610b
SL
12775 if (strcmp (fmt_str, target_percent_s) == 0
12776 || strchr (fmt_str, target_percent) == NULL)
10a0d495
JJ
12777 {
12778 const char *str;
12779
000ba23d 12780 if (strcmp (fmt_str, target_percent_s) == 0)
10a0d495
JJ
12781 {
12782 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
5039610b 12783 return NULL_TREE;
10a0d495 12784
5039610b
SL
12785 if (!arg || !validate_arg (arg, POINTER_TYPE))
12786 return NULL_TREE;
10a0d495 12787
5039610b 12788 str = c_getstr (arg);
10a0d495 12789 if (str == NULL)
5039610b 12790 return NULL_TREE;
10a0d495
JJ
12791 }
12792 else
12793 {
12794 /* The format specifier doesn't contain any '%' characters. */
12795 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
5039610b
SL
12796 && arg)
12797 return NULL_TREE;
10a0d495
JJ
12798 str = fmt_str;
12799 }
12800
12801 /* If the string was "", printf does nothing. */
12802 if (str[0] == '\0')
12803 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12804
12805 /* If the string has length of 1, call putchar. */
12806 if (str[1] == '\0')
12807 {
12808 /* Given printf("c"), (where c is any one character,)
12809 convert "c"[0] to an int and pass that to the replacement
12810 function. */
5039610b
SL
12811 newarg = build_int_cst (NULL_TREE, str[0]);
12812 if (fn_putchar)
db3927fb 12813 call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
10a0d495
JJ
12814 }
12815 else
12816 {
12817 /* If the string was "string\n", call puts("string"). */
12818 size_t len = strlen (str);
000ba23d 12819 if ((unsigned char)str[len - 1] == target_newline)
10a0d495
JJ
12820 {
12821 /* Create a NUL-terminated string that's one char shorter
12822 than the original, stripping off the trailing '\n'. */
f883e0a7 12823 char *newstr = XALLOCAVEC (char, len);
10a0d495
JJ
12824 memcpy (newstr, str, len - 1);
12825 newstr[len - 1] = 0;
12826
5039610b
SL
12827 newarg = build_string_literal (len, newstr);
12828 if (fn_puts)
db3927fb 12829 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
10a0d495
JJ
12830 }
12831 else
12832 /* We'd like to arrange to call fputs(string,stdout) here,
12833 but we need stdout and don't have a way to get it yet. */
5039610b 12834 return NULL_TREE;
10a0d495
JJ
12835 }
12836 }
12837
12838 /* The other optimizations can be done only on the non-va_list variants. */
12839 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
5039610b 12840 return NULL_TREE;
10a0d495
JJ
12841
12842 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
000ba23d 12843 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
10a0d495 12844 {
5039610b
SL
12845 if (!arg || !validate_arg (arg, POINTER_TYPE))
12846 return NULL_TREE;
12847 if (fn_puts)
db3927fb 12848 call = build_call_expr_loc (loc, fn_puts, 1, arg);
10a0d495
JJ
12849 }
12850
12851 /* If the format specifier was "%c", call __builtin_putchar(arg). */
000ba23d 12852 else if (strcmp (fmt_str, target_percent_c) == 0)
10a0d495 12853 {
5039610b
SL
12854 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12855 return NULL_TREE;
12856 if (fn_putchar)
db3927fb 12857 call = build_call_expr_loc (loc, fn_putchar, 1, arg);
10a0d495
JJ
12858 }
12859
5039610b
SL
12860 if (!call)
12861 return NULL_TREE;
10a0d495 12862
db3927fb 12863 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
10a0d495
JJ
12864}
12865
12866/* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
5039610b
SL
12867 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
12868 more than 3 arguments, and ARG may be null in the 2-argument case.
10a0d495 12869
5039610b 12870 Return NULL_TREE if no simplification was possible, otherwise return the
10a0d495
JJ
12871 simplified form of the call as a tree. FCODE is the BUILT_IN_*
12872 code of the function to be simplified. */
12873
12874static tree
db3927fb
AH
12875fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
12876 tree fmt, tree arg, bool ignore,
10a0d495
JJ
12877 enum built_in_function fcode)
12878{
5039610b 12879 tree fn_fputc, fn_fputs, call = NULL_TREE;
10a0d495
JJ
12880 const char *fmt_str = NULL;
12881
12882 /* If the return value is used, don't do the transformation. */
12883 if (! ignore)
5039610b 12884 return NULL_TREE;
10a0d495
JJ
12885
12886 /* Verify the required arguments in the original call. */
5039610b
SL
12887 if (!validate_arg (fp, POINTER_TYPE))
12888 return NULL_TREE;
12889 if (!validate_arg (fmt, POINTER_TYPE))
12890 return NULL_TREE;
10a0d495
JJ
12891
12892 /* Check whether the format is a literal string constant. */
12893 fmt_str = c_getstr (fmt);
12894 if (fmt_str == NULL)
12895 return NULL_TREE;
12896
12897 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12898 {
7e7b53aa
KG
12899 /* If we're using an unlocked function, assume the other
12900 unlocked functions exist explicitly. */
12901 fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12902 fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10a0d495
JJ
12903 }
12904 else
12905 {
12906 fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12907 fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12908 }
12909
62e5bf5d 12910 if (!init_target_chars ())
5039610b 12911 return NULL_TREE;
c22cacf3 12912
10a0d495 12913 /* If the format doesn't contain % args or %%, use strcpy. */
000ba23d 12914 if (strchr (fmt_str, target_percent) == NULL)
10a0d495
JJ
12915 {
12916 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
5039610b
SL
12917 && arg)
12918 return NULL_TREE;
10a0d495
JJ
12919
12920 /* If the format specifier was "", fprintf does nothing. */
12921 if (fmt_str[0] == '\0')
12922 {
12923 /* If FP has side-effects, just wait until gimplification is
12924 done. */
12925 if (TREE_SIDE_EFFECTS (fp))
5039610b 12926 return NULL_TREE;
10a0d495
JJ
12927
12928 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12929 }
12930
12931 /* When "string" doesn't contain %, replace all cases of
12932 fprintf (fp, string) with fputs (string, fp). The fputs
12933 builtin will take care of special cases like length == 1. */
5039610b 12934 if (fn_fputs)
db3927fb 12935 call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
10a0d495
JJ
12936 }
12937
12938 /* The other optimizations can be done only on the non-va_list variants. */
12939 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
5039610b 12940 return NULL_TREE;
10a0d495
JJ
12941
12942 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
000ba23d 12943 else if (strcmp (fmt_str, target_percent_s) == 0)
10a0d495 12944 {
5039610b
SL
12945 if (!arg || !validate_arg (arg, POINTER_TYPE))
12946 return NULL_TREE;
12947 if (fn_fputs)
db3927fb 12948 call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
10a0d495
JJ
12949 }
12950
12951 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
000ba23d 12952 else if (strcmp (fmt_str, target_percent_c) == 0)
10a0d495 12953 {
5039610b
SL
12954 if (!arg || !validate_arg (arg, INTEGER_TYPE))
12955 return NULL_TREE;
12956 if (fn_fputc)
db3927fb 12957 call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
10a0d495
JJ
12958 }
12959
5039610b
SL
12960 if (!call)
12961 return NULL_TREE;
db3927fb 12962 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
10a0d495 12963}
000ba23d
KG
12964
12965/* Initialize format string characters in the target charset. */
12966
12967static bool
12968init_target_chars (void)
12969{
12970 static bool init;
12971 if (!init)
12972 {
12973 target_newline = lang_hooks.to_target_charset ('\n');
12974 target_percent = lang_hooks.to_target_charset ('%');
12975 target_c = lang_hooks.to_target_charset ('c');
12976 target_s = lang_hooks.to_target_charset ('s');
12977 if (target_newline == 0 || target_percent == 0 || target_c == 0
12978 || target_s == 0)
12979 return false;
12980
12981 target_percent_c[0] = target_percent;
12982 target_percent_c[1] = target_c;
12983 target_percent_c[2] = '\0';
12984
12985 target_percent_s[0] = target_percent;
12986 target_percent_s[1] = target_s;
12987 target_percent_s[2] = '\0';
12988
12989 target_percent_s_newline[0] = target_percent;
12990 target_percent_s_newline[1] = target_s;
12991 target_percent_s_newline[2] = target_newline;
12992 target_percent_s_newline[3] = '\0';
c22cacf3 12993
000ba23d
KG
12994 init = true;
12995 }
12996 return true;
12997}
1f3f1f68 12998
4413d881
KG
12999/* Helper function for do_mpfr_arg*(). Ensure M is a normal number
13000 and no overflow/underflow occurred. INEXACT is true if M was not
2f8e468b 13001 exactly calculated. TYPE is the tree type for the result. This
4413d881
KG
13002 function assumes that you cleared the MPFR flags and then
13003 calculated M to see if anything subsequently set a flag prior to
13004 entering this function. Return NULL_TREE if any checks fail. */
13005
13006static tree
62e5bf5d 13007do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
4413d881
KG
13008{
13009 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13010 overflow/underflow occurred. If -frounding-math, proceed iff the
13011 result of calling FUNC was exact. */
62e5bf5d 13012 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
4413d881
KG
13013 && (!flag_rounding_math || !inexact))
13014 {
13015 REAL_VALUE_TYPE rr;
13016
205a4d09 13017 real_from_mpfr (&rr, m, type, GMP_RNDN);
4413d881
KG
13018 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13019 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13020 but the mpft_t is not, then we underflowed in the
13021 conversion. */
4c8c70e0 13022 if (real_isfinite (&rr)
4413d881
KG
13023 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13024 {
13025 REAL_VALUE_TYPE rmode;
13026
13027 real_convert (&rmode, TYPE_MODE (type), &rr);
13028 /* Proceed iff the specified mode can hold the value. */
13029 if (real_identical (&rmode, &rr))
13030 return build_real (type, rmode);
13031 }
13032 }
13033 return NULL_TREE;
13034}
13035
c128599a
KG
13036#ifdef HAVE_mpc
13037/* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13038 number and no overflow/underflow occurred. INEXACT is true if M
13039 was not exactly calculated. TYPE is the tree type for the result.
13040 This function assumes that you cleared the MPFR flags and then
13041 calculated M to see if anything subsequently set a flag prior to
ca75b926
KG
13042 entering this function. Return NULL_TREE if any checks fail, if
13043 FORCE_CONVERT is true, then bypass the checks. */
c128599a
KG
13044
13045static tree
ca75b926 13046do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
c128599a
KG
13047{
13048 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13049 overflow/underflow occurred. If -frounding-math, proceed iff the
13050 result of calling FUNC was exact. */
ca75b926
KG
13051 if (force_convert
13052 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13053 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13054 && (!flag_rounding_math || !inexact)))
c128599a
KG
13055 {
13056 REAL_VALUE_TYPE re, im;
13057
26a347c5
KG
13058 real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13059 real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
c128599a
KG
13060 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13061 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13062 but the mpft_t is not, then we underflowed in the
13063 conversion. */
ca75b926
KG
13064 if (force_convert
13065 || (real_isfinite (&re) && real_isfinite (&im)
13066 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13067 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
c128599a
KG
13068 {
13069 REAL_VALUE_TYPE re_mode, im_mode;
13070
13071 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13072 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13073 /* Proceed iff the specified mode can hold the value. */
ca75b926
KG
13074 if (force_convert
13075 || (real_identical (&re_mode, &re)
13076 && real_identical (&im_mode, &im)))
c128599a
KG
13077 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13078 build_real (TREE_TYPE (type), im_mode));
13079 }
13080 }
13081 return NULL_TREE;
13082}
13083#endif /* HAVE_mpc */
13084
1f3f1f68
KG
13085/* If argument ARG is a REAL_CST, call the one-argument mpfr function
13086 FUNC on it and return the resulting value as a tree with type TYPE.
b53fed56
KG
13087 If MIN and/or MAX are not NULL, then the supplied ARG must be
13088 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13089 acceptable values, otherwise they are not. The mpfr precision is
13090 set to the precision of TYPE. We assume that function FUNC returns
13091 zero if the result could be calculated exactly within the requested
13092 precision. */
1f3f1f68
KG
13093
13094static tree
b53fed56
KG
13095do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13096 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13097 bool inclusive)
1f3f1f68
KG
13098{
13099 tree result = NULL_TREE;
b8698a0f 13100
1f3f1f68
KG
13101 STRIP_NOPS (arg);
13102
5f641bd8
KG
13103 /* To proceed, MPFR must exactly represent the target floating point
13104 format, which only happens when the target base equals two. */
13105 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
455f14dd 13106 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
1f3f1f68 13107 {
4413d881 13108 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
1f3f1f68 13109
4c8c70e0 13110 if (real_isfinite (ra)
4413d881
KG
13111 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13112 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
1f3f1f68 13113 {
3e479de3
UW
13114 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13115 const int prec = fmt->p;
13116 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
b52dd66c 13117 int inexact;
1f3f1f68
KG
13118 mpfr_t m;
13119
13120 mpfr_init2 (m, prec);
205a4d09 13121 mpfr_from_real (m, ra, GMP_RNDN);
62e5bf5d 13122 mpfr_clear_flags ();
3e479de3 13123 inexact = func (m, m, rnd);
4413d881 13124 result = do_mpfr_ckconv (m, type, inexact);
1f3f1f68
KG
13125 mpfr_clear (m);
13126 }
13127 }
b8698a0f 13128
1f3f1f68
KG
13129 return result;
13130}
4413d881
KG
13131
13132/* If argument ARG is a REAL_CST, call the two-argument mpfr function
13133 FUNC on it and return the resulting value as a tree with type TYPE.
13134 The mpfr precision is set to the precision of TYPE. We assume that
13135 function FUNC returns zero if the result could be calculated
13136 exactly within the requested precision. */
13137
13138static tree
13139do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13140 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13141{
13142 tree result = NULL_TREE;
b8698a0f 13143
4413d881
KG
13144 STRIP_NOPS (arg1);
13145 STRIP_NOPS (arg2);
13146
5f641bd8
KG
13147 /* To proceed, MPFR must exactly represent the target floating point
13148 format, which only happens when the target base equals two. */
13149 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
455f14dd
RS
13150 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13151 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
4413d881
KG
13152 {
13153 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13154 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13155
4c8c70e0 13156 if (real_isfinite (ra1) && real_isfinite (ra2))
4413d881 13157 {
3e479de3
UW
13158 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13159 const int prec = fmt->p;
13160 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
4413d881
KG
13161 int inexact;
13162 mpfr_t m1, m2;
13163
13164 mpfr_inits2 (prec, m1, m2, NULL);
205a4d09
BM
13165 mpfr_from_real (m1, ra1, GMP_RNDN);
13166 mpfr_from_real (m2, ra2, GMP_RNDN);
62e5bf5d 13167 mpfr_clear_flags ();
3e479de3 13168 inexact = func (m1, m1, m2, rnd);
4413d881
KG
13169 result = do_mpfr_ckconv (m1, type, inexact);
13170 mpfr_clears (m1, m2, NULL);
13171 }
13172 }
b8698a0f 13173
4413d881
KG
13174 return result;
13175}
b68bcfff 13176
e61e5ddc
KG
13177/* If argument ARG is a REAL_CST, call the three-argument mpfr function
13178 FUNC on it and return the resulting value as a tree with type TYPE.
13179 The mpfr precision is set to the precision of TYPE. We assume that
13180 function FUNC returns zero if the result could be calculated
13181 exactly within the requested precision. */
13182
13183static tree
13184do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13185 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13186{
13187 tree result = NULL_TREE;
b8698a0f 13188
e61e5ddc
KG
13189 STRIP_NOPS (arg1);
13190 STRIP_NOPS (arg2);
13191 STRIP_NOPS (arg3);
13192
5f641bd8
KG
13193 /* To proceed, MPFR must exactly represent the target floating point
13194 format, which only happens when the target base equals two. */
13195 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
455f14dd
RS
13196 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13197 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13198 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
e61e5ddc
KG
13199 {
13200 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13201 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13202 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13203
4c8c70e0 13204 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
e61e5ddc 13205 {
3e479de3
UW
13206 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13207 const int prec = fmt->p;
13208 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
e61e5ddc
KG
13209 int inexact;
13210 mpfr_t m1, m2, m3;
13211
13212 mpfr_inits2 (prec, m1, m2, m3, NULL);
205a4d09
BM
13213 mpfr_from_real (m1, ra1, GMP_RNDN);
13214 mpfr_from_real (m2, ra2, GMP_RNDN);
13215 mpfr_from_real (m3, ra3, GMP_RNDN);
62e5bf5d 13216 mpfr_clear_flags ();
3e479de3 13217 inexact = func (m1, m1, m2, m3, rnd);
e61e5ddc
KG
13218 result = do_mpfr_ckconv (m1, type, inexact);
13219 mpfr_clears (m1, m2, m3, NULL);
13220 }
13221 }
b8698a0f 13222
e61e5ddc
KG
13223 return result;
13224}
13225
b68bcfff
KG
13226/* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13227 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
75c7c595
RG
13228 If ARG_SINP and ARG_COSP are NULL then the result is returned
13229 as a complex value.
b68bcfff
KG
13230 The type is taken from the type of ARG and is used for setting the
13231 precision of the calculation and results. */
13232
13233static tree
13234do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13235{
5f641bd8 13236 tree const type = TREE_TYPE (arg);
b68bcfff 13237 tree result = NULL_TREE;
b8698a0f 13238
b68bcfff 13239 STRIP_NOPS (arg);
b8698a0f 13240
5f641bd8
KG
13241 /* To proceed, MPFR must exactly represent the target floating point
13242 format, which only happens when the target base equals two. */
13243 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
455f14dd
RS
13244 && TREE_CODE (arg) == REAL_CST
13245 && !TREE_OVERFLOW (arg))
b68bcfff
KG
13246 {
13247 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13248
4c8c70e0 13249 if (real_isfinite (ra))
b68bcfff 13250 {
3e479de3
UW
13251 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13252 const int prec = fmt->p;
13253 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
b68bcfff
KG
13254 tree result_s, result_c;
13255 int inexact;
13256 mpfr_t m, ms, mc;
13257
13258 mpfr_inits2 (prec, m, ms, mc, NULL);
205a4d09 13259 mpfr_from_real (m, ra, GMP_RNDN);
62e5bf5d 13260 mpfr_clear_flags ();
3e479de3 13261 inexact = mpfr_sin_cos (ms, mc, m, rnd);
b68bcfff
KG
13262 result_s = do_mpfr_ckconv (ms, type, inexact);
13263 result_c = do_mpfr_ckconv (mc, type, inexact);
13264 mpfr_clears (m, ms, mc, NULL);
13265 if (result_s && result_c)
13266 {
75c7c595
RG
13267 /* If we are to return in a complex value do so. */
13268 if (!arg_sinp && !arg_cosp)
13269 return build_complex (build_complex_type (type),
13270 result_c, result_s);
13271
b68bcfff
KG
13272 /* Dereference the sin/cos pointer arguments. */
13273 arg_sinp = build_fold_indirect_ref (arg_sinp);
13274 arg_cosp = build_fold_indirect_ref (arg_cosp);
13275 /* Proceed if valid pointer type were passed in. */
13276 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13277 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13278 {
13279 /* Set the values. */
939409af 13280 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
07beea0d 13281 result_s);
b68bcfff 13282 TREE_SIDE_EFFECTS (result_s) = 1;
939409af 13283 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
07beea0d 13284 result_c);
b68bcfff
KG
13285 TREE_SIDE_EFFECTS (result_c) = 1;
13286 /* Combine the assignments into a compound expr. */
13287 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13288 result_s, result_c));
13289 }
13290 }
13291 }
13292 }
13293 return result;
13294}
550b3187 13295
550b3187
KG
13296/* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13297 two-argument mpfr order N Bessel function FUNC on them and return
13298 the resulting value as a tree with type TYPE. The mpfr precision
13299 is set to the precision of TYPE. We assume that function FUNC
13300 returns zero if the result could be calculated exactly within the
13301 requested precision. */
13302static tree
13303do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13304 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13305 const REAL_VALUE_TYPE *min, bool inclusive)
13306{
13307 tree result = NULL_TREE;
13308
13309 STRIP_NOPS (arg1);
13310 STRIP_NOPS (arg2);
13311
13312 /* To proceed, MPFR must exactly represent the target floating point
13313 format, which only happens when the target base equals two. */
13314 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13315 && host_integerp (arg1, 0)
13316 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13317 {
13318 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13319 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13320
13321 if (n == (long)n
4c8c70e0 13322 && real_isfinite (ra)
550b3187
KG
13323 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13324 {
3e479de3
UW
13325 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13326 const int prec = fmt->p;
13327 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
550b3187
KG
13328 int inexact;
13329 mpfr_t m;
13330
13331 mpfr_init2 (m, prec);
13332 mpfr_from_real (m, ra, GMP_RNDN);
13333 mpfr_clear_flags ();
3e479de3 13334 inexact = func (m, n, m, rnd);
550b3187
KG
13335 result = do_mpfr_ckconv (m, type, inexact);
13336 mpfr_clear (m);
13337 }
13338 }
b8698a0f 13339
550b3187
KG
13340 return result;
13341}
ea91f957
KG
13342
13343/* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13344 the pointer *(ARG_QUO) and return the result. The type is taken
13345 from the type of ARG0 and is used for setting the precision of the
13346 calculation and results. */
13347
13348static tree
13349do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13350{
13351 tree const type = TREE_TYPE (arg0);
13352 tree result = NULL_TREE;
b8698a0f 13353
ea91f957
KG
13354 STRIP_NOPS (arg0);
13355 STRIP_NOPS (arg1);
b8698a0f 13356
ea91f957
KG
13357 /* To proceed, MPFR must exactly represent the target floating point
13358 format, which only happens when the target base equals two. */
13359 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13360 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13361 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13362 {
13363 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13364 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13365
4c8c70e0 13366 if (real_isfinite (ra0) && real_isfinite (ra1))
ea91f957 13367 {
3e479de3
UW
13368 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13369 const int prec = fmt->p;
13370 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
ea91f957
KG
13371 tree result_rem;
13372 long integer_quo;
13373 mpfr_t m0, m1;
13374
13375 mpfr_inits2 (prec, m0, m1, NULL);
13376 mpfr_from_real (m0, ra0, GMP_RNDN);
13377 mpfr_from_real (m1, ra1, GMP_RNDN);
13378 mpfr_clear_flags ();
3e479de3 13379 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
ea91f957
KG
13380 /* Remquo is independent of the rounding mode, so pass
13381 inexact=0 to do_mpfr_ckconv(). */
13382 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13383 mpfr_clears (m0, m1, NULL);
13384 if (result_rem)
13385 {
13386 /* MPFR calculates quo in the host's long so it may
13387 return more bits in quo than the target int can hold
13388 if sizeof(host long) > sizeof(target int). This can
13389 happen even for native compilers in LP64 mode. In
13390 these cases, modulo the quo value with the largest
13391 number that the target int can hold while leaving one
13392 bit for the sign. */
13393 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13394 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13395
13396 /* Dereference the quo pointer argument. */
13397 arg_quo = build_fold_indirect_ref (arg_quo);
13398 /* Proceed iff a valid pointer type was passed in. */
13399 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13400 {
13401 /* Set the value. */
13402 tree result_quo = fold_build2 (MODIFY_EXPR,
13403 TREE_TYPE (arg_quo), arg_quo,
13404 build_int_cst (NULL, integer_quo));
13405 TREE_SIDE_EFFECTS (result_quo) = 1;
13406 /* Combine the quo assignment with the rem. */
13407 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13408 result_quo, result_rem));
13409 }
13410 }
13411 }
13412 }
13413 return result;
13414}
752b7d38
KG
13415
13416/* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13417 resulting value as a tree with type TYPE. The mpfr precision is
13418 set to the precision of TYPE. We assume that this mpfr function
13419 returns zero if the result could be calculated exactly within the
13420 requested precision. In addition, the integer pointer represented
13421 by ARG_SG will be dereferenced and set to the appropriate signgam
13422 (-1,1) value. */
13423
13424static tree
13425do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13426{
13427 tree result = NULL_TREE;
13428
13429 STRIP_NOPS (arg);
b8698a0f 13430
752b7d38
KG
13431 /* To proceed, MPFR must exactly represent the target floating point
13432 format, which only happens when the target base equals two. Also
13433 verify ARG is a constant and that ARG_SG is an int pointer. */
13434 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13435 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13436 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13437 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13438 {
13439 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13440
13441 /* In addition to NaN and Inf, the argument cannot be zero or a
13442 negative integer. */
4c8c70e0 13443 if (real_isfinite (ra)
752b7d38
KG
13444 && ra->cl != rvc_zero
13445 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13446 {
3e479de3
UW
13447 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13448 const int prec = fmt->p;
13449 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
752b7d38
KG
13450 int inexact, sg;
13451 mpfr_t m;
13452 tree result_lg;
13453
13454 mpfr_init2 (m, prec);
13455 mpfr_from_real (m, ra, GMP_RNDN);
13456 mpfr_clear_flags ();
3e479de3 13457 inexact = mpfr_lgamma (m, &sg, m, rnd);
752b7d38
KG
13458 result_lg = do_mpfr_ckconv (m, type, inexact);
13459 mpfr_clear (m);
13460 if (result_lg)
13461 {
13462 tree result_sg;
13463
13464 /* Dereference the arg_sg pointer argument. */
13465 arg_sg = build_fold_indirect_ref (arg_sg);
13466 /* Assign the signgam value into *arg_sg. */
13467 result_sg = fold_build2 (MODIFY_EXPR,
13468 TREE_TYPE (arg_sg), arg_sg,
13469 build_int_cst (NULL, sg));
13470 TREE_SIDE_EFFECTS (result_sg) = 1;
13471 /* Combine the signgam assignment with the lgamma result. */
13472 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13473 result_sg, result_lg));
13474 }
13475 }
13476 }
13477
13478 return result;
13479}
726a989a 13480
c128599a
KG
13481#ifdef HAVE_mpc
13482/* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13483 function FUNC on it and return the resulting value as a tree with
13484 type TYPE. The mpfr precision is set to the precision of TYPE. We
13485 assume that function FUNC returns zero if the result could be
13486 calculated exactly within the requested precision. */
13487
13488static tree
13489do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13490{
13491 tree result = NULL_TREE;
b8698a0f 13492
c128599a
KG
13493 STRIP_NOPS (arg);
13494
13495 /* To proceed, MPFR must exactly represent the target floating point
13496 format, which only happens when the target base equals two. */
13497 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13498 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13499 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13500 {
13501 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13502 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13503
13504 if (real_isfinite (re) && real_isfinite (im))
13505 {
13506 const struct real_format *const fmt =
13507 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13508 const int prec = fmt->p;
13509 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
bbb9d91f 13510 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
c128599a
KG
13511 int inexact;
13512 mpc_t m;
b8698a0f 13513
c128599a 13514 mpc_init2 (m, prec);
26a347c5
KG
13515 mpfr_from_real (mpc_realref(m), re, rnd);
13516 mpfr_from_real (mpc_imagref(m), im, rnd);
c128599a 13517 mpfr_clear_flags ();
bbb9d91f 13518 inexact = func (m, m, crnd);
ca75b926 13519 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
c128599a
KG
13520 mpc_clear (m);
13521 }
13522 }
13523
13524 return result;
13525}
a41d064d
KG
13526
13527/* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
13528 mpc function FUNC on it and return the resulting value as a tree
13529 with type TYPE. The mpfr precision is set to the precision of
13530 TYPE. We assume that function FUNC returns zero if the result
ca75b926
KG
13531 could be calculated exactly within the requested precision. If
13532 DO_NONFINITE is true, then fold expressions containing Inf or NaN
13533 in the arguments and/or results. */
a41d064d 13534
2f440f6a
KG
13535#ifdef HAVE_mpc
13536tree
ca75b926 13537do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
a41d064d
KG
13538 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
13539{
13540 tree result = NULL_TREE;
b8698a0f 13541
a41d064d
KG
13542 STRIP_NOPS (arg0);
13543 STRIP_NOPS (arg1);
13544
13545 /* To proceed, MPFR must exactly represent the target floating point
13546 format, which only happens when the target base equals two. */
13547 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
13548 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
13549 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
13550 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
13551 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
13552 {
13553 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
13554 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
13555 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
13556 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
13557
ca75b926
KG
13558 if (do_nonfinite
13559 || (real_isfinite (re0) && real_isfinite (im0)
13560 && real_isfinite (re1) && real_isfinite (im1)))
a41d064d
KG
13561 {
13562 const struct real_format *const fmt =
13563 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13564 const int prec = fmt->p;
13565 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13566 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13567 int inexact;
13568 mpc_t m0, m1;
b8698a0f 13569
a41d064d
KG
13570 mpc_init2 (m0, prec);
13571 mpc_init2 (m1, prec);
13572 mpfr_from_real (mpc_realref(m0), re0, rnd);
13573 mpfr_from_real (mpc_imagref(m0), im0, rnd);
13574 mpfr_from_real (mpc_realref(m1), re1, rnd);
13575 mpfr_from_real (mpc_imagref(m1), im1, rnd);
13576 mpfr_clear_flags ();
13577 inexact = func (m0, m0, m1, crnd);
ca75b926 13578 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
a41d064d
KG
13579 mpc_clear (m0);
13580 mpc_clear (m1);
13581 }
13582 }
13583
13584 return result;
13585}
13586# endif
c128599a
KG
13587#endif /* HAVE_mpc */
13588
726a989a
RB
13589/* FIXME tuples.
13590 The functions below provide an alternate interface for folding
13591 builtin function calls presented as GIMPLE_CALL statements rather
13592 than as CALL_EXPRs. The folded result is still expressed as a
13593 tree. There is too much code duplication in the handling of
13594 varargs functions, and a more intrusive re-factoring would permit
13595 better sharing of code between the tree and statement-based
13596 versions of these functions. */
13597
13598/* Construct a new CALL_EXPR using the tail of the argument list of STMT
13599 along with N new arguments specified as the "..." parameters. SKIP
13600 is the number of arguments in STMT to be omitted. This function is used
13601 to do varargs-to-varargs transformations. */
13602
13603static tree
13604gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13605{
13606 int oldnargs = gimple_call_num_args (stmt);
13607 int nargs = oldnargs - skip + n;
13608 tree fntype = TREE_TYPE (fndecl);
13609 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13610 tree *buffer;
13611 int i, j;
13612 va_list ap;
db3927fb 13613 location_t loc = gimple_location (stmt);
726a989a
RB
13614
13615 buffer = XALLOCAVEC (tree, nargs);
13616 va_start (ap, n);
13617 for (i = 0; i < n; i++)
13618 buffer[i] = va_arg (ap, tree);
13619 va_end (ap);
13620 for (j = skip; j < oldnargs; j++, i++)
13621 buffer[i] = gimple_call_arg (stmt, j);
13622
db3927fb 13623 return fold (build_call_array_loc (loc, TREE_TYPE (fntype), fn, nargs, buffer));
726a989a
RB
13624}
13625
13626/* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
13627 a normal call should be emitted rather than expanding the function
13628 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13629
13630static tree
13631gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13632{
13633 tree dest, size, len, fn, fmt, flag;
13634 const char *fmt_str;
13635 int nargs = gimple_call_num_args (stmt);
13636
13637 /* Verify the required arguments in the original call. */
13638 if (nargs < 4)
13639 return NULL_TREE;
13640 dest = gimple_call_arg (stmt, 0);
13641 if (!validate_arg (dest, POINTER_TYPE))
13642 return NULL_TREE;
13643 flag = gimple_call_arg (stmt, 1);
13644 if (!validate_arg (flag, INTEGER_TYPE))
13645 return NULL_TREE;
13646 size = gimple_call_arg (stmt, 2);
13647 if (!validate_arg (size, INTEGER_TYPE))
13648 return NULL_TREE;
13649 fmt = gimple_call_arg (stmt, 3);
13650 if (!validate_arg (fmt, POINTER_TYPE))
13651 return NULL_TREE;
13652
13653 if (! host_integerp (size, 1))
13654 return NULL_TREE;
13655
13656 len = NULL_TREE;
13657
13658 if (!init_target_chars ())
13659 return NULL_TREE;
13660
13661 /* Check whether the format is a literal string constant. */
13662 fmt_str = c_getstr (fmt);
13663 if (fmt_str != NULL)
13664 {
13665 /* If the format doesn't contain % args or %%, we know the size. */
13666 if (strchr (fmt_str, target_percent) == 0)
13667 {
13668 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13669 len = build_int_cstu (size_type_node, strlen (fmt_str));
13670 }
13671 /* If the format is "%s" and first ... argument is a string literal,
13672 we know the size too. */
13673 else if (fcode == BUILT_IN_SPRINTF_CHK
13674 && strcmp (fmt_str, target_percent_s) == 0)
13675 {
13676 tree arg;
13677
13678 if (nargs == 5)
13679 {
13680 arg = gimple_call_arg (stmt, 4);
13681 if (validate_arg (arg, POINTER_TYPE))
13682 {
13683 len = c_strlen (arg, 1);
13684 if (! len || ! host_integerp (len, 1))
13685 len = NULL_TREE;
13686 }
13687 }
13688 }
13689 }
13690
13691 if (! integer_all_onesp (size))
13692 {
13693 if (! len || ! tree_int_cst_lt (len, size))
13694 return NULL_TREE;
13695 }
13696
13697 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13698 or if format doesn't contain % chars or is "%s". */
13699 if (! integer_zerop (flag))
13700 {
13701 if (fmt_str == NULL)
13702 return NULL_TREE;
13703 if (strchr (fmt_str, target_percent) != NULL
13704 && strcmp (fmt_str, target_percent_s))
13705 return NULL_TREE;
13706 }
13707
13708 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13709 fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13710 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13711 if (!fn)
13712 return NULL_TREE;
13713
13714 return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13715}
13716
13717/* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
13718 a normal call should be emitted rather than expanding the function
13719 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13720 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13721 passed as second argument. */
13722
13723tree
13724gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13725 enum built_in_function fcode)
13726{
13727 tree dest, size, len, fn, fmt, flag;
13728 const char *fmt_str;
13729
13730 /* Verify the required arguments in the original call. */
13731 if (gimple_call_num_args (stmt) < 5)
13732 return NULL_TREE;
13733 dest = gimple_call_arg (stmt, 0);
13734 if (!validate_arg (dest, POINTER_TYPE))
13735 return NULL_TREE;
13736 len = gimple_call_arg (stmt, 1);
13737 if (!validate_arg (len, INTEGER_TYPE))
13738 return NULL_TREE;
13739 flag = gimple_call_arg (stmt, 2);
13740 if (!validate_arg (flag, INTEGER_TYPE))
13741 return NULL_TREE;
13742 size = gimple_call_arg (stmt, 3);
13743 if (!validate_arg (size, INTEGER_TYPE))
13744 return NULL_TREE;
13745 fmt = gimple_call_arg (stmt, 4);
13746 if (!validate_arg (fmt, POINTER_TYPE))
13747 return NULL_TREE;
13748
13749 if (! host_integerp (size, 1))
13750 return NULL_TREE;
13751
13752 if (! integer_all_onesp (size))
13753 {
13754 if (! host_integerp (len, 1))
13755 {
13756 /* If LEN is not constant, try MAXLEN too.
13757 For MAXLEN only allow optimizing into non-_ocs function
13758 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13759 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13760 return NULL_TREE;
13761 }
13762 else
13763 maxlen = len;
13764
13765 if (tree_int_cst_lt (size, maxlen))
13766 return NULL_TREE;
13767 }
13768
13769 if (!init_target_chars ())
13770 return NULL_TREE;
13771
13772 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13773 or if format doesn't contain % chars or is "%s". */
13774 if (! integer_zerop (flag))
13775 {
13776 fmt_str = c_getstr (fmt);
13777 if (fmt_str == NULL)
13778 return NULL_TREE;
13779 if (strchr (fmt_str, target_percent) != NULL
13780 && strcmp (fmt_str, target_percent_s))
13781 return NULL_TREE;
13782 }
13783
13784 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13785 available. */
13786 fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13787 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13788 if (!fn)
13789 return NULL_TREE;
13790
13791 return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13792}
13793
13794/* Builtins with folding operations that operate on "..." arguments
13795 need special handling; we need to store the arguments in a convenient
13796 data structure before attempting any folding. Fortunately there are
13797 only a few builtins that fall into this category. FNDECL is the
13798 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13799 result of the function call is ignored. */
13800
13801static tree
db3927fb
AH
13802gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
13803 bool ignore ATTRIBUTE_UNUSED)
726a989a
RB
13804{
13805 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13806 tree ret = NULL_TREE;
13807
13808 switch (fcode)
13809 {
13810 case BUILT_IN_SPRINTF_CHK:
13811 case BUILT_IN_VSPRINTF_CHK:
13812 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13813 break;
13814
13815 case BUILT_IN_SNPRINTF_CHK:
13816 case BUILT_IN_VSNPRINTF_CHK:
13817 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13818
13819 default:
13820 break;
13821 }
13822 if (ret)
13823 {
13824 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13825 TREE_NO_WARNING (ret) = 1;
13826 return ret;
13827 }
13828 return NULL_TREE;
13829}
13830
13831/* A wrapper function for builtin folding that prevents warnings for
13832 "statement without effect" and the like, caused by removing the
13833 call node earlier than the warning is generated. */
13834
13835tree
13836fold_call_stmt (gimple stmt, bool ignore)
13837{
13838 tree ret = NULL_TREE;
13839 tree fndecl = gimple_call_fndecl (stmt);
db3927fb 13840 location_t loc = gimple_location (stmt);
726a989a
RB
13841 if (fndecl
13842 && TREE_CODE (fndecl) == FUNCTION_DECL
13843 && DECL_BUILT_IN (fndecl)
13844 && !gimple_call_va_arg_pack_p (stmt))
13845 {
13846 int nargs = gimple_call_num_args (stmt);
13847
0889e9bc
JJ
13848 if (avoid_folding_inline_builtin (fndecl))
13849 return NULL_TREE;
726a989a
RB
13850 /* FIXME: Don't use a list in this interface. */
13851 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13852 {
13853 tree arglist = NULL_TREE;
13854 int i;
13855 for (i = nargs - 1; i >= 0; i--)
13856 arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13857 return targetm.fold_builtin (fndecl, arglist, ignore);
13858 }
13859 else
13860 {
13861 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13862 {
13863 tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13864 int i;
13865 for (i = 0; i < nargs; i++)
13866 args[i] = gimple_call_arg (stmt, i);
db3927fb 13867 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
726a989a
RB
13868 }
13869 if (!ret)
13870 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13871 if (ret)
13872 {
13873 /* Propagate location information from original call to
13874 expansion of builtin. Otherwise things like
13875 maybe_emit_chk_warning, that operate on the expansion
13876 of a builtin, will use the wrong location information. */
13877 if (gimple_has_location (stmt))
13878 {
13879 tree realret = ret;
13880 if (TREE_CODE (ret) == NOP_EXPR)
13881 realret = TREE_OPERAND (ret, 0);
13882 if (CAN_HAVE_LOCATION_P (realret)
13883 && !EXPR_HAS_LOCATION (realret))
db3927fb 13884 SET_EXPR_LOCATION (realret, loc);
726a989a
RB
13885 return realret;
13886 }
13887 return ret;
13888 }
13889 }
13890 }
13891 return NULL_TREE;
13892}
d7f09764
DN
13893
13894/* Look up the function in built_in_decls that corresponds to DECL
13895 and set ASMSPEC as its user assembler name. DECL must be a
13896 function decl that declares a builtin. */
13897
13898void
13899set_builtin_user_assembler_name (tree decl, const char *asmspec)
13900{
13901 tree builtin;
13902 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
13903 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
13904 && asmspec != 0);
13905
13906 builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
13907 set_user_assembler_name (builtin, asmspec);
13908 switch (DECL_FUNCTION_CODE (decl))
13909 {
13910 case BUILT_IN_MEMCPY:
13911 init_block_move_fn (asmspec);
13912 memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
13913 break;
13914 case BUILT_IN_MEMSET:
13915 init_block_clear_fn (asmspec);
13916 memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
13917 break;
13918 case BUILT_IN_MEMMOVE:
13919 memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
13920 break;
13921 case BUILT_IN_MEMCMP:
13922 memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
13923 break;
13924 case BUILT_IN_ABORT:
13925 abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
13926 break;
13927 default:
13928 break;
13929 }
13930}