2012-07-06 Tom de Vries <tom@codesourcery.com>
[official-gcc.git] / gcc / builtins.c
blobc12eb29aa02d561241ecfef3788da3e9dca4d4d7
1 /* Expand builtin functions.
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
4 2012 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "realmpfr.h"
30 #include "gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
47 #include "basic-block.h"
48 #include "tree-mudflap.h"
49 #include "tree-flow.h"
50 #include "value-prof.h"
51 #include "diagnostic-core.h"
52 #include "builtins.h"
55 #ifndef PAD_VARARGS_DOWN
56 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
57 #endif
58 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
60 struct target_builtins default_target_builtins;
61 #if SWITCHABLE_TARGET
62 struct target_builtins *this_target_builtins = &default_target_builtins;
63 #endif
65 /* Define the names of the builtin function types and codes. */
66 const char *const built_in_class_names[4]
67 = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
69 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
70 const char * built_in_names[(int) END_BUILTINS] =
72 #include "builtins.def"
74 #undef DEF_BUILTIN
76 /* Setup an array of _DECL trees, make sure each element is
77 initialized to NULL_TREE. */
78 builtin_info_type builtin_info;
80 static const char *c_getstr (tree);
81 static rtx c_readstr (const char *, enum machine_mode);
82 static int target_char_cast (tree, char *);
83 static rtx get_memory_rtx (tree, tree);
84 static int apply_args_size (void);
85 static int apply_result_size (void);
86 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
87 static rtx result_vector (int, rtx);
88 #endif
89 static void expand_builtin_update_setjmp_buf (rtx);
90 static void expand_builtin_prefetch (tree);
91 static rtx expand_builtin_apply_args (void);
92 static rtx expand_builtin_apply_args_1 (void);
93 static rtx expand_builtin_apply (rtx, rtx, rtx);
94 static void expand_builtin_return (rtx);
95 static enum type_class type_to_class (tree);
96 static rtx expand_builtin_classify_type (tree);
97 static void expand_errno_check (tree, rtx);
98 static rtx expand_builtin_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
101 static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
102 static rtx expand_builtin_interclass_mathfn (tree, rtx);
103 static rtx expand_builtin_sincos (tree);
104 static rtx expand_builtin_cexpi (tree, rtx);
105 static rtx expand_builtin_int_roundingfn (tree, rtx);
106 static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
107 static rtx expand_builtin_next_arg (void);
108 static rtx expand_builtin_va_start (tree);
109 static rtx expand_builtin_va_end (tree);
110 static rtx expand_builtin_va_copy (tree);
111 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcmp (tree, rtx);
113 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
114 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
115 static rtx expand_builtin_memcpy (tree, rtx);
116 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
118 enum machine_mode, int);
119 static rtx expand_builtin_strcpy (tree, rtx);
120 static rtx expand_builtin_strcpy_args (tree, tree, rtx);
121 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_strncpy (tree, rtx);
123 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
126 static rtx expand_builtin_bzero (tree);
127 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, bool);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static tree stabilize_va_list_loc (location_t, tree, int);
132 static rtx expand_builtin_expect (tree, rtx);
133 static tree fold_builtin_constant_p (tree);
134 static tree fold_builtin_expect (location_t, tree, tree);
135 static tree fold_builtin_classify_type (tree);
136 static tree fold_builtin_strlen (location_t, tree, tree);
137 static tree fold_builtin_inf (location_t, tree, int);
138 static tree fold_builtin_nan (tree, tree, int);
139 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
140 static bool validate_arg (const_tree, enum tree_code code);
141 static bool integer_valued_real_p (tree);
142 static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
143 static bool readonly_data_expr (tree);
144 static rtx expand_builtin_fabs (tree, rtx, rtx);
145 static rtx expand_builtin_signbit (tree, rtx);
146 static tree fold_builtin_sqrt (location_t, tree, tree);
147 static tree fold_builtin_cbrt (location_t, tree, tree);
148 static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
149 static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
150 static tree fold_builtin_cos (location_t, tree, tree, tree);
151 static tree fold_builtin_cosh (location_t, tree, tree, tree);
152 static tree fold_builtin_tan (tree, tree);
153 static tree fold_builtin_trunc (location_t, tree, tree);
154 static tree fold_builtin_floor (location_t, tree, tree);
155 static tree fold_builtin_ceil (location_t, tree, tree);
156 static tree fold_builtin_round (location_t, tree, tree);
157 static tree fold_builtin_int_roundingfn (location_t, tree, tree);
158 static tree fold_builtin_bitop (tree, tree);
159 static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
160 static tree fold_builtin_strchr (location_t, tree, tree, tree);
161 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
162 static tree fold_builtin_memcmp (location_t, tree, tree, tree);
163 static tree fold_builtin_strcmp (location_t, tree, tree);
164 static tree fold_builtin_strncmp (location_t, tree, tree, tree);
165 static tree fold_builtin_signbit (location_t, tree, tree);
166 static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
167 static tree fold_builtin_isascii (location_t, tree);
168 static tree fold_builtin_toascii (location_t, tree);
169 static tree fold_builtin_isdigit (location_t, tree);
170 static tree fold_builtin_fabs (location_t, tree, tree);
171 static tree fold_builtin_abs (location_t, tree, tree);
172 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
173 enum tree_code);
174 static tree fold_builtin_n (location_t, tree, tree *, int, bool);
175 static tree fold_builtin_0 (location_t, tree, bool);
176 static tree fold_builtin_1 (location_t, tree, tree, bool);
177 static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
178 static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
179 static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
180 static tree fold_builtin_varargs (location_t, tree, tree, bool);
182 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
183 static tree fold_builtin_strstr (location_t, tree, tree, tree);
184 static tree fold_builtin_strrchr (location_t, tree, tree, tree);
185 static tree fold_builtin_strcat (location_t, tree, tree);
186 static tree fold_builtin_strncat (location_t, tree, tree, tree);
187 static tree fold_builtin_strspn (location_t, tree, tree);
188 static tree fold_builtin_strcspn (location_t, tree, tree);
189 static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
190 static tree fold_builtin_snprintf (location_t, tree, tree, tree, tree, int);
192 static rtx expand_builtin_object_size (tree);
193 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
194 enum built_in_function);
195 static void maybe_emit_chk_warning (tree, enum built_in_function);
196 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
197 static void maybe_emit_free_warning (tree);
198 static tree fold_builtin_object_size (tree, tree);
199 static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
200 static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
201 static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
202 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
203 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
204 enum built_in_function);
205 static bool init_target_chars (void);
207 static unsigned HOST_WIDE_INT target_newline;
208 static unsigned HOST_WIDE_INT target_percent;
209 static unsigned HOST_WIDE_INT target_c;
210 static unsigned HOST_WIDE_INT target_s;
211 static char target_percent_c[3];
212 static char target_percent_s[3];
213 static char target_percent_s_newline[4];
214 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
215 const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
216 static tree do_mpfr_arg2 (tree, tree, tree,
217 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
218 static tree do_mpfr_arg3 (tree, tree, tree, tree,
219 int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
220 static tree do_mpfr_sincos (tree, tree, tree);
221 static tree do_mpfr_bessel_n (tree, tree, tree,
222 int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
223 const REAL_VALUE_TYPE *, bool);
224 static tree do_mpfr_remquo (tree, tree, tree);
225 static tree do_mpfr_lgamma_r (tree, tree, tree);
226 static void expand_builtin_sync_synchronize (void);
228 /* Return true if NAME starts with __builtin_ or __sync_. */
230 static bool
231 is_builtin_name (const char *name)
233 if (strncmp (name, "__builtin_", 10) == 0)
234 return true;
235 if (strncmp (name, "__sync_", 7) == 0)
236 return true;
237 if (strncmp (name, "__atomic_", 9) == 0)
238 return true;
239 return false;
243 /* Return true if DECL is a function symbol representing a built-in. */
245 bool
246 is_builtin_fn (tree decl)
248 return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
252 /* Return true if NODE should be considered for inline expansion regardless
253 of the optimization level. This means whenever a function is invoked with
254 its "internal" name, which normally contains the prefix "__builtin". */
256 static bool
257 called_as_built_in (tree node)
259 /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
260 we want the name used to call the function, not the name it
261 will have. */
262 const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
263 return is_builtin_name (name);
266 /* Compute values M and N such that M divides (address of EXP - N) and such
267 that N < M. If these numbers can be determined, store M in alignp and N in
268 *BITPOSP and return true. Otherwise return false and store BITS_PER_UNIT to
269 *alignp and any bit-offset to *bitposp.
271 Note that the address (and thus the alignment) computed here is based
272 on the address to which a symbol resolves, whereas DECL_ALIGN is based
273 on the address at which an object is actually located. These two
274 addresses are not always the same. For example, on ARM targets,
275 the address &foo of a Thumb function foo() has the lowest bit set,
276 whereas foo() itself starts on an even address. */
278 bool
279 get_object_alignment_1 (tree exp, unsigned int *alignp,
280 unsigned HOST_WIDE_INT *bitposp)
282 HOST_WIDE_INT bitsize, bitpos;
283 tree offset;
284 enum machine_mode mode;
285 int unsignedp, volatilep;
286 unsigned int inner, align = BITS_PER_UNIT;
287 bool known_alignment = false;
289 /* Get the innermost object and the constant (bitpos) and possibly
290 variable (offset) offset of the access. */
291 exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
292 &mode, &unsignedp, &volatilep, true);
294 /* Extract alignment information from the innermost object and
295 possibly adjust bitpos and offset. */
296 if (TREE_CODE (exp) == CONST_DECL)
297 exp = DECL_INITIAL (exp);
298 if (DECL_P (exp)
299 && TREE_CODE (exp) != LABEL_DECL)
301 if (TREE_CODE (exp) == FUNCTION_DECL)
303 /* Function addresses can encode extra information besides their
304 alignment. However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
305 allows the low bit to be used as a virtual bit, we know
306 that the address itself must be 2-byte aligned. */
307 if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
309 known_alignment = true;
310 align = 2 * BITS_PER_UNIT;
313 else
315 known_alignment = true;
316 align = DECL_ALIGN (exp);
319 else if (CONSTANT_CLASS_P (exp))
321 known_alignment = true;
322 align = TYPE_ALIGN (TREE_TYPE (exp));
323 #ifdef CONSTANT_ALIGNMENT
324 align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
325 #endif
327 else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
329 known_alignment = true;
330 align = TYPE_ALIGN (TREE_TYPE (exp));
332 else if (TREE_CODE (exp) == INDIRECT_REF)
334 known_alignment = true;
335 align = TYPE_ALIGN (TREE_TYPE (exp));
337 else if (TREE_CODE (exp) == MEM_REF)
339 tree addr = TREE_OPERAND (exp, 0);
340 unsigned ptr_align;
341 unsigned HOST_WIDE_INT ptr_bitpos;
343 if (TREE_CODE (addr) == BIT_AND_EXPR
344 && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
346 known_alignment = true;
347 align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
348 & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
349 align *= BITS_PER_UNIT;
350 addr = TREE_OPERAND (addr, 0);
353 if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
355 known_alignment = true;
356 bitpos += ptr_bitpos & ~(align - 1);
357 align = MAX (ptr_align, align);
360 bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
362 else if (TREE_CODE (exp) == TARGET_MEM_REF)
364 unsigned ptr_align;
365 unsigned HOST_WIDE_INT ptr_bitpos;
366 tree addr = TMR_BASE (exp);
368 if (TREE_CODE (addr) == BIT_AND_EXPR
369 && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
371 known_alignment = true;
372 align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
373 & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
374 align *= BITS_PER_UNIT;
375 addr = TREE_OPERAND (addr, 0);
378 if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
380 known_alignment = true;
381 bitpos += ptr_bitpos & ~(align - 1);
382 align = MAX (ptr_align, align);
385 if (TMR_OFFSET (exp))
386 bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
387 if (TMR_INDEX (exp) && TMR_STEP (exp))
389 unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
390 align = MIN (align, (step & -step) * BITS_PER_UNIT);
391 known_alignment = true;
393 else if (TMR_INDEX (exp))
394 known_alignment = false;
396 if (TMR_INDEX2 (exp))
397 known_alignment = false;
400 /* If there is a non-constant offset part extract the maximum
401 alignment that can prevail. */
402 inner = ~0U;
403 while (offset)
405 tree next_offset;
407 if (TREE_CODE (offset) == PLUS_EXPR)
409 next_offset = TREE_OPERAND (offset, 0);
410 offset = TREE_OPERAND (offset, 1);
412 else
413 next_offset = NULL;
414 if (host_integerp (offset, 1))
416 /* Any overflow in calculating offset_bits won't change
417 the alignment. */
418 unsigned offset_bits
419 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
421 if (offset_bits)
422 inner = MIN (inner, (offset_bits & -offset_bits));
424 else if (TREE_CODE (offset) == MULT_EXPR
425 && host_integerp (TREE_OPERAND (offset, 1), 1))
427 /* Any overflow in calculating offset_factor won't change
428 the alignment. */
429 unsigned offset_factor
430 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
431 * BITS_PER_UNIT);
433 if (offset_factor)
434 inner = MIN (inner, (offset_factor & -offset_factor));
436 else
438 known_alignment = false;
439 break;
441 offset = next_offset;
444 if (known_alignment)
446 /* Alignment is innermost object alignment adjusted by the constant
447 and non-constant offset parts. */
448 align = MIN (align, inner);
449 bitpos = bitpos & (align - 1);
450 *alignp = align;
452 else
454 bitpos = bitpos & (BITS_PER_UNIT - 1);
455 *alignp = BITS_PER_UNIT;
457 *bitposp = bitpos;
458 return known_alignment;
461 /* Return the alignment in bits of EXP, an object. */
463 unsigned int
464 get_object_alignment (tree exp)
466 unsigned HOST_WIDE_INT bitpos = 0;
467 unsigned int align;
469 get_object_alignment_1 (exp, &align, &bitpos);
471 /* align and bitpos now specify known low bits of the pointer.
472 ptr & (align - 1) == bitpos. */
474 if (bitpos != 0)
475 align = (bitpos & -bitpos);
476 return align;
479 /* Return the alignment of object EXP, also considering its type when we do
480 not know of explicit misalignment. Only handle MEM_REF and TARGET_MEM_REF.
482 ??? Note that, in the general case, the type of an expression is not kept
483 consistent with misalignment information by the front-end, for example when
484 taking the address of a member of a packed structure. However, in most of
485 the cases, expressions have the alignment of their type so we optimistically
486 fall back to this alignment when we cannot compute a misalignment. */
488 unsigned int
489 get_object_or_type_alignment (tree exp)
491 unsigned HOST_WIDE_INT misalign;
492 unsigned int align;
493 bool known_alignment;
495 gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
496 known_alignment = get_object_alignment_1 (exp, &align, &misalign);
497 if (misalign != 0)
498 align = (misalign & -misalign);
499 else if (!known_alignment)
500 align = TYPE_ALIGN (TREE_TYPE (exp));
502 return align;
505 /* For a pointer valued expression EXP compute values M and N such that M
506 divides (EXP - N) and such that N < M. If these numbers can be determined,
507 store M in alignp and N in *BITPOSP and return true. Otherwise return false
508 and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp.
510 If EXP is not a pointer, false is returned too. */
512 bool
513 get_pointer_alignment_1 (tree exp, unsigned int *alignp,
514 unsigned HOST_WIDE_INT *bitposp)
516 STRIP_NOPS (exp);
518 if (TREE_CODE (exp) == ADDR_EXPR)
519 return get_object_alignment_1 (TREE_OPERAND (exp, 0), alignp, bitposp);
520 else if (TREE_CODE (exp) == SSA_NAME
521 && POINTER_TYPE_P (TREE_TYPE (exp)))
523 unsigned int ptr_align, ptr_misalign;
524 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
526 if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
528 *bitposp = ptr_misalign * BITS_PER_UNIT;
529 *alignp = ptr_align * BITS_PER_UNIT;
530 return true;
532 else
534 *bitposp = 0;
535 *alignp = BITS_PER_UNIT;
536 return false;
540 *bitposp = 0;
541 *alignp = BITS_PER_UNIT;
542 return false;
545 /* Return the alignment in bits of EXP, a pointer valued expression.
546 The alignment returned is, by default, the alignment of the thing that
547 EXP points to. If it is not a POINTER_TYPE, 0 is returned.
549 Otherwise, look at the expression to see if we can do better, i.e., if the
550 expression is actually pointing at an object whose alignment is tighter. */
552 unsigned int
553 get_pointer_alignment (tree exp)
555 unsigned HOST_WIDE_INT bitpos = 0;
556 unsigned int align;
558 get_pointer_alignment_1 (exp, &align, &bitpos);
560 /* align and bitpos now specify known low bits of the pointer.
561 ptr & (align - 1) == bitpos. */
563 if (bitpos != 0)
564 align = (bitpos & -bitpos);
566 return align;
569 /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
570 way, because it could contain a zero byte in the middle.
571 TREE_STRING_LENGTH is the size of the character array, not the string.
573 ONLY_VALUE should be nonzero if the result is not going to be emitted
574 into the instruction stream and zero if it is going to be expanded.
575 E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
576 is returned, otherwise NULL, since
577 len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
578 evaluate the side-effects.
580 The value returned is of type `ssizetype'.
582 Unfortunately, string_constant can't access the values of const char
583 arrays with initializers, so neither can we do so here. */
585 tree
586 c_strlen (tree src, int only_value)
588 tree offset_node;
589 HOST_WIDE_INT offset;
590 int max;
591 const char *ptr;
592 location_t loc;
594 STRIP_NOPS (src);
595 if (TREE_CODE (src) == COND_EXPR
596 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
598 tree len1, len2;
600 len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
601 len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
602 if (tree_int_cst_equal (len1, len2))
603 return len1;
606 if (TREE_CODE (src) == COMPOUND_EXPR
607 && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
608 return c_strlen (TREE_OPERAND (src, 1), only_value);
610 loc = EXPR_LOC_OR_HERE (src);
612 src = string_constant (src, &offset_node);
613 if (src == 0)
614 return NULL_TREE;
616 max = TREE_STRING_LENGTH (src) - 1;
617 ptr = TREE_STRING_POINTER (src);
619 if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
621 /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
622 compute the offset to the following null if we don't know where to
623 start searching for it. */
624 int i;
626 for (i = 0; i < max; i++)
627 if (ptr[i] == 0)
628 return NULL_TREE;
630 /* We don't know the starting offset, but we do know that the string
631 has no internal zero bytes. We can assume that the offset falls
632 within the bounds of the string; otherwise, the programmer deserves
633 what he gets. Subtract the offset from the length of the string,
634 and return that. This would perhaps not be valid if we were dealing
635 with named arrays in addition to literal string constants. */
637 return size_diffop_loc (loc, size_int (max), offset_node);
640 /* We have a known offset into the string. Start searching there for
641 a null character if we can represent it as a single HOST_WIDE_INT. */
642 if (offset_node == 0)
643 offset = 0;
644 else if (! host_integerp (offset_node, 0))
645 offset = -1;
646 else
647 offset = tree_low_cst (offset_node, 0);
649 /* If the offset is known to be out of bounds, warn, and call strlen at
650 runtime. */
651 if (offset < 0 || offset > max)
653 /* Suppress multiple warnings for propagated constant strings. */
654 if (! TREE_NO_WARNING (src))
656 warning_at (loc, 0, "offset outside bounds of constant string");
657 TREE_NO_WARNING (src) = 1;
659 return NULL_TREE;
662 /* Use strlen to search for the first zero byte. Since any strings
663 constructed with build_string will have nulls appended, we win even
664 if we get handed something like (char[4])"abcd".
666 Since OFFSET is our starting index into the string, no further
667 calculation is needed. */
668 return ssize_int (strlen (ptr + offset));
671 /* Return a char pointer for a C string if it is a string constant
672 or sum of string constant and integer constant. */
674 static const char *
675 c_getstr (tree src)
677 tree offset_node;
679 src = string_constant (src, &offset_node);
680 if (src == 0)
681 return 0;
683 if (offset_node == 0)
684 return TREE_STRING_POINTER (src);
685 else if (!host_integerp (offset_node, 1)
686 || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
687 return 0;
689 return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
692 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
693 GET_MODE_BITSIZE (MODE) bits from string constant STR. */
695 static rtx
696 c_readstr (const char *str, enum machine_mode mode)
698 HOST_WIDE_INT c[2];
699 HOST_WIDE_INT ch;
700 unsigned int i, j;
702 gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
704 c[0] = 0;
705 c[1] = 0;
706 ch = 1;
707 for (i = 0; i < GET_MODE_SIZE (mode); i++)
709 j = i;
710 if (WORDS_BIG_ENDIAN)
711 j = GET_MODE_SIZE (mode) - i - 1;
712 if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
713 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
714 j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
715 j *= BITS_PER_UNIT;
716 gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
718 if (ch)
719 ch = (unsigned char) str[i];
720 c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
722 return immed_double_const (c[0], c[1], mode);
725 /* Cast a target constant CST to target CHAR and if that value fits into
726 host char type, return zero and put that value into variable pointed to by
727 P. */
729 static int
730 target_char_cast (tree cst, char *p)
732 unsigned HOST_WIDE_INT val, hostval;
734 if (TREE_CODE (cst) != INTEGER_CST
735 || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
736 return 1;
738 val = TREE_INT_CST_LOW (cst);
739 if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
740 val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
742 hostval = val;
743 if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
744 hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
746 if (val != hostval)
747 return 1;
749 *p = hostval;
750 return 0;
753 /* Similar to save_expr, but assumes that arbitrary code is not executed
754 in between the multiple evaluations. In particular, we assume that a
755 non-addressable local variable will not be modified. */
757 static tree
758 builtin_save_expr (tree exp)
760 if (TREE_CODE (exp) == SSA_NAME
761 || (TREE_ADDRESSABLE (exp) == 0
762 && (TREE_CODE (exp) == PARM_DECL
763 || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))))
764 return exp;
766 return save_expr (exp);
769 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
770 times to get the address of either a higher stack frame, or a return
771 address located within it (depending on FNDECL_CODE). */
773 static rtx
774 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
776 int i;
778 #ifdef INITIAL_FRAME_ADDRESS_RTX
779 rtx tem = INITIAL_FRAME_ADDRESS_RTX;
780 #else
781 rtx tem;
783 /* For a zero count with __builtin_return_address, we don't care what
784 frame address we return, because target-specific definitions will
785 override us. Therefore frame pointer elimination is OK, and using
786 the soft frame pointer is OK.
788 For a nonzero count, or a zero count with __builtin_frame_address,
789 we require a stable offset from the current frame pointer to the
790 previous one, so we must use the hard frame pointer, and
791 we must disable frame pointer elimination. */
792 if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
793 tem = frame_pointer_rtx;
794 else
796 tem = hard_frame_pointer_rtx;
798 /* Tell reload not to eliminate the frame pointer. */
799 crtl->accesses_prior_frames = 1;
801 #endif
803 /* Some machines need special handling before we can access
804 arbitrary frames. For example, on the SPARC, we must first flush
805 all register windows to the stack. */
806 #ifdef SETUP_FRAME_ADDRESSES
807 if (count > 0)
808 SETUP_FRAME_ADDRESSES ();
809 #endif
811 /* On the SPARC, the return address is not in the frame, it is in a
812 register. There is no way to access it off of the current frame
813 pointer, but it can be accessed off the previous frame pointer by
814 reading the value from the register window save area. */
815 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
816 if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
817 count--;
818 #endif
820 /* Scan back COUNT frames to the specified frame. */
821 for (i = 0; i < count; i++)
823 /* Assume the dynamic chain pointer is in the word that the
824 frame address points to, unless otherwise specified. */
825 #ifdef DYNAMIC_CHAIN_ADDRESS
826 tem = DYNAMIC_CHAIN_ADDRESS (tem);
827 #endif
828 tem = memory_address (Pmode, tem);
829 tem = gen_frame_mem (Pmode, tem);
830 tem = copy_to_reg (tem);
833 /* For __builtin_frame_address, return what we've got. But, on
834 the SPARC for example, we may have to add a bias. */
835 if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
836 #ifdef FRAME_ADDR_RTX
837 return FRAME_ADDR_RTX (tem);
838 #else
839 return tem;
840 #endif
842 /* For __builtin_return_address, get the return address from that frame. */
843 #ifdef RETURN_ADDR_RTX
844 tem = RETURN_ADDR_RTX (count, tem);
845 #else
846 tem = memory_address (Pmode,
847 plus_constant (Pmode, tem, GET_MODE_SIZE (Pmode)));
848 tem = gen_frame_mem (Pmode, tem);
849 #endif
850 return tem;
853 /* Alias set used for setjmp buffer. */
854 static alias_set_type setjmp_alias_set = -1;
856 /* Construct the leading half of a __builtin_setjmp call. Control will
857 return to RECEIVER_LABEL. This is also called directly by the SJLJ
858 exception handling code. */
860 void
861 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
863 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
864 rtx stack_save;
865 rtx mem;
867 if (setjmp_alias_set == -1)
868 setjmp_alias_set = new_alias_set ();
870 buf_addr = convert_memory_address (Pmode, buf_addr);
872 buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
874 /* We store the frame pointer and the address of receiver_label in
875 the buffer and use the rest of it for the stack save area, which
876 is machine-dependent. */
878 mem = gen_rtx_MEM (Pmode, buf_addr);
879 set_mem_alias_set (mem, setjmp_alias_set);
880 emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
882 mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
883 GET_MODE_SIZE (Pmode))),
884 set_mem_alias_set (mem, setjmp_alias_set);
886 emit_move_insn (validize_mem (mem),
887 force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
889 stack_save = gen_rtx_MEM (sa_mode,
890 plus_constant (Pmode, buf_addr,
891 2 * GET_MODE_SIZE (Pmode)));
892 set_mem_alias_set (stack_save, setjmp_alias_set);
893 emit_stack_save (SAVE_NONLOCAL, &stack_save);
895 /* If there is further processing to do, do it. */
896 #ifdef HAVE_builtin_setjmp_setup
897 if (HAVE_builtin_setjmp_setup)
898 emit_insn (gen_builtin_setjmp_setup (buf_addr));
899 #endif
901 /* We have a nonlocal label. */
902 cfun->has_nonlocal_label = 1;
905 /* Construct the trailing part of a __builtin_setjmp call. This is
906 also called directly by the SJLJ exception handling code. */
908 void
909 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
911 rtx chain;
913 /* Clobber the FP when we get here, so we have to make sure it's
914 marked as used by this function. */
915 emit_use (hard_frame_pointer_rtx);
917 /* Mark the static chain as clobbered here so life information
918 doesn't get messed up for it. */
919 chain = targetm.calls.static_chain (current_function_decl, true);
920 if (chain && REG_P (chain))
921 emit_clobber (chain);
923 /* Now put in the code to restore the frame pointer, and argument
924 pointer, if needed. */
925 #ifdef HAVE_nonlocal_goto
926 if (! HAVE_nonlocal_goto)
927 #endif
929 emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
930 /* This might change the hard frame pointer in ways that aren't
931 apparent to early optimization passes, so force a clobber. */
932 emit_clobber (hard_frame_pointer_rtx);
935 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
936 if (fixed_regs[ARG_POINTER_REGNUM])
938 #ifdef ELIMINABLE_REGS
939 size_t i;
940 static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
942 for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
943 if (elim_regs[i].from == ARG_POINTER_REGNUM
944 && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
945 break;
947 if (i == ARRAY_SIZE (elim_regs))
948 #endif
950 /* Now restore our arg pointer from the address at which it
951 was saved in our stack frame. */
952 emit_move_insn (crtl->args.internal_arg_pointer,
953 copy_to_reg (get_arg_pointer_save_area ()));
956 #endif
958 #ifdef HAVE_builtin_setjmp_receiver
959 if (HAVE_builtin_setjmp_receiver)
960 emit_insn (gen_builtin_setjmp_receiver (receiver_label));
961 else
962 #endif
963 #ifdef HAVE_nonlocal_goto_receiver
964 if (HAVE_nonlocal_goto_receiver)
965 emit_insn (gen_nonlocal_goto_receiver ());
966 else
967 #endif
968 { /* Nothing */ }
970 /* We must not allow the code we just generated to be reordered by
971 scheduling. Specifically, the update of the frame pointer must
972 happen immediately, not later. */
973 emit_insn (gen_blockage ());
976 /* __builtin_longjmp is passed a pointer to an array of five words (not
977 all will be used on all machines). It operates similarly to the C
978 library function of the same name, but is more efficient. Much of
979 the code below is copied from the handling of non-local gotos. */
981 static void
982 expand_builtin_longjmp (rtx buf_addr, rtx value)
984 rtx fp, lab, stack, insn, last;
985 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
987 /* DRAP is needed for stack realign if longjmp is expanded to current
988 function */
989 if (SUPPORTS_STACK_ALIGNMENT)
990 crtl->need_drap = true;
992 if (setjmp_alias_set == -1)
993 setjmp_alias_set = new_alias_set ();
995 buf_addr = convert_memory_address (Pmode, buf_addr);
997 buf_addr = force_reg (Pmode, buf_addr);
999 /* We require that the user must pass a second argument of 1, because
1000 that is what builtin_setjmp will return. */
1001 gcc_assert (value == const1_rtx);
1003 last = get_last_insn ();
1004 #ifdef HAVE_builtin_longjmp
1005 if (HAVE_builtin_longjmp)
1006 emit_insn (gen_builtin_longjmp (buf_addr));
1007 else
1008 #endif
1010 fp = gen_rtx_MEM (Pmode, buf_addr);
1011 lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
1012 GET_MODE_SIZE (Pmode)));
1014 stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, buf_addr,
1015 2 * GET_MODE_SIZE (Pmode)));
1016 set_mem_alias_set (fp, setjmp_alias_set);
1017 set_mem_alias_set (lab, setjmp_alias_set);
1018 set_mem_alias_set (stack, setjmp_alias_set);
1020 /* Pick up FP, label, and SP from the block and jump. This code is
1021 from expand_goto in stmt.c; see there for detailed comments. */
1022 #ifdef HAVE_nonlocal_goto
1023 if (HAVE_nonlocal_goto)
1024 /* We have to pass a value to the nonlocal_goto pattern that will
1025 get copied into the static_chain pointer, but it does not matter
1026 what that value is, because builtin_setjmp does not use it. */
1027 emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
1028 else
1029 #endif
1031 lab = copy_to_reg (lab);
1033 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1034 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1036 emit_move_insn (hard_frame_pointer_rtx, fp);
1037 emit_stack_restore (SAVE_NONLOCAL, stack);
1039 emit_use (hard_frame_pointer_rtx);
1040 emit_use (stack_pointer_rtx);
1041 emit_indirect_jump (lab);
1045 /* Search backwards and mark the jump insn as a non-local goto.
1046 Note that this precludes the use of __builtin_longjmp to a
1047 __builtin_setjmp target in the same function. However, we've
1048 already cautioned the user that these functions are for
1049 internal exception handling use only. */
1050 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1052 gcc_assert (insn != last);
1054 if (JUMP_P (insn))
1056 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1057 break;
1059 else if (CALL_P (insn))
1060 break;
1064 /* Expand a call to __builtin_nonlocal_goto. We're passed the target label
1065 and the address of the save area. */
1067 static rtx
1068 expand_builtin_nonlocal_goto (tree exp)
1070 tree t_label, t_save_area;
1071 rtx r_label, r_save_area, r_fp, r_sp, insn;
1073 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1074 return NULL_RTX;
1076 t_label = CALL_EXPR_ARG (exp, 0);
1077 t_save_area = CALL_EXPR_ARG (exp, 1);
1079 r_label = expand_normal (t_label);
1080 r_label = convert_memory_address (Pmode, r_label);
1081 r_save_area = expand_normal (t_save_area);
1082 r_save_area = convert_memory_address (Pmode, r_save_area);
1083 /* Copy the address of the save location to a register just in case it was
1084 based on the frame pointer. */
1085 r_save_area = copy_to_reg (r_save_area);
1086 r_fp = gen_rtx_MEM (Pmode, r_save_area);
1087 r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
1088 plus_constant (Pmode, r_save_area,
1089 GET_MODE_SIZE (Pmode)));
1091 crtl->has_nonlocal_goto = 1;
1093 #ifdef HAVE_nonlocal_goto
1094 /* ??? We no longer need to pass the static chain value, afaik. */
1095 if (HAVE_nonlocal_goto)
1096 emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
1097 else
1098 #endif
1100 r_label = copy_to_reg (r_label);
1102 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1103 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1105 /* Restore frame pointer for containing function. */
1106 emit_move_insn (hard_frame_pointer_rtx, r_fp);
1107 emit_stack_restore (SAVE_NONLOCAL, r_sp);
1109 /* USE of hard_frame_pointer_rtx added for consistency;
1110 not clear if really needed. */
1111 emit_use (hard_frame_pointer_rtx);
1112 emit_use (stack_pointer_rtx);
1114 /* If the architecture is using a GP register, we must
1115 conservatively assume that the target function makes use of it.
1116 The prologue of functions with nonlocal gotos must therefore
1117 initialize the GP register to the appropriate value, and we
1118 must then make sure that this value is live at the point
1119 of the jump. (Note that this doesn't necessarily apply
1120 to targets with a nonlocal_goto pattern; they are free
1121 to implement it in their own way. Note also that this is
1122 a no-op if the GP register is a global invariant.) */
1123 if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
1124 && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
1125 emit_use (pic_offset_table_rtx);
1127 emit_indirect_jump (r_label);
1130 /* Search backwards to the jump insn and mark it as a
1131 non-local goto. */
1132 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1134 if (JUMP_P (insn))
1136 add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1137 break;
1139 else if (CALL_P (insn))
1140 break;
1143 return const0_rtx;
1146 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
1147 (not all will be used on all machines) that was passed to __builtin_setjmp.
1148 It updates the stack pointer in that block to correspond to the current
1149 stack pointer. */
1151 static void
1152 expand_builtin_update_setjmp_buf (rtx buf_addr)
1154 enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1155 rtx stack_save
1156 = gen_rtx_MEM (sa_mode,
1157 memory_address
1158 (sa_mode,
1159 plus_constant (Pmode, buf_addr,
1160 2 * GET_MODE_SIZE (Pmode))));
1162 emit_stack_save (SAVE_NONLOCAL, &stack_save);
1165 /* Expand a call to __builtin_prefetch. For a target that does not support
1166 data prefetch, evaluate the memory address argument in case it has side
1167 effects. */
1169 static void
1170 expand_builtin_prefetch (tree exp)
1172 tree arg0, arg1, arg2;
1173 int nargs;
1174 rtx op0, op1, op2;
1176 if (!validate_arglist (exp, POINTER_TYPE, 0))
1177 return;
1179 arg0 = CALL_EXPR_ARG (exp, 0);
1181 /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1182 zero (read) and argument 2 (locality) defaults to 3 (high degree of
1183 locality). */
1184 nargs = call_expr_nargs (exp);
1185 if (nargs > 1)
1186 arg1 = CALL_EXPR_ARG (exp, 1);
1187 else
1188 arg1 = integer_zero_node;
1189 if (nargs > 2)
1190 arg2 = CALL_EXPR_ARG (exp, 2);
1191 else
1192 arg2 = integer_three_node;
1194 /* Argument 0 is an address. */
1195 op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1197 /* Argument 1 (read/write flag) must be a compile-time constant int. */
1198 if (TREE_CODE (arg1) != INTEGER_CST)
1200 error ("second argument to %<__builtin_prefetch%> must be a constant");
1201 arg1 = integer_zero_node;
1203 op1 = expand_normal (arg1);
1204 /* Argument 1 must be either zero or one. */
1205 if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1207 warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1208 " using zero");
1209 op1 = const0_rtx;
1212 /* Argument 2 (locality) must be a compile-time constant int. */
1213 if (TREE_CODE (arg2) != INTEGER_CST)
1215 error ("third argument to %<__builtin_prefetch%> must be a constant");
1216 arg2 = integer_zero_node;
1218 op2 = expand_normal (arg2);
1219 /* Argument 2 must be 0, 1, 2, or 3. */
1220 if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1222 warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1223 op2 = const0_rtx;
1226 #ifdef HAVE_prefetch
1227 if (HAVE_prefetch)
1229 struct expand_operand ops[3];
1231 create_address_operand (&ops[0], op0);
1232 create_integer_operand (&ops[1], INTVAL (op1));
1233 create_integer_operand (&ops[2], INTVAL (op2));
1234 if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops))
1235 return;
1237 #endif
1239 /* Don't do anything with direct references to volatile memory, but
1240 generate code to handle other side effects. */
1241 if (!MEM_P (op0) && side_effects_p (op0))
1242 emit_insn (op0);
1245 /* Get a MEM rtx for expression EXP which is the address of an operand
1246 to be used in a string instruction (cmpstrsi, movmemsi, ..). LEN is
1247 the maximum length of the block of memory that might be accessed or
1248 NULL if unknown. */
1250 static rtx
1251 get_memory_rtx (tree exp, tree len)
1253 tree orig_exp = exp;
1254 rtx addr, mem;
1256 /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1257 from its expression, for expr->a.b only <variable>.a.b is recorded. */
1258 if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1259 exp = TREE_OPERAND (exp, 0);
1261 addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1262 mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1264 /* Get an expression we can use to find the attributes to assign to MEM.
1265 First remove any nops. */
1266 while (CONVERT_EXPR_P (exp)
1267 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1268 exp = TREE_OPERAND (exp, 0);
1270 /* Build a MEM_REF representing the whole accessed area as a byte blob,
1271 (as builtin stringops may alias with anything). */
1272 exp = fold_build2 (MEM_REF,
1273 build_array_type (char_type_node,
1274 build_range_type (sizetype,
1275 size_one_node, len)),
1276 exp, build_int_cst (ptr_type_node, 0));
1278 /* If the MEM_REF has no acceptable address, try to get the base object
1279 from the original address we got, and build an all-aliasing
1280 unknown-sized access to that one. */
1281 if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0)))
1282 set_mem_attributes (mem, exp, 0);
1283 else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1284 && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0),
1285 0))))
1287 exp = build_fold_addr_expr (exp);
1288 exp = fold_build2 (MEM_REF,
1289 build_array_type (char_type_node,
1290 build_range_type (sizetype,
1291 size_zero_node,
1292 NULL)),
1293 exp, build_int_cst (ptr_type_node, 0));
1294 set_mem_attributes (mem, exp, 0);
1296 set_mem_alias_set (mem, 0);
1297 return mem;
1300 /* Built-in functions to perform an untyped call and return. */
1302 #define apply_args_mode \
1303 (this_target_builtins->x_apply_args_mode)
1304 #define apply_result_mode \
1305 (this_target_builtins->x_apply_result_mode)
1307 /* Return the size required for the block returned by __builtin_apply_args,
1308 and initialize apply_args_mode. */
1310 static int
1311 apply_args_size (void)
1313 static int size = -1;
1314 int align;
1315 unsigned int regno;
1316 enum machine_mode mode;
1318 /* The values computed by this function never change. */
1319 if (size < 0)
1321 /* The first value is the incoming arg-pointer. */
1322 size = GET_MODE_SIZE (Pmode);
1324 /* The second value is the structure value address unless this is
1325 passed as an "invisible" first argument. */
1326 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1327 size += GET_MODE_SIZE (Pmode);
1329 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1330 if (FUNCTION_ARG_REGNO_P (regno))
1332 mode = targetm.calls.get_raw_arg_mode (regno);
1334 gcc_assert (mode != VOIDmode);
1336 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1337 if (size % align != 0)
1338 size = CEIL (size, align) * align;
1339 size += GET_MODE_SIZE (mode);
1340 apply_args_mode[regno] = mode;
1342 else
1344 apply_args_mode[regno] = VOIDmode;
1347 return size;
1350 /* Return the size required for the block returned by __builtin_apply,
1351 and initialize apply_result_mode. */
1353 static int
1354 apply_result_size (void)
1356 static int size = -1;
1357 int align, regno;
1358 enum machine_mode mode;
1360 /* The values computed by this function never change. */
1361 if (size < 0)
1363 size = 0;
1365 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1366 if (targetm.calls.function_value_regno_p (regno))
1368 mode = targetm.calls.get_raw_result_mode (regno);
1370 gcc_assert (mode != VOIDmode);
1372 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1373 if (size % align != 0)
1374 size = CEIL (size, align) * align;
1375 size += GET_MODE_SIZE (mode);
1376 apply_result_mode[regno] = mode;
1378 else
1379 apply_result_mode[regno] = VOIDmode;
1381 /* Allow targets that use untyped_call and untyped_return to override
1382 the size so that machine-specific information can be stored here. */
1383 #ifdef APPLY_RESULT_SIZE
1384 size = APPLY_RESULT_SIZE;
1385 #endif
1387 return size;
1390 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1391 /* Create a vector describing the result block RESULT. If SAVEP is true,
1392 the result block is used to save the values; otherwise it is used to
1393 restore the values. */
1395 static rtx
1396 result_vector (int savep, rtx result)
1398 int regno, size, align, nelts;
1399 enum machine_mode mode;
1400 rtx reg, mem;
1401 rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1403 size = nelts = 0;
1404 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1405 if ((mode = apply_result_mode[regno]) != VOIDmode)
1407 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1408 if (size % align != 0)
1409 size = CEIL (size, align) * align;
1410 reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1411 mem = adjust_address (result, mode, size);
1412 savevec[nelts++] = (savep
1413 ? gen_rtx_SET (VOIDmode, mem, reg)
1414 : gen_rtx_SET (VOIDmode, reg, mem));
1415 size += GET_MODE_SIZE (mode);
1417 return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1419 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1421 /* Save the state required to perform an untyped call with the same
1422 arguments as were passed to the current function. */
1424 static rtx
1425 expand_builtin_apply_args_1 (void)
1427 rtx registers, tem;
1428 int size, align, regno;
1429 enum machine_mode mode;
1430 rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1432 /* Create a block where the arg-pointer, structure value address,
1433 and argument registers can be saved. */
1434 registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1436 /* Walk past the arg-pointer and structure value address. */
1437 size = GET_MODE_SIZE (Pmode);
1438 if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1439 size += GET_MODE_SIZE (Pmode);
1441 /* Save each register used in calling a function to the block. */
1442 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1443 if ((mode = apply_args_mode[regno]) != VOIDmode)
1445 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1446 if (size % align != 0)
1447 size = CEIL (size, align) * align;
1449 tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1451 emit_move_insn (adjust_address (registers, mode, size), tem);
1452 size += GET_MODE_SIZE (mode);
1455 /* Save the arg pointer to the block. */
1456 tem = copy_to_reg (crtl->args.internal_arg_pointer);
1457 #ifdef STACK_GROWS_DOWNWARD
1458 /* We need the pointer as the caller actually passed them to us, not
1459 as we might have pretended they were passed. Make sure it's a valid
1460 operand, as emit_move_insn isn't expected to handle a PLUS. */
1462 = force_operand (plus_constant (Pmode, tem, crtl->args.pretend_args_size),
1463 NULL_RTX);
1464 #endif
1465 emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1467 size = GET_MODE_SIZE (Pmode);
1469 /* Save the structure value address unless this is passed as an
1470 "invisible" first argument. */
1471 if (struct_incoming_value)
1473 emit_move_insn (adjust_address (registers, Pmode, size),
1474 copy_to_reg (struct_incoming_value));
1475 size += GET_MODE_SIZE (Pmode);
1478 /* Return the address of the block. */
1479 return copy_addr_to_reg (XEXP (registers, 0));
1482 /* __builtin_apply_args returns block of memory allocated on
1483 the stack into which is stored the arg pointer, structure
1484 value address, static chain, and all the registers that might
1485 possibly be used in performing a function call. The code is
1486 moved to the start of the function so the incoming values are
1487 saved. */
1489 static rtx
1490 expand_builtin_apply_args (void)
1492 /* Don't do __builtin_apply_args more than once in a function.
1493 Save the result of the first call and reuse it. */
1494 if (apply_args_value != 0)
1495 return apply_args_value;
1497 /* When this function is called, it means that registers must be
1498 saved on entry to this function. So we migrate the
1499 call to the first insn of this function. */
1500 rtx temp;
1501 rtx seq;
1503 start_sequence ();
1504 temp = expand_builtin_apply_args_1 ();
1505 seq = get_insns ();
1506 end_sequence ();
1508 apply_args_value = temp;
1510 /* Put the insns after the NOTE that starts the function.
1511 If this is inside a start_sequence, make the outer-level insn
1512 chain current, so the code is placed at the start of the
1513 function. If internal_arg_pointer is a non-virtual pseudo,
1514 it needs to be placed after the function that initializes
1515 that pseudo. */
1516 push_topmost_sequence ();
1517 if (REG_P (crtl->args.internal_arg_pointer)
1518 && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1519 emit_insn_before (seq, parm_birth_insn);
1520 else
1521 emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1522 pop_topmost_sequence ();
1523 return temp;
1527 /* Perform an untyped call and save the state required to perform an
1528 untyped return of whatever value was returned by the given function. */
1530 static rtx
1531 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1533 int size, align, regno;
1534 enum machine_mode mode;
1535 rtx incoming_args, result, reg, dest, src, call_insn;
1536 rtx old_stack_level = 0;
1537 rtx call_fusage = 0;
1538 rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1540 arguments = convert_memory_address (Pmode, arguments);
1542 /* Create a block where the return registers can be saved. */
1543 result = assign_stack_local (BLKmode, apply_result_size (), -1);
1545 /* Fetch the arg pointer from the ARGUMENTS block. */
1546 incoming_args = gen_reg_rtx (Pmode);
1547 emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1548 #ifndef STACK_GROWS_DOWNWARD
1549 incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1550 incoming_args, 0, OPTAB_LIB_WIDEN);
1551 #endif
1553 /* Push a new argument block and copy the arguments. Do not allow
1554 the (potential) memcpy call below to interfere with our stack
1555 manipulations. */
1556 do_pending_stack_adjust ();
1557 NO_DEFER_POP;
1559 /* Save the stack with nonlocal if available. */
1560 #ifdef HAVE_save_stack_nonlocal
1561 if (HAVE_save_stack_nonlocal)
1562 emit_stack_save (SAVE_NONLOCAL, &old_stack_level);
1563 else
1564 #endif
1565 emit_stack_save (SAVE_BLOCK, &old_stack_level);
1567 /* Allocate a block of memory onto the stack and copy the memory
1568 arguments to the outgoing arguments address. We can pass TRUE
1569 as the 4th argument because we just saved the stack pointer
1570 and will restore it right after the call. */
1571 allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true);
1573 /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1574 may have already set current_function_calls_alloca to true.
1575 current_function_calls_alloca won't be set if argsize is zero,
1576 so we have to guarantee need_drap is true here. */
1577 if (SUPPORTS_STACK_ALIGNMENT)
1578 crtl->need_drap = true;
1580 dest = virtual_outgoing_args_rtx;
1581 #ifndef STACK_GROWS_DOWNWARD
1582 if (CONST_INT_P (argsize))
1583 dest = plus_constant (Pmode, dest, -INTVAL (argsize));
1584 else
1585 dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1586 #endif
1587 dest = gen_rtx_MEM (BLKmode, dest);
1588 set_mem_align (dest, PARM_BOUNDARY);
1589 src = gen_rtx_MEM (BLKmode, incoming_args);
1590 set_mem_align (src, PARM_BOUNDARY);
1591 emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1593 /* Refer to the argument block. */
1594 apply_args_size ();
1595 arguments = gen_rtx_MEM (BLKmode, arguments);
1596 set_mem_align (arguments, PARM_BOUNDARY);
1598 /* Walk past the arg-pointer and structure value address. */
1599 size = GET_MODE_SIZE (Pmode);
1600 if (struct_value)
1601 size += GET_MODE_SIZE (Pmode);
1603 /* Restore each of the registers previously saved. Make USE insns
1604 for each of these registers for use in making the call. */
1605 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1606 if ((mode = apply_args_mode[regno]) != VOIDmode)
1608 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1609 if (size % align != 0)
1610 size = CEIL (size, align) * align;
1611 reg = gen_rtx_REG (mode, regno);
1612 emit_move_insn (reg, adjust_address (arguments, mode, size));
1613 use_reg (&call_fusage, reg);
1614 size += GET_MODE_SIZE (mode);
1617 /* Restore the structure value address unless this is passed as an
1618 "invisible" first argument. */
1619 size = GET_MODE_SIZE (Pmode);
1620 if (struct_value)
1622 rtx value = gen_reg_rtx (Pmode);
1623 emit_move_insn (value, adjust_address (arguments, Pmode, size));
1624 emit_move_insn (struct_value, value);
1625 if (REG_P (struct_value))
1626 use_reg (&call_fusage, struct_value);
1627 size += GET_MODE_SIZE (Pmode);
1630 /* All arguments and registers used for the call are set up by now! */
1631 function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1633 /* Ensure address is valid. SYMBOL_REF is already valid, so no need,
1634 and we don't want to load it into a register as an optimization,
1635 because prepare_call_address already did it if it should be done. */
1636 if (GET_CODE (function) != SYMBOL_REF)
1637 function = memory_address (FUNCTION_MODE, function);
1639 /* Generate the actual call instruction and save the return value. */
1640 #ifdef HAVE_untyped_call
1641 if (HAVE_untyped_call)
1642 emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1643 result, result_vector (1, result)));
1644 else
1645 #endif
1646 #ifdef HAVE_call_value
1647 if (HAVE_call_value)
1649 rtx valreg = 0;
1651 /* Locate the unique return register. It is not possible to
1652 express a call that sets more than one return register using
1653 call_value; use untyped_call for that. In fact, untyped_call
1654 only needs to save the return registers in the given block. */
1655 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1656 if ((mode = apply_result_mode[regno]) != VOIDmode)
1658 gcc_assert (!valreg); /* HAVE_untyped_call required. */
1660 valreg = gen_rtx_REG (mode, regno);
1663 emit_call_insn (GEN_CALL_VALUE (valreg,
1664 gen_rtx_MEM (FUNCTION_MODE, function),
1665 const0_rtx, NULL_RTX, const0_rtx));
1667 emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1669 else
1670 #endif
1671 gcc_unreachable ();
1673 /* Find the CALL insn we just emitted, and attach the register usage
1674 information. */
1675 call_insn = last_call_insn ();
1676 add_function_usage_to (call_insn, call_fusage);
1678 /* Restore the stack. */
1679 #ifdef HAVE_save_stack_nonlocal
1680 if (HAVE_save_stack_nonlocal)
1681 emit_stack_restore (SAVE_NONLOCAL, old_stack_level);
1682 else
1683 #endif
1684 emit_stack_restore (SAVE_BLOCK, old_stack_level);
1685 fixup_args_size_notes (call_insn, get_last_insn(), 0);
1687 OK_DEFER_POP;
1689 /* Return the address of the result block. */
1690 result = copy_addr_to_reg (XEXP (result, 0));
1691 return convert_memory_address (ptr_mode, result);
1694 /* Perform an untyped return. */
1696 static void
1697 expand_builtin_return (rtx result)
1699 int size, align, regno;
1700 enum machine_mode mode;
1701 rtx reg;
1702 rtx call_fusage = 0;
1704 result = convert_memory_address (Pmode, result);
1706 apply_result_size ();
1707 result = gen_rtx_MEM (BLKmode, result);
1709 #ifdef HAVE_untyped_return
1710 if (HAVE_untyped_return)
1712 emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1713 emit_barrier ();
1714 return;
1716 #endif
1718 /* Restore the return value and note that each value is used. */
1719 size = 0;
1720 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1721 if ((mode = apply_result_mode[regno]) != VOIDmode)
1723 align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1724 if (size % align != 0)
1725 size = CEIL (size, align) * align;
1726 reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1727 emit_move_insn (reg, adjust_address (result, mode, size));
1729 push_to_sequence (call_fusage);
1730 emit_use (reg);
1731 call_fusage = get_insns ();
1732 end_sequence ();
1733 size += GET_MODE_SIZE (mode);
1736 /* Put the USE insns before the return. */
1737 emit_insn (call_fusage);
1739 /* Return whatever values was restored by jumping directly to the end
1740 of the function. */
1741 expand_naked_return ();
1744 /* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
1746 static enum type_class
1747 type_to_class (tree type)
1749 switch (TREE_CODE (type))
1751 case VOID_TYPE: return void_type_class;
1752 case INTEGER_TYPE: return integer_type_class;
1753 case ENUMERAL_TYPE: return enumeral_type_class;
1754 case BOOLEAN_TYPE: return boolean_type_class;
1755 case POINTER_TYPE: return pointer_type_class;
1756 case REFERENCE_TYPE: return reference_type_class;
1757 case OFFSET_TYPE: return offset_type_class;
1758 case REAL_TYPE: return real_type_class;
1759 case COMPLEX_TYPE: return complex_type_class;
1760 case FUNCTION_TYPE: return function_type_class;
1761 case METHOD_TYPE: return method_type_class;
1762 case RECORD_TYPE: return record_type_class;
1763 case UNION_TYPE:
1764 case QUAL_UNION_TYPE: return union_type_class;
1765 case ARRAY_TYPE: return (TYPE_STRING_FLAG (type)
1766 ? string_type_class : array_type_class);
1767 case LANG_TYPE: return lang_type_class;
1768 default: return no_type_class;
1772 /* Expand a call EXP to __builtin_classify_type. */
1774 static rtx
1775 expand_builtin_classify_type (tree exp)
1777 if (call_expr_nargs (exp))
1778 return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1779 return GEN_INT (no_type_class);
1782 /* This helper macro, meant to be used in mathfn_built_in below,
1783 determines which among a set of three builtin math functions is
1784 appropriate for a given type mode. The `F' and `L' cases are
1785 automatically generated from the `double' case. */
1786 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1787 case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1788 fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1789 fcodel = BUILT_IN_MATHFN##L ; break;
1790 /* Similar to above, but appends _R after any F/L suffix. */
1791 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1792 case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1793 fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1794 fcodel = BUILT_IN_MATHFN##L_R ; break;
1796 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1797 if available. If IMPLICIT is true use the implicit builtin declaration,
1798 otherwise use the explicit declaration. If we can't do the conversion,
1799 return zero. */
1801 static tree
1802 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p)
1804 enum built_in_function fcode, fcodef, fcodel, fcode2;
1806 switch (fn)
1808 CASE_MATHFN (BUILT_IN_ACOS)
1809 CASE_MATHFN (BUILT_IN_ACOSH)
1810 CASE_MATHFN (BUILT_IN_ASIN)
1811 CASE_MATHFN (BUILT_IN_ASINH)
1812 CASE_MATHFN (BUILT_IN_ATAN)
1813 CASE_MATHFN (BUILT_IN_ATAN2)
1814 CASE_MATHFN (BUILT_IN_ATANH)
1815 CASE_MATHFN (BUILT_IN_CBRT)
1816 CASE_MATHFN (BUILT_IN_CEIL)
1817 CASE_MATHFN (BUILT_IN_CEXPI)
1818 CASE_MATHFN (BUILT_IN_COPYSIGN)
1819 CASE_MATHFN (BUILT_IN_COS)
1820 CASE_MATHFN (BUILT_IN_COSH)
1821 CASE_MATHFN (BUILT_IN_DREM)
1822 CASE_MATHFN (BUILT_IN_ERF)
1823 CASE_MATHFN (BUILT_IN_ERFC)
1824 CASE_MATHFN (BUILT_IN_EXP)
1825 CASE_MATHFN (BUILT_IN_EXP10)
1826 CASE_MATHFN (BUILT_IN_EXP2)
1827 CASE_MATHFN (BUILT_IN_EXPM1)
1828 CASE_MATHFN (BUILT_IN_FABS)
1829 CASE_MATHFN (BUILT_IN_FDIM)
1830 CASE_MATHFN (BUILT_IN_FLOOR)
1831 CASE_MATHFN (BUILT_IN_FMA)
1832 CASE_MATHFN (BUILT_IN_FMAX)
1833 CASE_MATHFN (BUILT_IN_FMIN)
1834 CASE_MATHFN (BUILT_IN_FMOD)
1835 CASE_MATHFN (BUILT_IN_FREXP)
1836 CASE_MATHFN (BUILT_IN_GAMMA)
1837 CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1838 CASE_MATHFN (BUILT_IN_HUGE_VAL)
1839 CASE_MATHFN (BUILT_IN_HYPOT)
1840 CASE_MATHFN (BUILT_IN_ILOGB)
1841 CASE_MATHFN (BUILT_IN_ICEIL)
1842 CASE_MATHFN (BUILT_IN_IFLOOR)
1843 CASE_MATHFN (BUILT_IN_INF)
1844 CASE_MATHFN (BUILT_IN_IRINT)
1845 CASE_MATHFN (BUILT_IN_IROUND)
1846 CASE_MATHFN (BUILT_IN_ISINF)
1847 CASE_MATHFN (BUILT_IN_J0)
1848 CASE_MATHFN (BUILT_IN_J1)
1849 CASE_MATHFN (BUILT_IN_JN)
1850 CASE_MATHFN (BUILT_IN_LCEIL)
1851 CASE_MATHFN (BUILT_IN_LDEXP)
1852 CASE_MATHFN (BUILT_IN_LFLOOR)
1853 CASE_MATHFN (BUILT_IN_LGAMMA)
1854 CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1855 CASE_MATHFN (BUILT_IN_LLCEIL)
1856 CASE_MATHFN (BUILT_IN_LLFLOOR)
1857 CASE_MATHFN (BUILT_IN_LLRINT)
1858 CASE_MATHFN (BUILT_IN_LLROUND)
1859 CASE_MATHFN (BUILT_IN_LOG)
1860 CASE_MATHFN (BUILT_IN_LOG10)
1861 CASE_MATHFN (BUILT_IN_LOG1P)
1862 CASE_MATHFN (BUILT_IN_LOG2)
1863 CASE_MATHFN (BUILT_IN_LOGB)
1864 CASE_MATHFN (BUILT_IN_LRINT)
1865 CASE_MATHFN (BUILT_IN_LROUND)
1866 CASE_MATHFN (BUILT_IN_MODF)
1867 CASE_MATHFN (BUILT_IN_NAN)
1868 CASE_MATHFN (BUILT_IN_NANS)
1869 CASE_MATHFN (BUILT_IN_NEARBYINT)
1870 CASE_MATHFN (BUILT_IN_NEXTAFTER)
1871 CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1872 CASE_MATHFN (BUILT_IN_POW)
1873 CASE_MATHFN (BUILT_IN_POWI)
1874 CASE_MATHFN (BUILT_IN_POW10)
1875 CASE_MATHFN (BUILT_IN_REMAINDER)
1876 CASE_MATHFN (BUILT_IN_REMQUO)
1877 CASE_MATHFN (BUILT_IN_RINT)
1878 CASE_MATHFN (BUILT_IN_ROUND)
1879 CASE_MATHFN (BUILT_IN_SCALB)
1880 CASE_MATHFN (BUILT_IN_SCALBLN)
1881 CASE_MATHFN (BUILT_IN_SCALBN)
1882 CASE_MATHFN (BUILT_IN_SIGNBIT)
1883 CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1884 CASE_MATHFN (BUILT_IN_SIN)
1885 CASE_MATHFN (BUILT_IN_SINCOS)
1886 CASE_MATHFN (BUILT_IN_SINH)
1887 CASE_MATHFN (BUILT_IN_SQRT)
1888 CASE_MATHFN (BUILT_IN_TAN)
1889 CASE_MATHFN (BUILT_IN_TANH)
1890 CASE_MATHFN (BUILT_IN_TGAMMA)
1891 CASE_MATHFN (BUILT_IN_TRUNC)
1892 CASE_MATHFN (BUILT_IN_Y0)
1893 CASE_MATHFN (BUILT_IN_Y1)
1894 CASE_MATHFN (BUILT_IN_YN)
1896 default:
1897 return NULL_TREE;
1900 if (TYPE_MAIN_VARIANT (type) == double_type_node)
1901 fcode2 = fcode;
1902 else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1903 fcode2 = fcodef;
1904 else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1905 fcode2 = fcodel;
1906 else
1907 return NULL_TREE;
1909 if (implicit_p && !builtin_decl_implicit_p (fcode2))
1910 return NULL_TREE;
1912 return builtin_decl_explicit (fcode2);
1915 /* Like mathfn_built_in_1(), but always use the implicit array. */
1917 tree
1918 mathfn_built_in (tree type, enum built_in_function fn)
1920 return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1923 /* If errno must be maintained, expand the RTL to check if the result,
1924 TARGET, of a built-in function call, EXP, is NaN, and if so set
1925 errno to EDOM. */
1927 static void
1928 expand_errno_check (tree exp, rtx target)
1930 rtx lab = gen_label_rtx ();
1932 /* Test the result; if it is NaN, set errno=EDOM because
1933 the argument was not in the domain. */
1934 do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1935 NULL_RTX, NULL_RTX, lab,
1936 /* The jump is very likely. */
1937 REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1));
1939 #ifdef TARGET_EDOM
1940 /* If this built-in doesn't throw an exception, set errno directly. */
1941 if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1943 #ifdef GEN_ERRNO_RTX
1944 rtx errno_rtx = GEN_ERRNO_RTX;
1945 #else
1946 rtx errno_rtx
1947 = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1948 #endif
1949 emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1950 emit_label (lab);
1951 return;
1953 #endif
1955 /* Make sure the library call isn't expanded as a tail call. */
1956 CALL_EXPR_TAILCALL (exp) = 0;
1958 /* We can't set errno=EDOM directly; let the library call do it.
1959 Pop the arguments right away in case the call gets deleted. */
1960 NO_DEFER_POP;
1961 expand_call (exp, target, 0);
1962 OK_DEFER_POP;
1963 emit_label (lab);
1966 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1967 Return NULL_RTX if a normal call should be emitted rather than expanding
1968 the function in-line. EXP is the expression that is a call to the builtin
1969 function; if convenient, the result should be placed in TARGET.
1970 SUBTARGET may be used as the target for computing one of EXP's operands. */
1972 static rtx
1973 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1975 optab builtin_optab;
1976 rtx op0, insns;
1977 tree fndecl = get_callee_fndecl (exp);
1978 enum machine_mode mode;
1979 bool errno_set = false;
1980 tree arg;
1982 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1983 return NULL_RTX;
1985 arg = CALL_EXPR_ARG (exp, 0);
1987 switch (DECL_FUNCTION_CODE (fndecl))
1989 CASE_FLT_FN (BUILT_IN_SQRT):
1990 errno_set = ! tree_expr_nonnegative_p (arg);
1991 builtin_optab = sqrt_optab;
1992 break;
1993 CASE_FLT_FN (BUILT_IN_EXP):
1994 errno_set = true; builtin_optab = exp_optab; break;
1995 CASE_FLT_FN (BUILT_IN_EXP10):
1996 CASE_FLT_FN (BUILT_IN_POW10):
1997 errno_set = true; builtin_optab = exp10_optab; break;
1998 CASE_FLT_FN (BUILT_IN_EXP2):
1999 errno_set = true; builtin_optab = exp2_optab; break;
2000 CASE_FLT_FN (BUILT_IN_EXPM1):
2001 errno_set = true; builtin_optab = expm1_optab; break;
2002 CASE_FLT_FN (BUILT_IN_LOGB):
2003 errno_set = true; builtin_optab = logb_optab; break;
2004 CASE_FLT_FN (BUILT_IN_LOG):
2005 errno_set = true; builtin_optab = log_optab; break;
2006 CASE_FLT_FN (BUILT_IN_LOG10):
2007 errno_set = true; builtin_optab = log10_optab; break;
2008 CASE_FLT_FN (BUILT_IN_LOG2):
2009 errno_set = true; builtin_optab = log2_optab; break;
2010 CASE_FLT_FN (BUILT_IN_LOG1P):
2011 errno_set = true; builtin_optab = log1p_optab; break;
2012 CASE_FLT_FN (BUILT_IN_ASIN):
2013 builtin_optab = asin_optab; break;
2014 CASE_FLT_FN (BUILT_IN_ACOS):
2015 builtin_optab = acos_optab; break;
2016 CASE_FLT_FN (BUILT_IN_TAN):
2017 builtin_optab = tan_optab; break;
2018 CASE_FLT_FN (BUILT_IN_ATAN):
2019 builtin_optab = atan_optab; break;
2020 CASE_FLT_FN (BUILT_IN_FLOOR):
2021 builtin_optab = floor_optab; break;
2022 CASE_FLT_FN (BUILT_IN_CEIL):
2023 builtin_optab = ceil_optab; break;
2024 CASE_FLT_FN (BUILT_IN_TRUNC):
2025 builtin_optab = btrunc_optab; break;
2026 CASE_FLT_FN (BUILT_IN_ROUND):
2027 builtin_optab = round_optab; break;
2028 CASE_FLT_FN (BUILT_IN_NEARBYINT):
2029 builtin_optab = nearbyint_optab;
2030 if (flag_trapping_math)
2031 break;
2032 /* Else fallthrough and expand as rint. */
2033 CASE_FLT_FN (BUILT_IN_RINT):
2034 builtin_optab = rint_optab; break;
2035 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
2036 builtin_optab = significand_optab; break;
2037 default:
2038 gcc_unreachable ();
2041 /* Make a suitable register to place result in. */
2042 mode = TYPE_MODE (TREE_TYPE (exp));
2044 if (! flag_errno_math || ! HONOR_NANS (mode))
2045 errno_set = false;
2047 /* Before working hard, check whether the instruction is available. */
2048 if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
2049 && (!errno_set || !optimize_insn_for_size_p ()))
2051 target = gen_reg_rtx (mode);
2053 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2054 need to expand the argument again. This way, we will not perform
2055 side-effects more the once. */
2056 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2058 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2060 start_sequence ();
2062 /* Compute into TARGET.
2063 Set TARGET to wherever the result comes back. */
2064 target = expand_unop (mode, builtin_optab, op0, target, 0);
2066 if (target != 0)
2068 if (errno_set)
2069 expand_errno_check (exp, target);
2071 /* Output the entire sequence. */
2072 insns = get_insns ();
2073 end_sequence ();
2074 emit_insn (insns);
2075 return target;
2078 /* If we were unable to expand via the builtin, stop the sequence
2079 (without outputting the insns) and call to the library function
2080 with the stabilized argument list. */
2081 end_sequence ();
2084 return expand_call (exp, target, target == const0_rtx);
2087 /* Expand a call to the builtin binary math functions (pow and atan2).
2088 Return NULL_RTX if a normal call should be emitted rather than expanding the
2089 function in-line. EXP is the expression that is a call to the builtin
2090 function; if convenient, the result should be placed in TARGET.
2091 SUBTARGET may be used as the target for computing one of EXP's
2092 operands. */
2094 static rtx
2095 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2097 optab builtin_optab;
2098 rtx op0, op1, insns;
2099 int op1_type = REAL_TYPE;
2100 tree fndecl = get_callee_fndecl (exp);
2101 tree arg0, arg1;
2102 enum machine_mode mode;
2103 bool errno_set = true;
2105 switch (DECL_FUNCTION_CODE (fndecl))
2107 CASE_FLT_FN (BUILT_IN_SCALBN):
2108 CASE_FLT_FN (BUILT_IN_SCALBLN):
2109 CASE_FLT_FN (BUILT_IN_LDEXP):
2110 op1_type = INTEGER_TYPE;
2111 default:
2112 break;
2115 if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2116 return NULL_RTX;
2118 arg0 = CALL_EXPR_ARG (exp, 0);
2119 arg1 = CALL_EXPR_ARG (exp, 1);
2121 switch (DECL_FUNCTION_CODE (fndecl))
2123 CASE_FLT_FN (BUILT_IN_POW):
2124 builtin_optab = pow_optab; break;
2125 CASE_FLT_FN (BUILT_IN_ATAN2):
2126 builtin_optab = atan2_optab; break;
2127 CASE_FLT_FN (BUILT_IN_SCALB):
2128 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2129 return 0;
2130 builtin_optab = scalb_optab; break;
2131 CASE_FLT_FN (BUILT_IN_SCALBN):
2132 CASE_FLT_FN (BUILT_IN_SCALBLN):
2133 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2134 return 0;
2135 /* Fall through... */
2136 CASE_FLT_FN (BUILT_IN_LDEXP):
2137 builtin_optab = ldexp_optab; break;
2138 CASE_FLT_FN (BUILT_IN_FMOD):
2139 builtin_optab = fmod_optab; break;
2140 CASE_FLT_FN (BUILT_IN_REMAINDER):
2141 CASE_FLT_FN (BUILT_IN_DREM):
2142 builtin_optab = remainder_optab; break;
2143 default:
2144 gcc_unreachable ();
2147 /* Make a suitable register to place result in. */
2148 mode = TYPE_MODE (TREE_TYPE (exp));
2150 /* Before working hard, check whether the instruction is available. */
2151 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2152 return NULL_RTX;
2154 target = gen_reg_rtx (mode);
2156 if (! flag_errno_math || ! HONOR_NANS (mode))
2157 errno_set = false;
2159 if (errno_set && optimize_insn_for_size_p ())
2160 return 0;
2162 /* Always stabilize the argument list. */
2163 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2164 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2166 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2167 op1 = expand_normal (arg1);
2169 start_sequence ();
2171 /* Compute into TARGET.
2172 Set TARGET to wherever the result comes back. */
2173 target = expand_binop (mode, builtin_optab, op0, op1,
2174 target, 0, OPTAB_DIRECT);
2176 /* If we were unable to expand via the builtin, stop the sequence
2177 (without outputting the insns) and call to the library function
2178 with the stabilized argument list. */
2179 if (target == 0)
2181 end_sequence ();
2182 return expand_call (exp, target, target == const0_rtx);
2185 if (errno_set)
2186 expand_errno_check (exp, target);
2188 /* Output the entire sequence. */
2189 insns = get_insns ();
2190 end_sequence ();
2191 emit_insn (insns);
2193 return target;
2196 /* Expand a call to the builtin trinary math functions (fma).
2197 Return NULL_RTX if a normal call should be emitted rather than expanding the
2198 function in-line. EXP is the expression that is a call to the builtin
2199 function; if convenient, the result should be placed in TARGET.
2200 SUBTARGET may be used as the target for computing one of EXP's
2201 operands. */
2203 static rtx
2204 expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
2206 optab builtin_optab;
2207 rtx op0, op1, op2, insns;
2208 tree fndecl = get_callee_fndecl (exp);
2209 tree arg0, arg1, arg2;
2210 enum machine_mode mode;
2212 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2213 return NULL_RTX;
2215 arg0 = CALL_EXPR_ARG (exp, 0);
2216 arg1 = CALL_EXPR_ARG (exp, 1);
2217 arg2 = CALL_EXPR_ARG (exp, 2);
2219 switch (DECL_FUNCTION_CODE (fndecl))
2221 CASE_FLT_FN (BUILT_IN_FMA):
2222 builtin_optab = fma_optab; break;
2223 default:
2224 gcc_unreachable ();
2227 /* Make a suitable register to place result in. */
2228 mode = TYPE_MODE (TREE_TYPE (exp));
2230 /* Before working hard, check whether the instruction is available. */
2231 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2232 return NULL_RTX;
2234 target = gen_reg_rtx (mode);
2236 /* Always stabilize the argument list. */
2237 CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2238 CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2239 CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2);
2241 op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2242 op1 = expand_normal (arg1);
2243 op2 = expand_normal (arg2);
2245 start_sequence ();
2247 /* Compute into TARGET.
2248 Set TARGET to wherever the result comes back. */
2249 target = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
2250 target, 0);
2252 /* If we were unable to expand via the builtin, stop the sequence
2253 (without outputting the insns) and call to the library function
2254 with the stabilized argument list. */
2255 if (target == 0)
2257 end_sequence ();
2258 return expand_call (exp, target, target == const0_rtx);
2261 /* Output the entire sequence. */
2262 insns = get_insns ();
2263 end_sequence ();
2264 emit_insn (insns);
2266 return target;
2269 /* Expand a call to the builtin sin and cos math functions.
2270 Return NULL_RTX if a normal call should be emitted rather than expanding the
2271 function in-line. EXP is the expression that is a call to the builtin
2272 function; if convenient, the result should be placed in TARGET.
2273 SUBTARGET may be used as the target for computing one of EXP's
2274 operands. */
2276 static rtx
2277 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2279 optab builtin_optab;
2280 rtx op0, insns;
2281 tree fndecl = get_callee_fndecl (exp);
2282 enum machine_mode mode;
2283 tree arg;
2285 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2286 return NULL_RTX;
2288 arg = CALL_EXPR_ARG (exp, 0);
2290 switch (DECL_FUNCTION_CODE (fndecl))
2292 CASE_FLT_FN (BUILT_IN_SIN):
2293 CASE_FLT_FN (BUILT_IN_COS):
2294 builtin_optab = sincos_optab; break;
2295 default:
2296 gcc_unreachable ();
2299 /* Make a suitable register to place result in. */
2300 mode = TYPE_MODE (TREE_TYPE (exp));
2302 /* Check if sincos insn is available, otherwise fallback
2303 to sin or cos insn. */
2304 if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2305 switch (DECL_FUNCTION_CODE (fndecl))
2307 CASE_FLT_FN (BUILT_IN_SIN):
2308 builtin_optab = sin_optab; break;
2309 CASE_FLT_FN (BUILT_IN_COS):
2310 builtin_optab = cos_optab; break;
2311 default:
2312 gcc_unreachable ();
2315 /* Before working hard, check whether the instruction is available. */
2316 if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
2318 target = gen_reg_rtx (mode);
2320 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2321 need to expand the argument again. This way, we will not perform
2322 side-effects more the once. */
2323 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2325 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2327 start_sequence ();
2329 /* Compute into TARGET.
2330 Set TARGET to wherever the result comes back. */
2331 if (builtin_optab == sincos_optab)
2333 int result;
2335 switch (DECL_FUNCTION_CODE (fndecl))
2337 CASE_FLT_FN (BUILT_IN_SIN):
2338 result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2339 break;
2340 CASE_FLT_FN (BUILT_IN_COS):
2341 result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2342 break;
2343 default:
2344 gcc_unreachable ();
2346 gcc_assert (result);
2348 else
2350 target = expand_unop (mode, builtin_optab, op0, target, 0);
2353 if (target != 0)
2355 /* Output the entire sequence. */
2356 insns = get_insns ();
2357 end_sequence ();
2358 emit_insn (insns);
2359 return target;
2362 /* If we were unable to expand via the builtin, stop the sequence
2363 (without outputting the insns) and call to the library function
2364 with the stabilized argument list. */
2365 end_sequence ();
2368 target = expand_call (exp, target, target == const0_rtx);
2370 return target;
2373 /* Given an interclass math builtin decl FNDECL and it's argument ARG
2374 return an RTL instruction code that implements the functionality.
2375 If that isn't possible or available return CODE_FOR_nothing. */
2377 static enum insn_code
2378 interclass_mathfn_icode (tree arg, tree fndecl)
2380 bool errno_set = false;
2381 optab builtin_optab = 0;
2382 enum machine_mode mode;
2384 switch (DECL_FUNCTION_CODE (fndecl))
2386 CASE_FLT_FN (BUILT_IN_ILOGB):
2387 errno_set = true; builtin_optab = ilogb_optab; break;
2388 CASE_FLT_FN (BUILT_IN_ISINF):
2389 builtin_optab = isinf_optab; break;
2390 case BUILT_IN_ISNORMAL:
2391 case BUILT_IN_ISFINITE:
2392 CASE_FLT_FN (BUILT_IN_FINITE):
2393 case BUILT_IN_FINITED32:
2394 case BUILT_IN_FINITED64:
2395 case BUILT_IN_FINITED128:
2396 case BUILT_IN_ISINFD32:
2397 case BUILT_IN_ISINFD64:
2398 case BUILT_IN_ISINFD128:
2399 /* These builtins have no optabs (yet). */
2400 break;
2401 default:
2402 gcc_unreachable ();
2405 /* There's no easy way to detect the case we need to set EDOM. */
2406 if (flag_errno_math && errno_set)
2407 return CODE_FOR_nothing;
2409 /* Optab mode depends on the mode of the input argument. */
2410 mode = TYPE_MODE (TREE_TYPE (arg));
2412 if (builtin_optab)
2413 return optab_handler (builtin_optab, mode);
2414 return CODE_FOR_nothing;
2417 /* Expand a call to one of the builtin math functions that operate on
2418 floating point argument and output an integer result (ilogb, isinf,
2419 isnan, etc).
2420 Return 0 if a normal call should be emitted rather than expanding the
2421 function in-line. EXP is the expression that is a call to the builtin
2422 function; if convenient, the result should be placed in TARGET. */
2424 static rtx
2425 expand_builtin_interclass_mathfn (tree exp, rtx target)
2427 enum insn_code icode = CODE_FOR_nothing;
2428 rtx op0;
2429 tree fndecl = get_callee_fndecl (exp);
2430 enum machine_mode mode;
2431 tree arg;
2433 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2434 return NULL_RTX;
2436 arg = CALL_EXPR_ARG (exp, 0);
2437 icode = interclass_mathfn_icode (arg, fndecl);
2438 mode = TYPE_MODE (TREE_TYPE (arg));
2440 if (icode != CODE_FOR_nothing)
2442 struct expand_operand ops[1];
2443 rtx last = get_last_insn ();
2444 tree orig_arg = arg;
2446 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2447 need to expand the argument again. This way, we will not perform
2448 side-effects more the once. */
2449 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2451 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2453 if (mode != GET_MODE (op0))
2454 op0 = convert_to_mode (mode, op0, 0);
2456 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
2457 if (maybe_legitimize_operands (icode, 0, 1, ops)
2458 && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN))
2459 return ops[0].value;
2461 delete_insns_since (last);
2462 CALL_EXPR_ARG (exp, 0) = orig_arg;
2465 return NULL_RTX;
2468 /* Expand a call to the builtin sincos math function.
2469 Return NULL_RTX if a normal call should be emitted rather than expanding the
2470 function in-line. EXP is the expression that is a call to the builtin
2471 function. */
2473 static rtx
2474 expand_builtin_sincos (tree exp)
2476 rtx op0, op1, op2, target1, target2;
2477 enum machine_mode mode;
2478 tree arg, sinp, cosp;
2479 int result;
2480 location_t loc = EXPR_LOCATION (exp);
2481 tree alias_type, alias_off;
2483 if (!validate_arglist (exp, REAL_TYPE,
2484 POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2485 return NULL_RTX;
2487 arg = CALL_EXPR_ARG (exp, 0);
2488 sinp = CALL_EXPR_ARG (exp, 1);
2489 cosp = CALL_EXPR_ARG (exp, 2);
2491 /* Make a suitable register to place result in. */
2492 mode = TYPE_MODE (TREE_TYPE (arg));
2494 /* Check if sincos insn is available, otherwise emit the call. */
2495 if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing)
2496 return NULL_RTX;
2498 target1 = gen_reg_rtx (mode);
2499 target2 = gen_reg_rtx (mode);
2501 op0 = expand_normal (arg);
2502 alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true);
2503 alias_off = build_int_cst (alias_type, 0);
2504 op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2505 sinp, alias_off));
2506 op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2507 cosp, alias_off));
2509 /* Compute into target1 and target2.
2510 Set TARGET to wherever the result comes back. */
2511 result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2512 gcc_assert (result);
2514 /* Move target1 and target2 to the memory locations indicated
2515 by op1 and op2. */
2516 emit_move_insn (op1, target1);
2517 emit_move_insn (op2, target2);
2519 return const0_rtx;
2522 /* Expand a call to the internal cexpi builtin to the sincos math function.
2523 EXP is the expression that is a call to the builtin function; if convenient,
2524 the result should be placed in TARGET. */
2526 static rtx
2527 expand_builtin_cexpi (tree exp, rtx target)
2529 tree fndecl = get_callee_fndecl (exp);
2530 tree arg, type;
2531 enum machine_mode mode;
2532 rtx op0, op1, op2;
2533 location_t loc = EXPR_LOCATION (exp);
2535 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2536 return NULL_RTX;
2538 arg = CALL_EXPR_ARG (exp, 0);
2539 type = TREE_TYPE (arg);
2540 mode = TYPE_MODE (TREE_TYPE (arg));
2542 /* Try expanding via a sincos optab, fall back to emitting a libcall
2543 to sincos or cexp. We are sure we have sincos or cexp because cexpi
2544 is only generated from sincos, cexp or if we have either of them. */
2545 if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing)
2547 op1 = gen_reg_rtx (mode);
2548 op2 = gen_reg_rtx (mode);
2550 op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2552 /* Compute into op1 and op2. */
2553 expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2555 else if (TARGET_HAS_SINCOS)
2557 tree call, fn = NULL_TREE;
2558 tree top1, top2;
2559 rtx op1a, op2a;
2561 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2562 fn = builtin_decl_explicit (BUILT_IN_SINCOSF);
2563 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2564 fn = builtin_decl_explicit (BUILT_IN_SINCOS);
2565 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2566 fn = builtin_decl_explicit (BUILT_IN_SINCOSL);
2567 else
2568 gcc_unreachable ();
2570 op1 = assign_temp (TREE_TYPE (arg), 1, 1);
2571 op2 = assign_temp (TREE_TYPE (arg), 1, 1);
2572 op1a = copy_addr_to_reg (XEXP (op1, 0));
2573 op2a = copy_addr_to_reg (XEXP (op2, 0));
2574 top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2575 top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2577 /* Make sure not to fold the sincos call again. */
2578 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2579 expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2580 call, 3, arg, top1, top2));
2582 else
2584 tree call, fn = NULL_TREE, narg;
2585 tree ctype = build_complex_type (type);
2587 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2588 fn = builtin_decl_explicit (BUILT_IN_CEXPF);
2589 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2590 fn = builtin_decl_explicit (BUILT_IN_CEXP);
2591 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2592 fn = builtin_decl_explicit (BUILT_IN_CEXPL);
2593 else
2594 gcc_unreachable ();
2596 /* If we don't have a decl for cexp create one. This is the
2597 friendliest fallback if the user calls __builtin_cexpi
2598 without full target C99 function support. */
2599 if (fn == NULL_TREE)
2601 tree fntype;
2602 const char *name = NULL;
2604 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2605 name = "cexpf";
2606 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2607 name = "cexp";
2608 else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2609 name = "cexpl";
2611 fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2612 fn = build_fn_decl (name, fntype);
2615 narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2616 build_real (type, dconst0), arg);
2618 /* Make sure not to fold the cexp call again. */
2619 call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2620 return expand_expr (build_call_nary (ctype, call, 1, narg),
2621 target, VOIDmode, EXPAND_NORMAL);
2624 /* Now build the proper return type. */
2625 return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2626 make_tree (TREE_TYPE (arg), op2),
2627 make_tree (TREE_TYPE (arg), op1)),
2628 target, VOIDmode, EXPAND_NORMAL);
2631 /* Conveniently construct a function call expression. FNDECL names the
2632 function to be called, N is the number of arguments, and the "..."
2633 parameters are the argument expressions. Unlike build_call_exr
2634 this doesn't fold the call, hence it will always return a CALL_EXPR. */
2636 static tree
2637 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2639 va_list ap;
2640 tree fntype = TREE_TYPE (fndecl);
2641 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2643 va_start (ap, n);
2644 fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2645 va_end (ap);
2646 SET_EXPR_LOCATION (fn, loc);
2647 return fn;
2650 /* Expand a call to one of the builtin rounding functions gcc defines
2651 as an extension (lfloor and lceil). As these are gcc extensions we
2652 do not need to worry about setting errno to EDOM.
2653 If expanding via optab fails, lower expression to (int)(floor(x)).
2654 EXP is the expression that is a call to the builtin function;
2655 if convenient, the result should be placed in TARGET. */
2657 static rtx
2658 expand_builtin_int_roundingfn (tree exp, rtx target)
2660 convert_optab builtin_optab;
2661 rtx op0, insns, tmp;
2662 tree fndecl = get_callee_fndecl (exp);
2663 enum built_in_function fallback_fn;
2664 tree fallback_fndecl;
2665 enum machine_mode mode;
2666 tree arg;
2668 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2669 gcc_unreachable ();
2671 arg = CALL_EXPR_ARG (exp, 0);
2673 switch (DECL_FUNCTION_CODE (fndecl))
2675 CASE_FLT_FN (BUILT_IN_ICEIL):
2676 CASE_FLT_FN (BUILT_IN_LCEIL):
2677 CASE_FLT_FN (BUILT_IN_LLCEIL):
2678 builtin_optab = lceil_optab;
2679 fallback_fn = BUILT_IN_CEIL;
2680 break;
2682 CASE_FLT_FN (BUILT_IN_IFLOOR):
2683 CASE_FLT_FN (BUILT_IN_LFLOOR):
2684 CASE_FLT_FN (BUILT_IN_LLFLOOR):
2685 builtin_optab = lfloor_optab;
2686 fallback_fn = BUILT_IN_FLOOR;
2687 break;
2689 default:
2690 gcc_unreachable ();
2693 /* Make a suitable register to place result in. */
2694 mode = TYPE_MODE (TREE_TYPE (exp));
2696 target = gen_reg_rtx (mode);
2698 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2699 need to expand the argument again. This way, we will not perform
2700 side-effects more the once. */
2701 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2703 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2705 start_sequence ();
2707 /* Compute into TARGET. */
2708 if (expand_sfix_optab (target, op0, builtin_optab))
2710 /* Output the entire sequence. */
2711 insns = get_insns ();
2712 end_sequence ();
2713 emit_insn (insns);
2714 return target;
2717 /* If we were unable to expand via the builtin, stop the sequence
2718 (without outputting the insns). */
2719 end_sequence ();
2721 /* Fall back to floating point rounding optab. */
2722 fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2724 /* For non-C99 targets we may end up without a fallback fndecl here
2725 if the user called __builtin_lfloor directly. In this case emit
2726 a call to the floor/ceil variants nevertheless. This should result
2727 in the best user experience for not full C99 targets. */
2728 if (fallback_fndecl == NULL_TREE)
2730 tree fntype;
2731 const char *name = NULL;
2733 switch (DECL_FUNCTION_CODE (fndecl))
2735 case BUILT_IN_ICEIL:
2736 case BUILT_IN_LCEIL:
2737 case BUILT_IN_LLCEIL:
2738 name = "ceil";
2739 break;
2740 case BUILT_IN_ICEILF:
2741 case BUILT_IN_LCEILF:
2742 case BUILT_IN_LLCEILF:
2743 name = "ceilf";
2744 break;
2745 case BUILT_IN_ICEILL:
2746 case BUILT_IN_LCEILL:
2747 case BUILT_IN_LLCEILL:
2748 name = "ceill";
2749 break;
2750 case BUILT_IN_IFLOOR:
2751 case BUILT_IN_LFLOOR:
2752 case BUILT_IN_LLFLOOR:
2753 name = "floor";
2754 break;
2755 case BUILT_IN_IFLOORF:
2756 case BUILT_IN_LFLOORF:
2757 case BUILT_IN_LLFLOORF:
2758 name = "floorf";
2759 break;
2760 case BUILT_IN_IFLOORL:
2761 case BUILT_IN_LFLOORL:
2762 case BUILT_IN_LLFLOORL:
2763 name = "floorl";
2764 break;
2765 default:
2766 gcc_unreachable ();
2769 fntype = build_function_type_list (TREE_TYPE (arg),
2770 TREE_TYPE (arg), NULL_TREE);
2771 fallback_fndecl = build_fn_decl (name, fntype);
2774 exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
2776 tmp = expand_normal (exp);
2778 /* Truncate the result of floating point optab to integer
2779 via expand_fix (). */
2780 target = gen_reg_rtx (mode);
2781 expand_fix (target, tmp, 0);
2783 return target;
2786 /* Expand a call to one of the builtin math functions doing integer
2787 conversion (lrint).
2788 Return 0 if a normal call should be emitted rather than expanding the
2789 function in-line. EXP is the expression that is a call to the builtin
2790 function; if convenient, the result should be placed in TARGET. */
2792 static rtx
2793 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2795 convert_optab builtin_optab;
2796 rtx op0, insns;
2797 tree fndecl = get_callee_fndecl (exp);
2798 tree arg;
2799 enum machine_mode mode;
2800 enum built_in_function fallback_fn = BUILT_IN_NONE;
2802 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2803 gcc_unreachable ();
2805 arg = CALL_EXPR_ARG (exp, 0);
2807 switch (DECL_FUNCTION_CODE (fndecl))
2809 CASE_FLT_FN (BUILT_IN_IRINT):
2810 fallback_fn = BUILT_IN_LRINT;
2811 /* FALLTHRU */
2812 CASE_FLT_FN (BUILT_IN_LRINT):
2813 CASE_FLT_FN (BUILT_IN_LLRINT):
2814 builtin_optab = lrint_optab;
2815 break;
2817 CASE_FLT_FN (BUILT_IN_IROUND):
2818 fallback_fn = BUILT_IN_LROUND;
2819 /* FALLTHRU */
2820 CASE_FLT_FN (BUILT_IN_LROUND):
2821 CASE_FLT_FN (BUILT_IN_LLROUND):
2822 builtin_optab = lround_optab;
2823 break;
2825 default:
2826 gcc_unreachable ();
2829 /* There's no easy way to detect the case we need to set EDOM. */
2830 if (flag_errno_math && fallback_fn == BUILT_IN_NONE)
2831 return NULL_RTX;
2833 /* Make a suitable register to place result in. */
2834 mode = TYPE_MODE (TREE_TYPE (exp));
2836 /* There's no easy way to detect the case we need to set EDOM. */
2837 if (!flag_errno_math)
2839 target = gen_reg_rtx (mode);
2841 /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2842 need to expand the argument again. This way, we will not perform
2843 side-effects more the once. */
2844 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2846 op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2848 start_sequence ();
2850 if (expand_sfix_optab (target, op0, builtin_optab))
2852 /* Output the entire sequence. */
2853 insns = get_insns ();
2854 end_sequence ();
2855 emit_insn (insns);
2856 return target;
2859 /* If we were unable to expand via the builtin, stop the sequence
2860 (without outputting the insns) and call to the library function
2861 with the stabilized argument list. */
2862 end_sequence ();
2865 if (fallback_fn != BUILT_IN_NONE)
2867 /* Fall back to rounding to long int. Use implicit_p 0 - for non-C99
2868 targets, (int) round (x) should never be transformed into
2869 BUILT_IN_IROUND and if __builtin_iround is called directly, emit
2870 a call to lround in the hope that the target provides at least some
2871 C99 functions. This should result in the best user experience for
2872 not full C99 targets. */
2873 tree fallback_fndecl = mathfn_built_in_1 (TREE_TYPE (arg),
2874 fallback_fn, 0);
2876 exp = build_call_nofold_loc (EXPR_LOCATION (exp),
2877 fallback_fndecl, 1, arg);
2879 target = expand_call (exp, NULL_RTX, target == const0_rtx);
2880 return convert_to_mode (mode, target, 0);
2883 target = expand_call (exp, target, target == const0_rtx);
2885 return target;
2888 /* Expand a call to the powi built-in mathematical function. Return NULL_RTX if
2889 a normal call should be emitted rather than expanding the function
2890 in-line. EXP is the expression that is a call to the builtin
2891 function; if convenient, the result should be placed in TARGET. */
2893 static rtx
2894 expand_builtin_powi (tree exp, rtx target)
2896 tree arg0, arg1;
2897 rtx op0, op1;
2898 enum machine_mode mode;
2899 enum machine_mode mode2;
2901 if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2902 return NULL_RTX;
2904 arg0 = CALL_EXPR_ARG (exp, 0);
2905 arg1 = CALL_EXPR_ARG (exp, 1);
2906 mode = TYPE_MODE (TREE_TYPE (exp));
2908 /* Emit a libcall to libgcc. */
2910 /* Mode of the 2nd argument must match that of an int. */
2911 mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2913 if (target == NULL_RTX)
2914 target = gen_reg_rtx (mode);
2916 op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL);
2917 if (GET_MODE (op0) != mode)
2918 op0 = convert_to_mode (mode, op0, 0);
2919 op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
2920 if (GET_MODE (op1) != mode2)
2921 op1 = convert_to_mode (mode2, op1, 0);
2923 target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2924 target, LCT_CONST, mode, 2,
2925 op0, mode, op1, mode2);
2927 return target;
2930 /* Expand expression EXP which is a call to the strlen builtin. Return
2931 NULL_RTX if we failed the caller should emit a normal call, otherwise
2932 try to get the result in TARGET, if convenient. */
2934 static rtx
2935 expand_builtin_strlen (tree exp, rtx target,
2936 enum machine_mode target_mode)
2938 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2939 return NULL_RTX;
2940 else
2942 struct expand_operand ops[4];
2943 rtx pat;
2944 tree len;
2945 tree src = CALL_EXPR_ARG (exp, 0);
2946 rtx src_reg, before_strlen;
2947 enum machine_mode insn_mode = target_mode;
2948 enum insn_code icode = CODE_FOR_nothing;
2949 unsigned int align;
2951 /* If the length can be computed at compile-time, return it. */
2952 len = c_strlen (src, 0);
2953 if (len)
2954 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2956 /* If the length can be computed at compile-time and is constant
2957 integer, but there are side-effects in src, evaluate
2958 src for side-effects, then return len.
2959 E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2960 can be optimized into: i++; x = 3; */
2961 len = c_strlen (src, 1);
2962 if (len && TREE_CODE (len) == INTEGER_CST)
2964 expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2965 return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2968 align = get_pointer_alignment (src) / BITS_PER_UNIT;
2970 /* If SRC is not a pointer type, don't do this operation inline. */
2971 if (align == 0)
2972 return NULL_RTX;
2974 /* Bail out if we can't compute strlen in the right mode. */
2975 while (insn_mode != VOIDmode)
2977 icode = optab_handler (strlen_optab, insn_mode);
2978 if (icode != CODE_FOR_nothing)
2979 break;
2981 insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2983 if (insn_mode == VOIDmode)
2984 return NULL_RTX;
2986 /* Make a place to hold the source address. We will not expand
2987 the actual source until we are sure that the expansion will
2988 not fail -- there are trees that cannot be expanded twice. */
2989 src_reg = gen_reg_rtx (Pmode);
2991 /* Mark the beginning of the strlen sequence so we can emit the
2992 source operand later. */
2993 before_strlen = get_last_insn ();
2995 create_output_operand (&ops[0], target, insn_mode);
2996 create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg));
2997 create_integer_operand (&ops[2], 0);
2998 create_integer_operand (&ops[3], align);
2999 if (!maybe_expand_insn (icode, 4, ops))
3000 return NULL_RTX;
3002 /* Now that we are assured of success, expand the source. */
3003 start_sequence ();
3004 pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL);
3005 if (pat != src_reg)
3007 #ifdef POINTERS_EXTEND_UNSIGNED
3008 if (GET_MODE (pat) != Pmode)
3009 pat = convert_to_mode (Pmode, pat,
3010 POINTERS_EXTEND_UNSIGNED);
3011 #endif
3012 emit_move_insn (src_reg, pat);
3014 pat = get_insns ();
3015 end_sequence ();
3017 if (before_strlen)
3018 emit_insn_after (pat, before_strlen);
3019 else
3020 emit_insn_before (pat, get_insns ());
3022 /* Return the value in the proper mode for this function. */
3023 if (GET_MODE (ops[0].value) == target_mode)
3024 target = ops[0].value;
3025 else if (target != 0)
3026 convert_move (target, ops[0].value, 0);
3027 else
3028 target = convert_to_mode (target_mode, ops[0].value, 0);
3030 return target;
3034 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3035 bytes from constant string DATA + OFFSET and return it as target
3036 constant. */
3038 static rtx
3039 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3040 enum machine_mode mode)
3042 const char *str = (const char *) data;
3044 gcc_assert (offset >= 0
3045 && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3046 <= strlen (str) + 1));
3048 return c_readstr (str + offset, mode);
3051 /* Expand a call EXP to the memcpy builtin.
3052 Return NULL_RTX if we failed, the caller should emit a normal call,
3053 otherwise try to get the result in TARGET, if convenient (and in
3054 mode MODE if that's convenient). */
3056 static rtx
3057 expand_builtin_memcpy (tree exp, rtx target)
3059 if (!validate_arglist (exp,
3060 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3061 return NULL_RTX;
3062 else
3064 tree dest = CALL_EXPR_ARG (exp, 0);
3065 tree src = CALL_EXPR_ARG (exp, 1);
3066 tree len = CALL_EXPR_ARG (exp, 2);
3067 const char *src_str;
3068 unsigned int src_align = get_pointer_alignment (src);
3069 unsigned int dest_align = get_pointer_alignment (dest);
3070 rtx dest_mem, src_mem, dest_addr, len_rtx;
3071 HOST_WIDE_INT expected_size = -1;
3072 unsigned int expected_align = 0;
3074 /* If DEST is not a pointer type, call the normal function. */
3075 if (dest_align == 0)
3076 return NULL_RTX;
3078 /* If either SRC is not a pointer type, don't do this
3079 operation in-line. */
3080 if (src_align == 0)
3081 return NULL_RTX;
3083 if (currently_expanding_gimple_stmt)
3084 stringop_block_profile (currently_expanding_gimple_stmt,
3085 &expected_align, &expected_size);
3087 if (expected_align < dest_align)
3088 expected_align = dest_align;
3089 dest_mem = get_memory_rtx (dest, len);
3090 set_mem_align (dest_mem, dest_align);
3091 len_rtx = expand_normal (len);
3092 src_str = c_getstr (src);
3094 /* If SRC is a string constant and block move would be done
3095 by pieces, we can avoid loading the string from memory
3096 and only stored the computed constants. */
3097 if (src_str
3098 && CONST_INT_P (len_rtx)
3099 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3100 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3101 CONST_CAST (char *, src_str),
3102 dest_align, false))
3104 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3105 builtin_memcpy_read_str,
3106 CONST_CAST (char *, src_str),
3107 dest_align, false, 0);
3108 dest_mem = force_operand (XEXP (dest_mem, 0), target);
3109 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3110 return dest_mem;
3113 src_mem = get_memory_rtx (src, len);
3114 set_mem_align (src_mem, src_align);
3116 /* Copy word part most expediently. */
3117 dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3118 CALL_EXPR_TAILCALL (exp)
3119 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3120 expected_align, expected_size);
3122 if (dest_addr == 0)
3124 dest_addr = force_operand (XEXP (dest_mem, 0), target);
3125 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3127 return dest_addr;
3131 /* Expand a call EXP to the mempcpy builtin.
3132 Return NULL_RTX if we failed; the caller should emit a normal call,
3133 otherwise try to get the result in TARGET, if convenient (and in
3134 mode MODE if that's convenient). If ENDP is 0 return the
3135 destination pointer, if ENDP is 1 return the end pointer ala
3136 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3137 stpcpy. */
3139 static rtx
3140 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3142 if (!validate_arglist (exp,
3143 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3144 return NULL_RTX;
3145 else
3147 tree dest = CALL_EXPR_ARG (exp, 0);
3148 tree src = CALL_EXPR_ARG (exp, 1);
3149 tree len = CALL_EXPR_ARG (exp, 2);
3150 return expand_builtin_mempcpy_args (dest, src, len,
3151 target, mode, /*endp=*/ 1);
3155 /* Helper function to do the actual work for expand_builtin_mempcpy. The
3156 arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3157 so that this can also be called without constructing an actual CALL_EXPR.
3158 The other arguments and return value are the same as for
3159 expand_builtin_mempcpy. */
3161 static rtx
3162 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3163 rtx target, enum machine_mode mode, int endp)
3165 /* If return value is ignored, transform mempcpy into memcpy. */
3166 if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
3168 tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3169 tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
3170 dest, src, len);
3171 return expand_expr (result, target, mode, EXPAND_NORMAL);
3173 else
3175 const char *src_str;
3176 unsigned int src_align = get_pointer_alignment (src);
3177 unsigned int dest_align = get_pointer_alignment (dest);
3178 rtx dest_mem, src_mem, len_rtx;
3180 /* If either SRC or DEST is not a pointer type, don't do this
3181 operation in-line. */
3182 if (dest_align == 0 || src_align == 0)
3183 return NULL_RTX;
3185 /* If LEN is not constant, call the normal function. */
3186 if (! host_integerp (len, 1))
3187 return NULL_RTX;
3189 len_rtx = expand_normal (len);
3190 src_str = c_getstr (src);
3192 /* If SRC is a string constant and block move would be done
3193 by pieces, we can avoid loading the string from memory
3194 and only stored the computed constants. */
3195 if (src_str
3196 && CONST_INT_P (len_rtx)
3197 && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3198 && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3199 CONST_CAST (char *, src_str),
3200 dest_align, false))
3202 dest_mem = get_memory_rtx (dest, len);
3203 set_mem_align (dest_mem, dest_align);
3204 dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3205 builtin_memcpy_read_str,
3206 CONST_CAST (char *, src_str),
3207 dest_align, false, endp);
3208 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3209 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3210 return dest_mem;
3213 if (CONST_INT_P (len_rtx)
3214 && can_move_by_pieces (INTVAL (len_rtx),
3215 MIN (dest_align, src_align)))
3217 dest_mem = get_memory_rtx (dest, len);
3218 set_mem_align (dest_mem, dest_align);
3219 src_mem = get_memory_rtx (src, len);
3220 set_mem_align (src_mem, src_align);
3221 dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3222 MIN (dest_align, src_align), endp);
3223 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3224 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3225 return dest_mem;
3228 return NULL_RTX;
3232 #ifndef HAVE_movstr
3233 # define HAVE_movstr 0
3234 # define CODE_FOR_movstr CODE_FOR_nothing
3235 #endif
3237 /* Expand into a movstr instruction, if one is available. Return NULL_RTX if
3238 we failed, the caller should emit a normal call, otherwise try to
3239 get the result in TARGET, if convenient. If ENDP is 0 return the
3240 destination pointer, if ENDP is 1 return the end pointer ala
3241 mempcpy, and if ENDP is 2 return the end pointer minus one ala
3242 stpcpy. */
3244 static rtx
3245 expand_movstr (tree dest, tree src, rtx target, int endp)
3247 struct expand_operand ops[3];
3248 rtx dest_mem;
3249 rtx src_mem;
3251 if (!HAVE_movstr)
3252 return NULL_RTX;
3254 dest_mem = get_memory_rtx (dest, NULL);
3255 src_mem = get_memory_rtx (src, NULL);
3256 if (!endp)
3258 target = force_reg (Pmode, XEXP (dest_mem, 0));
3259 dest_mem = replace_equiv_address (dest_mem, target);
3262 create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
3263 create_fixed_operand (&ops[1], dest_mem);
3264 create_fixed_operand (&ops[2], src_mem);
3265 expand_insn (CODE_FOR_movstr, 3, ops);
3267 if (endp && target != const0_rtx)
3269 target = ops[0].value;
3270 /* movstr is supposed to set end to the address of the NUL
3271 terminator. If the caller requested a mempcpy-like return value,
3272 adjust it. */
3273 if (endp == 1)
3275 rtx tem = plus_constant (GET_MODE (target),
3276 gen_lowpart (GET_MODE (target), target), 1);
3277 emit_move_insn (target, force_operand (tem, NULL_RTX));
3280 return target;
3283 /* Expand expression EXP, which is a call to the strcpy builtin. Return
3284 NULL_RTX if we failed the caller should emit a normal call, otherwise
3285 try to get the result in TARGET, if convenient (and in mode MODE if that's
3286 convenient). */
3288 static rtx
3289 expand_builtin_strcpy (tree exp, rtx target)
3291 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3293 tree dest = CALL_EXPR_ARG (exp, 0);
3294 tree src = CALL_EXPR_ARG (exp, 1);
3295 return expand_builtin_strcpy_args (dest, src, target);
3297 return NULL_RTX;
3300 /* Helper function to do the actual work for expand_builtin_strcpy. The
3301 arguments to the builtin_strcpy call DEST and SRC are broken out
3302 so that this can also be called without constructing an actual CALL_EXPR.
3303 The other arguments and return value are the same as for
3304 expand_builtin_strcpy. */
3306 static rtx
3307 expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3309 return expand_movstr (dest, src, target, /*endp=*/0);
3312 /* Expand a call EXP to the stpcpy builtin.
3313 Return NULL_RTX if we failed the caller should emit a normal call,
3314 otherwise try to get the result in TARGET, if convenient (and in
3315 mode MODE if that's convenient). */
3317 static rtx
3318 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3320 tree dst, src;
3321 location_t loc = EXPR_LOCATION (exp);
3323 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3324 return NULL_RTX;
3326 dst = CALL_EXPR_ARG (exp, 0);
3327 src = CALL_EXPR_ARG (exp, 1);
3329 /* If return value is ignored, transform stpcpy into strcpy. */
3330 if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY))
3332 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3333 tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
3334 return expand_expr (result, target, mode, EXPAND_NORMAL);
3336 else
3338 tree len, lenp1;
3339 rtx ret;
3341 /* Ensure we get an actual string whose length can be evaluated at
3342 compile-time, not an expression containing a string. This is
3343 because the latter will potentially produce pessimized code
3344 when used to produce the return value. */
3345 if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3346 return expand_movstr (dst, src, target, /*endp=*/2);
3348 lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3349 ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3350 target, mode, /*endp=*/2);
3352 if (ret)
3353 return ret;
3355 if (TREE_CODE (len) == INTEGER_CST)
3357 rtx len_rtx = expand_normal (len);
3359 if (CONST_INT_P (len_rtx))
3361 ret = expand_builtin_strcpy_args (dst, src, target);
3363 if (ret)
3365 if (! target)
3367 if (mode != VOIDmode)
3368 target = gen_reg_rtx (mode);
3369 else
3370 target = gen_reg_rtx (GET_MODE (ret));
3372 if (GET_MODE (target) != GET_MODE (ret))
3373 ret = gen_lowpart (GET_MODE (target), ret);
3375 ret = plus_constant (GET_MODE (ret), ret, INTVAL (len_rtx));
3376 ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3377 gcc_assert (ret);
3379 return target;
3384 return expand_movstr (dst, src, target, /*endp=*/2);
3388 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3389 bytes from constant string DATA + OFFSET and return it as target
3390 constant. */
3393 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3394 enum machine_mode mode)
3396 const char *str = (const char *) data;
3398 if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3399 return const0_rtx;
3401 return c_readstr (str + offset, mode);
3404 /* Expand expression EXP, which is a call to the strncpy builtin. Return
3405 NULL_RTX if we failed the caller should emit a normal call. */
3407 static rtx
3408 expand_builtin_strncpy (tree exp, rtx target)
3410 location_t loc = EXPR_LOCATION (exp);
3412 if (validate_arglist (exp,
3413 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3415 tree dest = CALL_EXPR_ARG (exp, 0);
3416 tree src = CALL_EXPR_ARG (exp, 1);
3417 tree len = CALL_EXPR_ARG (exp, 2);
3418 tree slen = c_strlen (src, 1);
3420 /* We must be passed a constant len and src parameter. */
3421 if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3422 return NULL_RTX;
3424 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3426 /* We're required to pad with trailing zeros if the requested
3427 len is greater than strlen(s2)+1. In that case try to
3428 use store_by_pieces, if it fails, punt. */
3429 if (tree_int_cst_lt (slen, len))
3431 unsigned int dest_align = get_pointer_alignment (dest);
3432 const char *p = c_getstr (src);
3433 rtx dest_mem;
3435 if (!p || dest_align == 0 || !host_integerp (len, 1)
3436 || !can_store_by_pieces (tree_low_cst (len, 1),
3437 builtin_strncpy_read_str,
3438 CONST_CAST (char *, p),
3439 dest_align, false))
3440 return NULL_RTX;
3442 dest_mem = get_memory_rtx (dest, len);
3443 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3444 builtin_strncpy_read_str,
3445 CONST_CAST (char *, p), dest_align, false, 0);
3446 dest_mem = force_operand (XEXP (dest_mem, 0), target);
3447 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3448 return dest_mem;
3451 return NULL_RTX;
3454 /* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
3455 bytes from constant string DATA + OFFSET and return it as target
3456 constant. */
3459 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3460 enum machine_mode mode)
3462 const char *c = (const char *) data;
3463 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3465 memset (p, *c, GET_MODE_SIZE (mode));
3467 return c_readstr (p, mode);
3470 /* Callback routine for store_by_pieces. Return the RTL of a register
3471 containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3472 char value given in the RTL register data. For example, if mode is
3473 4 bytes wide, return the RTL for 0x01010101*data. */
3475 static rtx
3476 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3477 enum machine_mode mode)
3479 rtx target, coeff;
3480 size_t size;
3481 char *p;
3483 size = GET_MODE_SIZE (mode);
3484 if (size == 1)
3485 return (rtx) data;
3487 p = XALLOCAVEC (char, size);
3488 memset (p, 1, size);
3489 coeff = c_readstr (p, mode);
3491 target = convert_to_mode (mode, (rtx) data, 1);
3492 target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3493 return force_reg (mode, target);
3496 /* Expand expression EXP, which is a call to the memset builtin. Return
3497 NULL_RTX if we failed the caller should emit a normal call, otherwise
3498 try to get the result in TARGET, if convenient (and in mode MODE if that's
3499 convenient). */
3501 static rtx
3502 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3504 if (!validate_arglist (exp,
3505 POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3506 return NULL_RTX;
3507 else
3509 tree dest = CALL_EXPR_ARG (exp, 0);
3510 tree val = CALL_EXPR_ARG (exp, 1);
3511 tree len = CALL_EXPR_ARG (exp, 2);
3512 return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3516 /* Helper function to do the actual work for expand_builtin_memset. The
3517 arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3518 so that this can also be called without constructing an actual CALL_EXPR.
3519 The other arguments and return value are the same as for
3520 expand_builtin_memset. */
3522 static rtx
3523 expand_builtin_memset_args (tree dest, tree val, tree len,
3524 rtx target, enum machine_mode mode, tree orig_exp)
3526 tree fndecl, fn;
3527 enum built_in_function fcode;
3528 enum machine_mode val_mode;
3529 char c;
3530 unsigned int dest_align;
3531 rtx dest_mem, dest_addr, len_rtx;
3532 HOST_WIDE_INT expected_size = -1;
3533 unsigned int expected_align = 0;
3535 dest_align = get_pointer_alignment (dest);
3537 /* If DEST is not a pointer type, don't do this operation in-line. */
3538 if (dest_align == 0)
3539 return NULL_RTX;
3541 if (currently_expanding_gimple_stmt)
3542 stringop_block_profile (currently_expanding_gimple_stmt,
3543 &expected_align, &expected_size);
3545 if (expected_align < dest_align)
3546 expected_align = dest_align;
3548 /* If the LEN parameter is zero, return DEST. */
3549 if (integer_zerop (len))
3551 /* Evaluate and ignore VAL in case it has side-effects. */
3552 expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3553 return expand_expr (dest, target, mode, EXPAND_NORMAL);
3556 /* Stabilize the arguments in case we fail. */
3557 dest = builtin_save_expr (dest);
3558 val = builtin_save_expr (val);
3559 len = builtin_save_expr (len);
3561 len_rtx = expand_normal (len);
3562 dest_mem = get_memory_rtx (dest, len);
3563 val_mode = TYPE_MODE (unsigned_char_type_node);
3565 if (TREE_CODE (val) != INTEGER_CST)
3567 rtx val_rtx;
3569 val_rtx = expand_normal (val);
3570 val_rtx = convert_to_mode (val_mode, val_rtx, 0);
3572 /* Assume that we can memset by pieces if we can store
3573 * the coefficients by pieces (in the required modes).
3574 * We can't pass builtin_memset_gen_str as that emits RTL. */
3575 c = 1;
3576 if (host_integerp (len, 1)
3577 && can_store_by_pieces (tree_low_cst (len, 1),
3578 builtin_memset_read_str, &c, dest_align,
3579 true))
3581 val_rtx = force_reg (val_mode, val_rtx);
3582 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3583 builtin_memset_gen_str, val_rtx, dest_align,
3584 true, 0);
3586 else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3587 dest_align, expected_align,
3588 expected_size))
3589 goto do_libcall;
3591 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3592 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3593 return dest_mem;
3596 if (target_char_cast (val, &c))
3597 goto do_libcall;
3599 if (c)
3601 if (host_integerp (len, 1)
3602 && can_store_by_pieces (tree_low_cst (len, 1),
3603 builtin_memset_read_str, &c, dest_align,
3604 true))
3605 store_by_pieces (dest_mem, tree_low_cst (len, 1),
3606 builtin_memset_read_str, &c, dest_align, true, 0);
3607 else if (!set_storage_via_setmem (dest_mem, len_rtx,
3608 gen_int_mode (c, val_mode),
3609 dest_align, expected_align,
3610 expected_size))
3611 goto do_libcall;
3613 dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3614 dest_mem = convert_memory_address (ptr_mode, dest_mem);
3615 return dest_mem;
3618 set_mem_align (dest_mem, dest_align);
3619 dest_addr = clear_storage_hints (dest_mem, len_rtx,
3620 CALL_EXPR_TAILCALL (orig_exp)
3621 ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3622 expected_align, expected_size);
3624 if (dest_addr == 0)
3626 dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3627 dest_addr = convert_memory_address (ptr_mode, dest_addr);
3630 return dest_addr;
3632 do_libcall:
3633 fndecl = get_callee_fndecl (orig_exp);
3634 fcode = DECL_FUNCTION_CODE (fndecl);
3635 if (fcode == BUILT_IN_MEMSET)
3636 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
3637 dest, val, len);
3638 else if (fcode == BUILT_IN_BZERO)
3639 fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2,
3640 dest, len);
3641 else
3642 gcc_unreachable ();
3643 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3644 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3645 return expand_call (fn, target, target == const0_rtx);
3648 /* Expand expression EXP, which is a call to the bzero builtin. Return
3649 NULL_RTX if we failed the caller should emit a normal call. */
3651 static rtx
3652 expand_builtin_bzero (tree exp)
3654 tree dest, size;
3655 location_t loc = EXPR_LOCATION (exp);
3657 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3658 return NULL_RTX;
3660 dest = CALL_EXPR_ARG (exp, 0);
3661 size = CALL_EXPR_ARG (exp, 1);
3663 /* New argument list transforming bzero(ptr x, int y) to
3664 memset(ptr x, int 0, size_t y). This is done this way
3665 so that if it isn't expanded inline, we fallback to
3666 calling bzero instead of memset. */
3668 return expand_builtin_memset_args (dest, integer_zero_node,
3669 fold_convert_loc (loc,
3670 size_type_node, size),
3671 const0_rtx, VOIDmode, exp);
3674 /* Expand expression EXP, which is a call to the memcmp built-in function.
3675 Return NULL_RTX if we failed and the caller should emit a normal call,
3676 otherwise try to get the result in TARGET, if convenient (and in mode
3677 MODE, if that's convenient). */
3679 static rtx
3680 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3681 ATTRIBUTE_UNUSED enum machine_mode mode)
3683 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3685 if (!validate_arglist (exp,
3686 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3687 return NULL_RTX;
3689 /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
3690 implementing memcmp because it will stop if it encounters two
3691 zero bytes. */
3692 #if defined HAVE_cmpmemsi
3694 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3695 rtx result;
3696 rtx insn;
3697 tree arg1 = CALL_EXPR_ARG (exp, 0);
3698 tree arg2 = CALL_EXPR_ARG (exp, 1);
3699 tree len = CALL_EXPR_ARG (exp, 2);
3701 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3702 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3703 enum machine_mode insn_mode;
3705 if (HAVE_cmpmemsi)
3706 insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3707 else
3708 return NULL_RTX;
3710 /* If we don't have POINTER_TYPE, call the function. */
3711 if (arg1_align == 0 || arg2_align == 0)
3712 return NULL_RTX;
3714 /* Make a place to write the result of the instruction. */
3715 result = target;
3716 if (! (result != 0
3717 && REG_P (result) && GET_MODE (result) == insn_mode
3718 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3719 result = gen_reg_rtx (insn_mode);
3721 arg1_rtx = get_memory_rtx (arg1, len);
3722 arg2_rtx = get_memory_rtx (arg2, len);
3723 arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3725 /* Set MEM_SIZE as appropriate. */
3726 if (CONST_INT_P (arg3_rtx))
3728 set_mem_size (arg1_rtx, INTVAL (arg3_rtx));
3729 set_mem_size (arg2_rtx, INTVAL (arg3_rtx));
3732 if (HAVE_cmpmemsi)
3733 insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3734 GEN_INT (MIN (arg1_align, arg2_align)));
3735 else
3736 gcc_unreachable ();
3738 if (insn)
3739 emit_insn (insn);
3740 else
3741 emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3742 TYPE_MODE (integer_type_node), 3,
3743 XEXP (arg1_rtx, 0), Pmode,
3744 XEXP (arg2_rtx, 0), Pmode,
3745 convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3746 TYPE_UNSIGNED (sizetype)),
3747 TYPE_MODE (sizetype));
3749 /* Return the value in the proper mode for this function. */
3750 mode = TYPE_MODE (TREE_TYPE (exp));
3751 if (GET_MODE (result) == mode)
3752 return result;
3753 else if (target != 0)
3755 convert_move (target, result, 0);
3756 return target;
3758 else
3759 return convert_to_mode (mode, result, 0);
3761 #endif /* HAVE_cmpmemsi. */
3763 return NULL_RTX;
3766 /* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
3767 if we failed the caller should emit a normal call, otherwise try to get
3768 the result in TARGET, if convenient. */
3770 static rtx
3771 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3773 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3774 return NULL_RTX;
3776 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3777 if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing
3778 || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing)
3780 rtx arg1_rtx, arg2_rtx;
3781 rtx result, insn = NULL_RTX;
3782 tree fndecl, fn;
3783 tree arg1 = CALL_EXPR_ARG (exp, 0);
3784 tree arg2 = CALL_EXPR_ARG (exp, 1);
3786 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3787 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3789 /* If we don't have POINTER_TYPE, call the function. */
3790 if (arg1_align == 0 || arg2_align == 0)
3791 return NULL_RTX;
3793 /* Stabilize the arguments in case gen_cmpstr(n)si fail. */
3794 arg1 = builtin_save_expr (arg1);
3795 arg2 = builtin_save_expr (arg2);
3797 arg1_rtx = get_memory_rtx (arg1, NULL);
3798 arg2_rtx = get_memory_rtx (arg2, NULL);
3800 #ifdef HAVE_cmpstrsi
3801 /* Try to call cmpstrsi. */
3802 if (HAVE_cmpstrsi)
3804 enum machine_mode insn_mode
3805 = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3807 /* Make a place to write the result of the instruction. */
3808 result = target;
3809 if (! (result != 0
3810 && REG_P (result) && GET_MODE (result) == insn_mode
3811 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3812 result = gen_reg_rtx (insn_mode);
3814 insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3815 GEN_INT (MIN (arg1_align, arg2_align)));
3817 #endif
3818 #ifdef HAVE_cmpstrnsi
3819 /* Try to determine at least one length and call cmpstrnsi. */
3820 if (!insn && HAVE_cmpstrnsi)
3822 tree len;
3823 rtx arg3_rtx;
3825 enum machine_mode insn_mode
3826 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3827 tree len1 = c_strlen (arg1, 1);
3828 tree len2 = c_strlen (arg2, 1);
3830 if (len1)
3831 len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3832 if (len2)
3833 len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3835 /* If we don't have a constant length for the first, use the length
3836 of the second, if we know it. We don't require a constant for
3837 this case; some cost analysis could be done if both are available
3838 but neither is constant. For now, assume they're equally cheap,
3839 unless one has side effects. If both strings have constant lengths,
3840 use the smaller. */
3842 if (!len1)
3843 len = len2;
3844 else if (!len2)
3845 len = len1;
3846 else if (TREE_SIDE_EFFECTS (len1))
3847 len = len2;
3848 else if (TREE_SIDE_EFFECTS (len2))
3849 len = len1;
3850 else if (TREE_CODE (len1) != INTEGER_CST)
3851 len = len2;
3852 else if (TREE_CODE (len2) != INTEGER_CST)
3853 len = len1;
3854 else if (tree_int_cst_lt (len1, len2))
3855 len = len1;
3856 else
3857 len = len2;
3859 /* If both arguments have side effects, we cannot optimize. */
3860 if (!len || TREE_SIDE_EFFECTS (len))
3861 goto do_libcall;
3863 arg3_rtx = expand_normal (len);
3865 /* Make a place to write the result of the instruction. */
3866 result = target;
3867 if (! (result != 0
3868 && REG_P (result) && GET_MODE (result) == insn_mode
3869 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3870 result = gen_reg_rtx (insn_mode);
3872 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3873 GEN_INT (MIN (arg1_align, arg2_align)));
3875 #endif
3877 if (insn)
3879 enum machine_mode mode;
3880 emit_insn (insn);
3882 /* Return the value in the proper mode for this function. */
3883 mode = TYPE_MODE (TREE_TYPE (exp));
3884 if (GET_MODE (result) == mode)
3885 return result;
3886 if (target == 0)
3887 return convert_to_mode (mode, result, 0);
3888 convert_move (target, result, 0);
3889 return target;
3892 /* Expand the library call ourselves using a stabilized argument
3893 list to avoid re-evaluating the function's arguments twice. */
3894 #ifdef HAVE_cmpstrnsi
3895 do_libcall:
3896 #endif
3897 fndecl = get_callee_fndecl (exp);
3898 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
3899 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3900 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3901 return expand_call (fn, target, target == const0_rtx);
3903 #endif
3904 return NULL_RTX;
3907 /* Expand expression EXP, which is a call to the strncmp builtin. Return
3908 NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
3909 the result in TARGET, if convenient. */
3911 static rtx
3912 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3913 ATTRIBUTE_UNUSED enum machine_mode mode)
3915 location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3917 if (!validate_arglist (exp,
3918 POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3919 return NULL_RTX;
3921 /* If c_strlen can determine an expression for one of the string
3922 lengths, and it doesn't have side effects, then emit cmpstrnsi
3923 using length MIN(strlen(string)+1, arg3). */
3924 #ifdef HAVE_cmpstrnsi
3925 if (HAVE_cmpstrnsi)
3927 tree len, len1, len2;
3928 rtx arg1_rtx, arg2_rtx, arg3_rtx;
3929 rtx result, insn;
3930 tree fndecl, fn;
3931 tree arg1 = CALL_EXPR_ARG (exp, 0);
3932 tree arg2 = CALL_EXPR_ARG (exp, 1);
3933 tree arg3 = CALL_EXPR_ARG (exp, 2);
3935 unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3936 unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3937 enum machine_mode insn_mode
3938 = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3940 len1 = c_strlen (arg1, 1);
3941 len2 = c_strlen (arg2, 1);
3943 if (len1)
3944 len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
3945 if (len2)
3946 len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
3948 /* If we don't have a constant length for the first, use the length
3949 of the second, if we know it. We don't require a constant for
3950 this case; some cost analysis could be done if both are available
3951 but neither is constant. For now, assume they're equally cheap,
3952 unless one has side effects. If both strings have constant lengths,
3953 use the smaller. */
3955 if (!len1)
3956 len = len2;
3957 else if (!len2)
3958 len = len1;
3959 else if (TREE_SIDE_EFFECTS (len1))
3960 len = len2;
3961 else if (TREE_SIDE_EFFECTS (len2))
3962 len = len1;
3963 else if (TREE_CODE (len1) != INTEGER_CST)
3964 len = len2;
3965 else if (TREE_CODE (len2) != INTEGER_CST)
3966 len = len1;
3967 else if (tree_int_cst_lt (len1, len2))
3968 len = len1;
3969 else
3970 len = len2;
3972 /* If both arguments have side effects, we cannot optimize. */
3973 if (!len || TREE_SIDE_EFFECTS (len))
3974 return NULL_RTX;
3976 /* The actual new length parameter is MIN(len,arg3). */
3977 len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
3978 fold_convert_loc (loc, TREE_TYPE (len), arg3));
3980 /* If we don't have POINTER_TYPE, call the function. */
3981 if (arg1_align == 0 || arg2_align == 0)
3982 return NULL_RTX;
3984 /* Make a place to write the result of the instruction. */
3985 result = target;
3986 if (! (result != 0
3987 && REG_P (result) && GET_MODE (result) == insn_mode
3988 && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3989 result = gen_reg_rtx (insn_mode);
3991 /* Stabilize the arguments in case gen_cmpstrnsi fails. */
3992 arg1 = builtin_save_expr (arg1);
3993 arg2 = builtin_save_expr (arg2);
3994 len = builtin_save_expr (len);
3996 arg1_rtx = get_memory_rtx (arg1, len);
3997 arg2_rtx = get_memory_rtx (arg2, len);
3998 arg3_rtx = expand_normal (len);
3999 insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4000 GEN_INT (MIN (arg1_align, arg2_align)));
4001 if (insn)
4003 emit_insn (insn);
4005 /* Return the value in the proper mode for this function. */
4006 mode = TYPE_MODE (TREE_TYPE (exp));
4007 if (GET_MODE (result) == mode)
4008 return result;
4009 if (target == 0)
4010 return convert_to_mode (mode, result, 0);
4011 convert_move (target, result, 0);
4012 return target;
4015 /* Expand the library call ourselves using a stabilized argument
4016 list to avoid re-evaluating the function's arguments twice. */
4017 fndecl = get_callee_fndecl (exp);
4018 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
4019 arg1, arg2, len);
4020 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4021 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4022 return expand_call (fn, target, target == const0_rtx);
4024 #endif
4025 return NULL_RTX;
4028 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4029 if that's convenient. */
4032 expand_builtin_saveregs (void)
4034 rtx val, seq;
4036 /* Don't do __builtin_saveregs more than once in a function.
4037 Save the result of the first call and reuse it. */
4038 if (saveregs_value != 0)
4039 return saveregs_value;
4041 /* When this function is called, it means that registers must be
4042 saved on entry to this function. So we migrate the call to the
4043 first insn of this function. */
4045 start_sequence ();
4047 /* Do whatever the machine needs done in this case. */
4048 val = targetm.calls.expand_builtin_saveregs ();
4050 seq = get_insns ();
4051 end_sequence ();
4053 saveregs_value = val;
4055 /* Put the insns after the NOTE that starts the function. If this
4056 is inside a start_sequence, make the outer-level insn chain current, so
4057 the code is placed at the start of the function. */
4058 push_topmost_sequence ();
4059 emit_insn_after (seq, entry_of_function ());
4060 pop_topmost_sequence ();
4062 return val;
4065 /* Expand a call to __builtin_next_arg. */
4067 static rtx
4068 expand_builtin_next_arg (void)
4070 /* Checking arguments is already done in fold_builtin_next_arg
4071 that must be called before this function. */
4072 return expand_binop (ptr_mode, add_optab,
4073 crtl->args.internal_arg_pointer,
4074 crtl->args.arg_offset_rtx,
4075 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4078 /* Make it easier for the backends by protecting the valist argument
4079 from multiple evaluations. */
4081 static tree
4082 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4084 tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4086 /* The current way of determining the type of valist is completely
4087 bogus. We should have the information on the va builtin instead. */
4088 if (!vatype)
4089 vatype = targetm.fn_abi_va_list (cfun->decl);
4091 if (TREE_CODE (vatype) == ARRAY_TYPE)
4093 if (TREE_SIDE_EFFECTS (valist))
4094 valist = save_expr (valist);
4096 /* For this case, the backends will be expecting a pointer to
4097 vatype, but it's possible we've actually been given an array
4098 (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4099 So fix it. */
4100 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4102 tree p1 = build_pointer_type (TREE_TYPE (vatype));
4103 valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4106 else
4108 tree pt = build_pointer_type (vatype);
4110 if (! needs_lvalue)
4112 if (! TREE_SIDE_EFFECTS (valist))
4113 return valist;
4115 valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4116 TREE_SIDE_EFFECTS (valist) = 1;
4119 if (TREE_SIDE_EFFECTS (valist))
4120 valist = save_expr (valist);
4121 valist = fold_build2_loc (loc, MEM_REF,
4122 vatype, valist, build_int_cst (pt, 0));
4125 return valist;
4128 /* The "standard" definition of va_list is void*. */
4130 tree
4131 std_build_builtin_va_list (void)
4133 return ptr_type_node;
4136 /* The "standard" abi va_list is va_list_type_node. */
4138 tree
4139 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4141 return va_list_type_node;
4144 /* The "standard" type of va_list is va_list_type_node. */
4146 tree
4147 std_canonical_va_list_type (tree type)
4149 tree wtype, htype;
4151 if (INDIRECT_REF_P (type))
4152 type = TREE_TYPE (type);
4153 else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4154 type = TREE_TYPE (type);
4155 wtype = va_list_type_node;
4156 htype = type;
4157 /* Treat structure va_list types. */
4158 if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4159 htype = TREE_TYPE (htype);
4160 else if (TREE_CODE (wtype) == ARRAY_TYPE)
4162 /* If va_list is an array type, the argument may have decayed
4163 to a pointer type, e.g. by being passed to another function.
4164 In that case, unwrap both types so that we can compare the
4165 underlying records. */
4166 if (TREE_CODE (htype) == ARRAY_TYPE
4167 || POINTER_TYPE_P (htype))
4169 wtype = TREE_TYPE (wtype);
4170 htype = TREE_TYPE (htype);
4173 if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4174 return va_list_type_node;
4176 return NULL_TREE;
4179 /* The "standard" implementation of va_start: just assign `nextarg' to
4180 the variable. */
4182 void
4183 std_expand_builtin_va_start (tree valist, rtx nextarg)
4185 rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4186 convert_move (va_r, nextarg, 0);
4189 /* Expand EXP, a call to __builtin_va_start. */
4191 static rtx
4192 expand_builtin_va_start (tree exp)
4194 rtx nextarg;
4195 tree valist;
4196 location_t loc = EXPR_LOCATION (exp);
4198 if (call_expr_nargs (exp) < 2)
4200 error_at (loc, "too few arguments to function %<va_start%>");
4201 return const0_rtx;
4204 if (fold_builtin_next_arg (exp, true))
4205 return const0_rtx;
4207 nextarg = expand_builtin_next_arg ();
4208 valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4210 if (targetm.expand_builtin_va_start)
4211 targetm.expand_builtin_va_start (valist, nextarg);
4212 else
4213 std_expand_builtin_va_start (valist, nextarg);
4215 return const0_rtx;
4218 /* The "standard" implementation of va_arg: read the value from the
4219 current (padded) address and increment by the (padded) size. */
4221 tree
4222 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4223 gimple_seq *post_p)
4225 tree addr, t, type_size, rounded_size, valist_tmp;
4226 unsigned HOST_WIDE_INT align, boundary;
4227 bool indirect;
4229 #ifdef ARGS_GROW_DOWNWARD
4230 /* All of the alignment and movement below is for args-grow-up machines.
4231 As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4232 implement their own specialized gimplify_va_arg_expr routines. */
4233 gcc_unreachable ();
4234 #endif
4236 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4237 if (indirect)
4238 type = build_pointer_type (type);
4240 align = PARM_BOUNDARY / BITS_PER_UNIT;
4241 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
4243 /* When we align parameter on stack for caller, if the parameter
4244 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4245 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee
4246 here with caller. */
4247 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4248 boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4250 boundary /= BITS_PER_UNIT;
4252 /* Hoist the valist value into a temporary for the moment. */
4253 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4255 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
4256 requires greater alignment, we must perform dynamic alignment. */
4257 if (boundary > align
4258 && !integer_zerop (TYPE_SIZE (type)))
4260 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4261 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
4262 gimplify_and_add (t, pre_p);
4264 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4265 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
4266 valist_tmp,
4267 build_int_cst (TREE_TYPE (valist), -boundary)));
4268 gimplify_and_add (t, pre_p);
4270 else
4271 boundary = align;
4273 /* If the actual alignment is less than the alignment of the type,
4274 adjust the type accordingly so that we don't assume strict alignment
4275 when dereferencing the pointer. */
4276 boundary *= BITS_PER_UNIT;
4277 if (boundary < TYPE_ALIGN (type))
4279 type = build_variant_type_copy (type);
4280 TYPE_ALIGN (type) = boundary;
4283 /* Compute the rounded size of the type. */
4284 type_size = size_in_bytes (type);
4285 rounded_size = round_up (type_size, align);
4287 /* Reduce rounded_size so it's sharable with the postqueue. */
4288 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4290 /* Get AP. */
4291 addr = valist_tmp;
4292 if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4294 /* Small args are padded downward. */
4295 t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4296 rounded_size, size_int (align));
4297 t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4298 size_binop (MINUS_EXPR, rounded_size, type_size));
4299 addr = fold_build_pointer_plus (addr, t);
4302 /* Compute new value for AP. */
4303 t = fold_build_pointer_plus (valist_tmp, rounded_size);
4304 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4305 gimplify_and_add (t, pre_p);
4307 addr = fold_convert (build_pointer_type (type), addr);
4309 if (indirect)
4310 addr = build_va_arg_indirect_ref (addr);
4312 return build_va_arg_indirect_ref (addr);
4315 /* Build an indirect-ref expression over the given TREE, which represents a
4316 piece of a va_arg() expansion. */
4317 tree
4318 build_va_arg_indirect_ref (tree addr)
4320 addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
4322 if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */
4323 mf_mark (addr);
4325 return addr;
4328 /* Return a dummy expression of type TYPE in order to keep going after an
4329 error. */
4331 static tree
4332 dummy_object (tree type)
4334 tree t = build_int_cst (build_pointer_type (type), 0);
4335 return build2 (MEM_REF, type, t, t);
4338 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4339 builtin function, but a very special sort of operator. */
4341 enum gimplify_status
4342 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4344 tree promoted_type, have_va_type;
4345 tree valist = TREE_OPERAND (*expr_p, 0);
4346 tree type = TREE_TYPE (*expr_p);
4347 tree t;
4348 location_t loc = EXPR_LOCATION (*expr_p);
4350 /* Verify that valist is of the proper type. */
4351 have_va_type = TREE_TYPE (valist);
4352 if (have_va_type == error_mark_node)
4353 return GS_ERROR;
4354 have_va_type = targetm.canonical_va_list_type (have_va_type);
4356 if (have_va_type == NULL_TREE)
4358 error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4359 return GS_ERROR;
4362 /* Generate a diagnostic for requesting data of a type that cannot
4363 be passed through `...' due to type promotion at the call site. */
4364 if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4365 != type)
4367 static bool gave_help;
4368 bool warned;
4370 /* Unfortunately, this is merely undefined, rather than a constraint
4371 violation, so we cannot make this an error. If this call is never
4372 executed, the program is still strictly conforming. */
4373 warned = warning_at (loc, 0,
4374 "%qT is promoted to %qT when passed through %<...%>",
4375 type, promoted_type);
4376 if (!gave_help && warned)
4378 gave_help = true;
4379 inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4380 promoted_type, type);
4383 /* We can, however, treat "undefined" any way we please.
4384 Call abort to encourage the user to fix the program. */
4385 if (warned)
4386 inform (loc, "if this code is reached, the program will abort");
4387 /* Before the abort, allow the evaluation of the va_list
4388 expression to exit or longjmp. */
4389 gimplify_and_add (valist, pre_p);
4390 t = build_call_expr_loc (loc,
4391 builtin_decl_implicit (BUILT_IN_TRAP), 0);
4392 gimplify_and_add (t, pre_p);
4394 /* This is dead code, but go ahead and finish so that the
4395 mode of the result comes out right. */
4396 *expr_p = dummy_object (type);
4397 return GS_ALL_DONE;
4399 else
4401 /* Make it easier for the backends by protecting the valist argument
4402 from multiple evaluations. */
4403 if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4405 /* For this case, the backends will be expecting a pointer to
4406 TREE_TYPE (abi), but it's possible we've
4407 actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4408 So fix it. */
4409 if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4411 tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4412 valist = fold_convert_loc (loc, p1,
4413 build_fold_addr_expr_loc (loc, valist));
4416 gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4418 else
4419 gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4421 if (!targetm.gimplify_va_arg_expr)
4422 /* FIXME: Once most targets are converted we should merely
4423 assert this is non-null. */
4424 return GS_ALL_DONE;
4426 *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4427 return GS_OK;
4431 /* Expand EXP, a call to __builtin_va_end. */
4433 static rtx
4434 expand_builtin_va_end (tree exp)
4436 tree valist = CALL_EXPR_ARG (exp, 0);
4438 /* Evaluate for side effects, if needed. I hate macros that don't
4439 do that. */
4440 if (TREE_SIDE_EFFECTS (valist))
4441 expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4443 return const0_rtx;
4446 /* Expand EXP, a call to __builtin_va_copy. We do this as a
4447 builtin rather than just as an assignment in stdarg.h because of the
4448 nastiness of array-type va_list types. */
4450 static rtx
4451 expand_builtin_va_copy (tree exp)
4453 tree dst, src, t;
4454 location_t loc = EXPR_LOCATION (exp);
4456 dst = CALL_EXPR_ARG (exp, 0);
4457 src = CALL_EXPR_ARG (exp, 1);
4459 dst = stabilize_va_list_loc (loc, dst, 1);
4460 src = stabilize_va_list_loc (loc, src, 0);
4462 gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4464 if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4466 t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4467 TREE_SIDE_EFFECTS (t) = 1;
4468 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4470 else
4472 rtx dstb, srcb, size;
4474 /* Evaluate to pointers. */
4475 dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4476 srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4477 size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4478 NULL_RTX, VOIDmode, EXPAND_NORMAL);
4480 dstb = convert_memory_address (Pmode, dstb);
4481 srcb = convert_memory_address (Pmode, srcb);
4483 /* "Dereference" to BLKmode memories. */
4484 dstb = gen_rtx_MEM (BLKmode, dstb);
4485 set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4486 set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4487 srcb = gen_rtx_MEM (BLKmode, srcb);
4488 set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4489 set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4491 /* Copy. */
4492 emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4495 return const0_rtx;
4498 /* Expand a call to one of the builtin functions __builtin_frame_address or
4499 __builtin_return_address. */
4501 static rtx
4502 expand_builtin_frame_address (tree fndecl, tree exp)
4504 /* The argument must be a nonnegative integer constant.
4505 It counts the number of frames to scan up the stack.
4506 The value is the return address saved in that frame. */
4507 if (call_expr_nargs (exp) == 0)
4508 /* Warning about missing arg was already issued. */
4509 return const0_rtx;
4510 else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4512 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4513 error ("invalid argument to %<__builtin_frame_address%>");
4514 else
4515 error ("invalid argument to %<__builtin_return_address%>");
4516 return const0_rtx;
4518 else
4520 rtx tem
4521 = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4522 tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4524 /* Some ports cannot access arbitrary stack frames. */
4525 if (tem == NULL)
4527 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4528 warning (0, "unsupported argument to %<__builtin_frame_address%>");
4529 else
4530 warning (0, "unsupported argument to %<__builtin_return_address%>");
4531 return const0_rtx;
4534 /* For __builtin_frame_address, return what we've got. */
4535 if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4536 return tem;
4538 if (!REG_P (tem)
4539 && ! CONSTANT_P (tem))
4540 tem = copy_addr_to_reg (tem);
4541 return tem;
4545 /* Expand EXP, a call to the alloca builtin. Return NULL_RTX if we
4546 failed and the caller should emit a normal call. CANNOT_ACCUMULATE
4547 is the same as for allocate_dynamic_stack_space. */
4549 static rtx
4550 expand_builtin_alloca (tree exp, bool cannot_accumulate)
4552 rtx op0;
4553 rtx result;
4554 bool valid_arglist;
4555 unsigned int align;
4556 bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
4557 == BUILT_IN_ALLOCA_WITH_ALIGN);
4559 /* Emit normal call if we use mudflap. */
4560 if (flag_mudflap)
4561 return NULL_RTX;
4563 valid_arglist
4564 = (alloca_with_align
4565 ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
4566 : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE));
4568 if (!valid_arglist)
4569 return NULL_RTX;
4571 /* Compute the argument. */
4572 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4574 /* Compute the alignment. */
4575 align = (alloca_with_align
4576 ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
4577 : BIGGEST_ALIGNMENT);
4579 /* Allocate the desired space. */
4580 result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate);
4581 result = convert_memory_address (ptr_mode, result);
4583 return result;
4586 /* Expand a call to bswap builtin in EXP.
4587 Return NULL_RTX if a normal call should be emitted rather than expanding the
4588 function in-line. If convenient, the result should be placed in TARGET.
4589 SUBTARGET may be used as the target for computing one of EXP's operands. */
4591 static rtx
4592 expand_builtin_bswap (enum machine_mode target_mode, tree exp, rtx target,
4593 rtx subtarget)
4595 tree arg;
4596 rtx op0;
4598 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4599 return NULL_RTX;
4601 arg = CALL_EXPR_ARG (exp, 0);
4602 op0 = expand_expr (arg,
4603 subtarget && GET_MODE (subtarget) == target_mode
4604 ? subtarget : NULL_RTX,
4605 target_mode, EXPAND_NORMAL);
4606 if (GET_MODE (op0) != target_mode)
4607 op0 = convert_to_mode (target_mode, op0, 1);
4609 target = expand_unop (target_mode, bswap_optab, op0, target, 1);
4611 gcc_assert (target);
4613 return convert_to_mode (target_mode, target, 1);
4616 /* Expand a call to a unary builtin in EXP.
4617 Return NULL_RTX if a normal call should be emitted rather than expanding the
4618 function in-line. If convenient, the result should be placed in TARGET.
4619 SUBTARGET may be used as the target for computing one of EXP's operands. */
4621 static rtx
4622 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4623 rtx subtarget, optab op_optab)
4625 rtx op0;
4627 if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4628 return NULL_RTX;
4630 /* Compute the argument. */
4631 op0 = expand_expr (CALL_EXPR_ARG (exp, 0),
4632 (subtarget
4633 && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))
4634 == GET_MODE (subtarget))) ? subtarget : NULL_RTX,
4635 VOIDmode, EXPAND_NORMAL);
4636 /* Compute op, into TARGET if possible.
4637 Set TARGET to wherever the result comes back. */
4638 target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4639 op_optab, op0, target, op_optab != clrsb_optab);
4640 gcc_assert (target);
4642 return convert_to_mode (target_mode, target, 0);
4645 /* Expand a call to __builtin_expect. We just return our argument
4646 as the builtin_expect semantic should've been already executed by
4647 tree branch prediction pass. */
4649 static rtx
4650 expand_builtin_expect (tree exp, rtx target)
4652 tree arg;
4654 if (call_expr_nargs (exp) < 2)
4655 return const0_rtx;
4656 arg = CALL_EXPR_ARG (exp, 0);
4658 target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4659 /* When guessing was done, the hints should be already stripped away. */
4660 gcc_assert (!flag_guess_branch_prob
4661 || optimize == 0 || seen_error ());
4662 return target;
4665 /* Expand a call to __builtin_assume_aligned. We just return our first
4666 argument as the builtin_assume_aligned semantic should've been already
4667 executed by CCP. */
4669 static rtx
4670 expand_builtin_assume_aligned (tree exp, rtx target)
4672 if (call_expr_nargs (exp) < 2)
4673 return const0_rtx;
4674 target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode,
4675 EXPAND_NORMAL);
4676 gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1))
4677 && (call_expr_nargs (exp) < 3
4678 || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2))));
4679 return target;
4682 void
4683 expand_builtin_trap (void)
4685 #ifdef HAVE_trap
4686 if (HAVE_trap)
4687 emit_insn (gen_trap ());
4688 else
4689 #endif
4690 emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4691 emit_barrier ();
4694 /* Expand a call to __builtin_unreachable. We do nothing except emit
4695 a barrier saying that control flow will not pass here.
4697 It is the responsibility of the program being compiled to ensure
4698 that control flow does never reach __builtin_unreachable. */
4699 static void
4700 expand_builtin_unreachable (void)
4702 emit_barrier ();
4705 /* Expand EXP, a call to fabs, fabsf or fabsl.
4706 Return NULL_RTX if a normal call should be emitted rather than expanding
4707 the function inline. If convenient, the result should be placed
4708 in TARGET. SUBTARGET may be used as the target for computing
4709 the operand. */
4711 static rtx
4712 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4714 enum machine_mode mode;
4715 tree arg;
4716 rtx op0;
4718 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4719 return NULL_RTX;
4721 arg = CALL_EXPR_ARG (exp, 0);
4722 CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4723 mode = TYPE_MODE (TREE_TYPE (arg));
4724 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4725 return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4728 /* Expand EXP, a call to copysign, copysignf, or copysignl.
4729 Return NULL is a normal call should be emitted rather than expanding the
4730 function inline. If convenient, the result should be placed in TARGET.
4731 SUBTARGET may be used as the target for computing the operand. */
4733 static rtx
4734 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4736 rtx op0, op1;
4737 tree arg;
4739 if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4740 return NULL_RTX;
4742 arg = CALL_EXPR_ARG (exp, 0);
4743 op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4745 arg = CALL_EXPR_ARG (exp, 1);
4746 op1 = expand_normal (arg);
4748 return expand_copysign (op0, op1, target);
4751 /* Create a new constant string literal and return a char* pointer to it.
4752 The STRING_CST value is the LEN characters at STR. */
4753 tree
4754 build_string_literal (int len, const char *str)
4756 tree t, elem, index, type;
4758 t = build_string (len, str);
4759 elem = build_type_variant (char_type_node, 1, 0);
4760 index = build_index_type (size_int (len - 1));
4761 type = build_array_type (elem, index);
4762 TREE_TYPE (t) = type;
4763 TREE_CONSTANT (t) = 1;
4764 TREE_READONLY (t) = 1;
4765 TREE_STATIC (t) = 1;
4767 type = build_pointer_type (elem);
4768 t = build1 (ADDR_EXPR, type,
4769 build4 (ARRAY_REF, elem,
4770 t, integer_zero_node, NULL_TREE, NULL_TREE));
4771 return t;
4774 /* Expand a call to __builtin___clear_cache. */
4776 static rtx
4777 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
4779 #ifndef HAVE_clear_cache
4780 #ifdef CLEAR_INSN_CACHE
4781 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4782 does something. Just do the default expansion to a call to
4783 __clear_cache(). */
4784 return NULL_RTX;
4785 #else
4786 /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4787 does nothing. There is no need to call it. Do nothing. */
4788 return const0_rtx;
4789 #endif /* CLEAR_INSN_CACHE */
4790 #else
4791 /* We have a "clear_cache" insn, and it will handle everything. */
4792 tree begin, end;
4793 rtx begin_rtx, end_rtx;
4795 /* We must not expand to a library call. If we did, any
4796 fallback library function in libgcc that might contain a call to
4797 __builtin___clear_cache() would recurse infinitely. */
4798 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4800 error ("both arguments to %<__builtin___clear_cache%> must be pointers");
4801 return const0_rtx;
4804 if (HAVE_clear_cache)
4806 struct expand_operand ops[2];
4808 begin = CALL_EXPR_ARG (exp, 0);
4809 begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
4811 end = CALL_EXPR_ARG (exp, 1);
4812 end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
4814 create_address_operand (&ops[0], begin_rtx);
4815 create_address_operand (&ops[1], end_rtx);
4816 if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops))
4817 return const0_rtx;
4819 return const0_rtx;
4820 #endif /* HAVE_clear_cache */
4823 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */
4825 static rtx
4826 round_trampoline_addr (rtx tramp)
4828 rtx temp, addend, mask;
4830 /* If we don't need too much alignment, we'll have been guaranteed
4831 proper alignment by get_trampoline_type. */
4832 if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4833 return tramp;
4835 /* Round address up to desired boundary. */
4836 temp = gen_reg_rtx (Pmode);
4837 addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4838 mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4840 temp = expand_simple_binop (Pmode, PLUS, tramp, addend,
4841 temp, 0, OPTAB_LIB_WIDEN);
4842 tramp = expand_simple_binop (Pmode, AND, temp, mask,
4843 temp, 0, OPTAB_LIB_WIDEN);
4845 return tramp;
4848 static rtx
4849 expand_builtin_init_trampoline (tree exp, bool onstack)
4851 tree t_tramp, t_func, t_chain;
4852 rtx m_tramp, r_tramp, r_chain, tmp;
4854 if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4855 POINTER_TYPE, VOID_TYPE))
4856 return NULL_RTX;
4858 t_tramp = CALL_EXPR_ARG (exp, 0);
4859 t_func = CALL_EXPR_ARG (exp, 1);
4860 t_chain = CALL_EXPR_ARG (exp, 2);
4862 r_tramp = expand_normal (t_tramp);
4863 m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
4864 MEM_NOTRAP_P (m_tramp) = 1;
4866 /* If ONSTACK, the TRAMP argument should be the address of a field
4867 within the local function's FRAME decl. Either way, let's see if
4868 we can fill in the MEM_ATTRs for this memory. */
4869 if (TREE_CODE (t_tramp) == ADDR_EXPR)
4870 set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
4871 true, 0);
4873 /* Creator of a heap trampoline is responsible for making sure the
4874 address is aligned to at least STACK_BOUNDARY. Normally malloc
4875 will ensure this anyhow. */
4876 tmp = round_trampoline_addr (r_tramp);
4877 if (tmp != r_tramp)
4879 m_tramp = change_address (m_tramp, BLKmode, tmp);
4880 set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
4881 set_mem_size (m_tramp, TRAMPOLINE_SIZE);
4884 /* The FUNC argument should be the address of the nested function.
4885 Extract the actual function decl to pass to the hook. */
4886 gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
4887 t_func = TREE_OPERAND (t_func, 0);
4888 gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
4890 r_chain = expand_normal (t_chain);
4892 /* Generate insns to initialize the trampoline. */
4893 targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4895 if (onstack)
4897 trampolines_created = 1;
4899 warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines,
4900 "trampoline generated for nested function %qD", t_func);
4903 return const0_rtx;
4906 static rtx
4907 expand_builtin_adjust_trampoline (tree exp)
4909 rtx tramp;
4911 if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4912 return NULL_RTX;
4914 tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4915 tramp = round_trampoline_addr (tramp);
4916 if (targetm.calls.trampoline_adjust_address)
4917 tramp = targetm.calls.trampoline_adjust_address (tramp);
4919 return tramp;
4922 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
4923 function. The function first checks whether the back end provides
4924 an insn to implement signbit for the respective mode. If not, it
4925 checks whether the floating point format of the value is such that
4926 the sign bit can be extracted. If that is not the case, the
4927 function returns NULL_RTX to indicate that a normal call should be
4928 emitted rather than expanding the function in-line. EXP is the
4929 expression that is a call to the builtin function; if convenient,
4930 the result should be placed in TARGET. */
4931 static rtx
4932 expand_builtin_signbit (tree exp, rtx target)
4934 const struct real_format *fmt;
4935 enum machine_mode fmode, imode, rmode;
4936 tree arg;
4937 int word, bitpos;
4938 enum insn_code icode;
4939 rtx temp;
4940 location_t loc = EXPR_LOCATION (exp);
4942 if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4943 return NULL_RTX;
4945 arg = CALL_EXPR_ARG (exp, 0);
4946 fmode = TYPE_MODE (TREE_TYPE (arg));
4947 rmode = TYPE_MODE (TREE_TYPE (exp));
4948 fmt = REAL_MODE_FORMAT (fmode);
4950 arg = builtin_save_expr (arg);
4952 /* Expand the argument yielding a RTX expression. */
4953 temp = expand_normal (arg);
4955 /* Check if the back end provides an insn that handles signbit for the
4956 argument's mode. */
4957 icode = optab_handler (signbit_optab, fmode);
4958 if (icode != CODE_FOR_nothing)
4960 rtx last = get_last_insn ();
4961 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
4962 if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
4963 return target;
4964 delete_insns_since (last);
4967 /* For floating point formats without a sign bit, implement signbit
4968 as "ARG < 0.0". */
4969 bitpos = fmt->signbit_ro;
4970 if (bitpos < 0)
4972 /* But we can't do this if the format supports signed zero. */
4973 if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4974 return NULL_RTX;
4976 arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
4977 build_real (TREE_TYPE (arg), dconst0));
4978 return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4981 if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4983 imode = int_mode_for_mode (fmode);
4984 if (imode == BLKmode)
4985 return NULL_RTX;
4986 temp = gen_lowpart (imode, temp);
4988 else
4990 imode = word_mode;
4991 /* Handle targets with different FP word orders. */
4992 if (FLOAT_WORDS_BIG_ENDIAN)
4993 word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
4994 else
4995 word = bitpos / BITS_PER_WORD;
4996 temp = operand_subword_force (temp, word, fmode);
4997 bitpos = bitpos % BITS_PER_WORD;
5000 /* Force the intermediate word_mode (or narrower) result into a
5001 register. This avoids attempting to create paradoxical SUBREGs
5002 of floating point modes below. */
5003 temp = force_reg (imode, temp);
5005 /* If the bitpos is within the "result mode" lowpart, the operation
5006 can be implement with a single bitwise AND. Otherwise, we need
5007 a right shift and an AND. */
5009 if (bitpos < GET_MODE_BITSIZE (rmode))
5011 double_int mask = double_int_setbit (double_int_zero, bitpos);
5013 if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5014 temp = gen_lowpart (rmode, temp);
5015 temp = expand_binop (rmode, and_optab, temp,
5016 immed_double_int_const (mask, rmode),
5017 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5019 else
5021 /* Perform a logical right shift to place the signbit in the least
5022 significant bit, then truncate the result to the desired mode
5023 and mask just this bit. */
5024 temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1);
5025 temp = gen_lowpart (rmode, temp);
5026 temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5027 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5030 return temp;
5033 /* Expand fork or exec calls. TARGET is the desired target of the
5034 call. EXP is the call. FN is the
5035 identificator of the actual function. IGNORE is nonzero if the
5036 value is to be ignored. */
5038 static rtx
5039 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5041 tree id, decl;
5042 tree call;
5044 /* If we are not profiling, just call the function. */
5045 if (!profile_arc_flag)
5046 return NULL_RTX;
5048 /* Otherwise call the wrapper. This should be equivalent for the rest of
5049 compiler, so the code does not diverge, and the wrapper may run the
5050 code necessary for keeping the profiling sane. */
5052 switch (DECL_FUNCTION_CODE (fn))
5054 case BUILT_IN_FORK:
5055 id = get_identifier ("__gcov_fork");
5056 break;
5058 case BUILT_IN_EXECL:
5059 id = get_identifier ("__gcov_execl");
5060 break;
5062 case BUILT_IN_EXECV:
5063 id = get_identifier ("__gcov_execv");
5064 break;
5066 case BUILT_IN_EXECLP:
5067 id = get_identifier ("__gcov_execlp");
5068 break;
5070 case BUILT_IN_EXECLE:
5071 id = get_identifier ("__gcov_execle");
5072 break;
5074 case BUILT_IN_EXECVP:
5075 id = get_identifier ("__gcov_execvp");
5076 break;
5078 case BUILT_IN_EXECVE:
5079 id = get_identifier ("__gcov_execve");
5080 break;
5082 default:
5083 gcc_unreachable ();
5086 decl = build_decl (DECL_SOURCE_LOCATION (fn),
5087 FUNCTION_DECL, id, TREE_TYPE (fn));
5088 DECL_EXTERNAL (decl) = 1;
5089 TREE_PUBLIC (decl) = 1;
5090 DECL_ARTIFICIAL (decl) = 1;
5091 TREE_NOTHROW (decl) = 1;
5092 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5093 DECL_VISIBILITY_SPECIFIED (decl) = 1;
5094 call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5095 return expand_call (call, target, ignore);
5100 /* Reconstitute a mode for a __sync intrinsic operation. Since the type of
5101 the pointer in these functions is void*, the tree optimizers may remove
5102 casts. The mode computed in expand_builtin isn't reliable either, due
5103 to __sync_bool_compare_and_swap.
5105 FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5106 group of builtins. This gives us log2 of the mode size. */
5108 static inline enum machine_mode
5109 get_builtin_sync_mode (int fcode_diff)
5111 /* The size is not negotiable, so ask not to get BLKmode in return
5112 if the target indicates that a smaller size would be better. */
5113 return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5116 /* Expand the memory expression LOC and return the appropriate memory operand
5117 for the builtin_sync operations. */
5119 static rtx
5120 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5122 rtx addr, mem;
5124 addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5125 addr = convert_memory_address (Pmode, addr);
5127 /* Note that we explicitly do not want any alias information for this
5128 memory, so that we kill all other live memories. Otherwise we don't
5129 satisfy the full barrier semantics of the intrinsic. */
5130 mem = validize_mem (gen_rtx_MEM (mode, addr));
5132 /* The alignment needs to be at least according to that of the mode. */
5133 set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
5134 get_pointer_alignment (loc)));
5135 set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5136 MEM_VOLATILE_P (mem) = 1;
5138 return mem;
5141 /* Make sure an argument is in the right mode.
5142 EXP is the tree argument.
5143 MODE is the mode it should be in. */
5145 static rtx
5146 expand_expr_force_mode (tree exp, enum machine_mode mode)
5148 rtx val;
5149 enum machine_mode old_mode;
5151 val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
5152 /* If VAL is promoted to a wider mode, convert it back to MODE. Take care
5153 of CONST_INTs, where we know the old_mode only from the call argument. */
5155 old_mode = GET_MODE (val);
5156 if (old_mode == VOIDmode)
5157 old_mode = TYPE_MODE (TREE_TYPE (exp));
5158 val = convert_modes (mode, old_mode, val, 1);
5159 return val;
5163 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5164 EXP is the CALL_EXPR. CODE is the rtx code
5165 that corresponds to the arithmetic or logical operation from the name;
5166 an exception here is that NOT actually means NAND. TARGET is an optional
5167 place for us to store the results; AFTER is true if this is the
5168 fetch_and_xxx form. */
5170 static rtx
5171 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5172 enum rtx_code code, bool after,
5173 rtx target)
5175 rtx val, mem;
5176 location_t loc = EXPR_LOCATION (exp);
5178 if (code == NOT && warn_sync_nand)
5180 tree fndecl = get_callee_fndecl (exp);
5181 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5183 static bool warned_f_a_n, warned_n_a_f;
5185 switch (fcode)
5187 case BUILT_IN_SYNC_FETCH_AND_NAND_1:
5188 case BUILT_IN_SYNC_FETCH_AND_NAND_2:
5189 case BUILT_IN_SYNC_FETCH_AND_NAND_4:
5190 case BUILT_IN_SYNC_FETCH_AND_NAND_8:
5191 case BUILT_IN_SYNC_FETCH_AND_NAND_16:
5192 if (warned_f_a_n)
5193 break;
5195 fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N);
5196 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5197 warned_f_a_n = true;
5198 break;
5200 case BUILT_IN_SYNC_NAND_AND_FETCH_1:
5201 case BUILT_IN_SYNC_NAND_AND_FETCH_2:
5202 case BUILT_IN_SYNC_NAND_AND_FETCH_4:
5203 case BUILT_IN_SYNC_NAND_AND_FETCH_8:
5204 case BUILT_IN_SYNC_NAND_AND_FETCH_16:
5205 if (warned_n_a_f)
5206 break;
5208 fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N);
5209 inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5210 warned_n_a_f = true;
5211 break;
5213 default:
5214 gcc_unreachable ();
5218 /* Expand the operands. */
5219 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5220 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5222 return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SEQ_CST,
5223 after);
5226 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5227 intrinsics. EXP is the CALL_EXPR. IS_BOOL is
5228 true if this is the boolean form. TARGET is a place for us to store the
5229 results; this is NOT optional if IS_BOOL is true. */
5231 static rtx
5232 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5233 bool is_bool, rtx target)
5235 rtx old_val, new_val, mem;
5236 rtx *pbool, *poval;
5238 /* Expand the operands. */
5239 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5240 old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5241 new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5243 pbool = poval = NULL;
5244 if (target != const0_rtx)
5246 if (is_bool)
5247 pbool = &target;
5248 else
5249 poval = &target;
5251 if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val,
5252 false, MEMMODEL_SEQ_CST,
5253 MEMMODEL_SEQ_CST))
5254 return NULL_RTX;
5256 return target;
5259 /* Expand the __sync_lock_test_and_set intrinsic. Note that the most
5260 general form is actually an atomic exchange, and some targets only
5261 support a reduced form with the second argument being a constant 1.
5262 EXP is the CALL_EXPR; TARGET is an optional place for us to store
5263 the results. */
5265 static rtx
5266 expand_builtin_sync_lock_test_and_set (enum machine_mode mode, tree exp,
5267 rtx target)
5269 rtx val, mem;
5271 /* Expand the operands. */
5272 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5273 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5275 return expand_sync_lock_test_and_set (target, mem, val);
5278 /* Expand the __sync_lock_release intrinsic. EXP is the CALL_EXPR. */
5280 static void
5281 expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
5283 rtx mem;
5285 /* Expand the operands. */
5286 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5288 expand_atomic_store (mem, const0_rtx, MEMMODEL_RELEASE, true);
5291 /* Given an integer representing an ``enum memmodel'', verify its
5292 correctness and return the memory model enum. */
5294 static enum memmodel
5295 get_memmodel (tree exp)
5297 rtx op;
5298 unsigned HOST_WIDE_INT val;
5300 /* If the parameter is not a constant, it's a run time value so we'll just
5301 convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking. */
5302 if (TREE_CODE (exp) != INTEGER_CST)
5303 return MEMMODEL_SEQ_CST;
5305 op = expand_normal (exp);
5307 val = INTVAL (op);
5308 if (targetm.memmodel_check)
5309 val = targetm.memmodel_check (val);
5310 else if (val & ~MEMMODEL_MASK)
5312 warning (OPT_Winvalid_memory_model,
5313 "Unknown architecture specifier in memory model to builtin.");
5314 return MEMMODEL_SEQ_CST;
5317 if ((INTVAL(op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
5319 warning (OPT_Winvalid_memory_model,
5320 "invalid memory model argument to builtin");
5321 return MEMMODEL_SEQ_CST;
5324 return (enum memmodel) val;
5327 /* Expand the __atomic_exchange intrinsic:
5328 TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel)
5329 EXP is the CALL_EXPR.
5330 TARGET is an optional place for us to store the results. */
5332 static rtx
5333 expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
5335 rtx val, mem;
5336 enum memmodel model;
5338 model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5339 if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME)
5341 error ("invalid memory model for %<__atomic_exchange%>");
5342 return NULL_RTX;
5345 if (!flag_inline_atomics)
5346 return NULL_RTX;
5348 /* Expand the operands. */
5349 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5350 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5352 return expand_atomic_exchange (target, mem, val, model);
5355 /* Expand the __atomic_compare_exchange intrinsic:
5356 bool __atomic_compare_exchange (TYPE *object, TYPE *expect,
5357 TYPE desired, BOOL weak,
5358 enum memmodel success,
5359 enum memmodel failure)
5360 EXP is the CALL_EXPR.
5361 TARGET is an optional place for us to store the results. */
5363 static rtx
5364 expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp,
5365 rtx target)
5367 rtx expect, desired, mem, oldval;
5368 enum memmodel success, failure;
5369 tree weak;
5370 bool is_weak;
5372 success = get_memmodel (CALL_EXPR_ARG (exp, 4));
5373 failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
5375 if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
5376 || (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5378 error ("invalid failure memory model for %<__atomic_compare_exchange%>");
5379 return NULL_RTX;
5382 if (failure > success)
5384 error ("failure memory model cannot be stronger than success "
5385 "memory model for %<__atomic_compare_exchange%>");
5386 return NULL_RTX;
5389 if (!flag_inline_atomics)
5390 return NULL_RTX;
5392 /* Expand the operands. */
5393 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5395 expect = expand_normal (CALL_EXPR_ARG (exp, 1));
5396 expect = convert_memory_address (Pmode, expect);
5397 desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5399 weak = CALL_EXPR_ARG (exp, 3);
5400 is_weak = false;
5401 if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
5402 is_weak = true;
5404 oldval = copy_to_reg (gen_rtx_MEM (mode, expect));
5406 if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
5407 &oldval, mem, oldval, desired,
5408 is_weak, success, failure))
5409 return NULL_RTX;
5411 emit_move_insn (gen_rtx_MEM (mode, expect), oldval);
5412 return target;
5415 /* Expand the __atomic_load intrinsic:
5416 TYPE __atomic_load (TYPE *object, enum memmodel)
5417 EXP is the CALL_EXPR.
5418 TARGET is an optional place for us to store the results. */
5420 static rtx
5421 expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
5423 rtx mem;
5424 enum memmodel model;
5426 model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5427 if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
5428 || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5430 error ("invalid memory model for %<__atomic_load%>");
5431 return NULL_RTX;
5434 if (!flag_inline_atomics)
5435 return NULL_RTX;
5437 /* Expand the operand. */
5438 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5440 return expand_atomic_load (target, mem, model);
5444 /* Expand the __atomic_store intrinsic:
5445 void __atomic_store (TYPE *object, TYPE desired, enum memmodel)
5446 EXP is the CALL_EXPR.
5447 TARGET is an optional place for us to store the results. */
5449 static rtx
5450 expand_builtin_atomic_store (enum machine_mode mode, tree exp)
5452 rtx mem, val;
5453 enum memmodel model;
5455 model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5456 if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED
5457 && (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
5458 && (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
5460 error ("invalid memory model for %<__atomic_store%>");
5461 return NULL_RTX;
5464 if (!flag_inline_atomics)
5465 return NULL_RTX;
5467 /* Expand the operands. */
5468 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5469 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5471 return expand_atomic_store (mem, val, model, false);
5474 /* Expand the __atomic_fetch_XXX intrinsic:
5475 TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
5476 EXP is the CALL_EXPR.
5477 TARGET is an optional place for us to store the results.
5478 CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR.
5479 FETCH_AFTER is true if returning the result of the operation.
5480 FETCH_AFTER is false if returning the value before the operation.
5481 IGNORE is true if the result is not used.
5482 EXT_CALL is the correct builtin for an external call if this cannot be
5483 resolved to an instruction sequence. */
5485 static rtx
5486 expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
5487 enum rtx_code code, bool fetch_after,
5488 bool ignore, enum built_in_function ext_call)
5490 rtx val, mem, ret;
5491 enum memmodel model;
5492 tree fndecl;
5493 tree addr;
5495 model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5497 /* Expand the operands. */
5498 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5499 val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5501 /* Only try generating instructions if inlining is turned on. */
5502 if (flag_inline_atomics)
5504 ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after);
5505 if (ret)
5506 return ret;
5509 /* Return if a different routine isn't needed for the library call. */
5510 if (ext_call == BUILT_IN_NONE)
5511 return NULL_RTX;
5513 /* Change the call to the specified function. */
5514 fndecl = get_callee_fndecl (exp);
5515 addr = CALL_EXPR_FN (exp);
5516 STRIP_NOPS (addr);
5518 gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
5519 TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
5521 /* Expand the call here so we can emit trailing code. */
5522 ret = expand_call (exp, target, ignore);
5524 /* Replace the original function just in case it matters. */
5525 TREE_OPERAND (addr, 0) = fndecl;
5527 /* Then issue the arithmetic correction to return the right result. */
5528 if (!ignore)
5530 if (code == NOT)
5532 ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
5533 OPTAB_LIB_WIDEN);
5534 ret = expand_simple_unop (mode, NOT, ret, target, true);
5536 else
5537 ret = expand_simple_binop (mode, code, ret, val, target, true,
5538 OPTAB_LIB_WIDEN);
5540 return ret;
5544 #ifndef HAVE_atomic_clear
5545 # define HAVE_atomic_clear 0
5546 # define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX)
5547 #endif
5549 /* Expand an atomic clear operation.
5550 void _atomic_clear (BOOL *obj, enum memmodel)
5551 EXP is the call expression. */
5553 static rtx
5554 expand_builtin_atomic_clear (tree exp)
5556 enum machine_mode mode;
5557 rtx mem, ret;
5558 enum memmodel model;
5560 mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5561 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5562 model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5564 if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
5565 || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5567 error ("invalid memory model for %<__atomic_store%>");
5568 return const0_rtx;
5571 if (HAVE_atomic_clear)
5573 emit_insn (gen_atomic_clear (mem, model));
5574 return const0_rtx;
5577 /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release.
5578 Failing that, a store is issued by __atomic_store. The only way this can
5579 fail is if the bool type is larger than a word size. Unlikely, but
5580 handle it anyway for completeness. Assume a single threaded model since
5581 there is no atomic support in this case, and no barriers are required. */
5582 ret = expand_atomic_store (mem, const0_rtx, model, true);
5583 if (!ret)
5584 emit_move_insn (mem, const0_rtx);
5585 return const0_rtx;
5588 /* Expand an atomic test_and_set operation.
5589 bool _atomic_test_and_set (BOOL *obj, enum memmodel)
5590 EXP is the call expression. */
5592 static rtx
5593 expand_builtin_atomic_test_and_set (tree exp, rtx target)
5595 rtx mem;
5596 enum memmodel model;
5597 enum machine_mode mode;
5599 mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5600 mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5601 model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5603 return expand_atomic_test_and_set (target, mem, model);
5607 /* Return true if (optional) argument ARG1 of size ARG0 is always lock free on
5608 this architecture. If ARG1 is NULL, use typical alignment for size ARG0. */
5610 static tree
5611 fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
5613 int size;
5614 enum machine_mode mode;
5615 unsigned int mode_align, type_align;
5617 if (TREE_CODE (arg0) != INTEGER_CST)
5618 return NULL_TREE;
5620 size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT;
5621 mode = mode_for_size (size, MODE_INT, 0);
5622 mode_align = GET_MODE_ALIGNMENT (mode);
5624 if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
5625 type_align = mode_align;
5626 else
5628 tree ttype = TREE_TYPE (arg1);
5630 /* This function is usually invoked and folded immediately by the front
5631 end before anything else has a chance to look at it. The pointer
5632 parameter at this point is usually cast to a void *, so check for that
5633 and look past the cast. */
5634 if (TREE_CODE (arg1) == NOP_EXPR && POINTER_TYPE_P (ttype)
5635 && VOID_TYPE_P (TREE_TYPE (ttype)))
5636 arg1 = TREE_OPERAND (arg1, 0);
5638 ttype = TREE_TYPE (arg1);
5639 gcc_assert (POINTER_TYPE_P (ttype));
5641 /* Get the underlying type of the object. */
5642 ttype = TREE_TYPE (ttype);
5643 type_align = TYPE_ALIGN (ttype);
5646 /* If the object has smaller alignment, the the lock free routines cannot
5647 be used. */
5648 if (type_align < mode_align)
5649 return boolean_false_node;
5651 /* Check if a compare_and_swap pattern exists for the mode which represents
5652 the required size. The pattern is not allowed to fail, so the existence
5653 of the pattern indicates support is present. */
5654 if (can_compare_and_swap_p (mode, true))
5655 return boolean_true_node;
5656 else
5657 return boolean_false_node;
5660 /* Return true if the parameters to call EXP represent an object which will
5661 always generate lock free instructions. The first argument represents the
5662 size of the object, and the second parameter is a pointer to the object
5663 itself. If NULL is passed for the object, then the result is based on
5664 typical alignment for an object of the specified size. Otherwise return
5665 false. */
5667 static rtx
5668 expand_builtin_atomic_always_lock_free (tree exp)
5670 tree size;
5671 tree arg0 = CALL_EXPR_ARG (exp, 0);
5672 tree arg1 = CALL_EXPR_ARG (exp, 1);
5674 if (TREE_CODE (arg0) != INTEGER_CST)
5676 error ("non-constant argument 1 to __atomic_always_lock_free");
5677 return const0_rtx;
5680 size = fold_builtin_atomic_always_lock_free (arg0, arg1);
5681 if (size == boolean_true_node)
5682 return const1_rtx;
5683 return const0_rtx;
5686 /* Return a one or zero if it can be determined that object ARG1 of size ARG
5687 is lock free on this architecture. */
5689 static tree
5690 fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
5692 if (!flag_inline_atomics)
5693 return NULL_TREE;
5695 /* If it isn't always lock free, don't generate a result. */
5696 if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node)
5697 return boolean_true_node;
5699 return NULL_TREE;
5702 /* Return true if the parameters to call EXP represent an object which will
5703 always generate lock free instructions. The first argument represents the
5704 size of the object, and the second parameter is a pointer to the object
5705 itself. If NULL is passed for the object, then the result is based on
5706 typical alignment for an object of the specified size. Otherwise return
5707 NULL*/
5709 static rtx
5710 expand_builtin_atomic_is_lock_free (tree exp)
5712 tree size;
5713 tree arg0 = CALL_EXPR_ARG (exp, 0);
5714 tree arg1 = CALL_EXPR_ARG (exp, 1);
5716 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
5718 error ("non-integer argument 1 to __atomic_is_lock_free");
5719 return NULL_RTX;
5722 if (!flag_inline_atomics)
5723 return NULL_RTX;
5725 /* If the value is known at compile time, return the RTX for it. */
5726 size = fold_builtin_atomic_is_lock_free (arg0, arg1);
5727 if (size == boolean_true_node)
5728 return const1_rtx;
5730 return NULL_RTX;
5733 /* Expand the __atomic_thread_fence intrinsic:
5734 void __atomic_thread_fence (enum memmodel)
5735 EXP is the CALL_EXPR. */
5737 static void
5738 expand_builtin_atomic_thread_fence (tree exp)
5740 enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5741 expand_mem_thread_fence (model);
5744 /* Expand the __atomic_signal_fence intrinsic:
5745 void __atomic_signal_fence (enum memmodel)
5746 EXP is the CALL_EXPR. */
5748 static void
5749 expand_builtin_atomic_signal_fence (tree exp)
5751 enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5752 expand_mem_signal_fence (model);
5755 /* Expand the __sync_synchronize intrinsic. */
5757 static void
5758 expand_builtin_sync_synchronize (void)
5760 expand_mem_thread_fence (MEMMODEL_SEQ_CST);
5764 /* Expand an expression EXP that calls a built-in function,
5765 with result going to TARGET if that's convenient
5766 (and in mode MODE if that's convenient).
5767 SUBTARGET may be used as the target for computing one of EXP's operands.
5768 IGNORE is nonzero if the value is to be ignored. */
5771 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5772 int ignore)
5774 tree fndecl = get_callee_fndecl (exp);
5775 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5776 enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5777 int flags;
5779 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5780 return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5782 /* When not optimizing, generate calls to library functions for a certain
5783 set of builtins. */
5784 if (!optimize
5785 && !called_as_built_in (fndecl)
5786 && fcode != BUILT_IN_ALLOCA
5787 && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
5788 && fcode != BUILT_IN_FREE)
5789 return expand_call (exp, target, ignore);
5791 /* The built-in function expanders test for target == const0_rtx
5792 to determine whether the function's result will be ignored. */
5793 if (ignore)
5794 target = const0_rtx;
5796 /* If the result of a pure or const built-in function is ignored, and
5797 none of its arguments are volatile, we can avoid expanding the
5798 built-in call and just evaluate the arguments for side-effects. */
5799 if (target == const0_rtx
5800 && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
5801 && !(flags & ECF_LOOPING_CONST_OR_PURE))
5803 bool volatilep = false;
5804 tree arg;
5805 call_expr_arg_iterator iter;
5807 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5808 if (TREE_THIS_VOLATILE (arg))
5810 volatilep = true;
5811 break;
5814 if (! volatilep)
5816 FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5817 expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5818 return const0_rtx;
5822 switch (fcode)
5824 CASE_FLT_FN (BUILT_IN_FABS):
5825 target = expand_builtin_fabs (exp, target, subtarget);
5826 if (target)
5827 return target;
5828 break;
5830 CASE_FLT_FN (BUILT_IN_COPYSIGN):
5831 target = expand_builtin_copysign (exp, target, subtarget);
5832 if (target)
5833 return target;
5834 break;
5836 /* Just do a normal library call if we were unable to fold
5837 the values. */
5838 CASE_FLT_FN (BUILT_IN_CABS):
5839 break;
5841 CASE_FLT_FN (BUILT_IN_EXP):
5842 CASE_FLT_FN (BUILT_IN_EXP10):
5843 CASE_FLT_FN (BUILT_IN_POW10):
5844 CASE_FLT_FN (BUILT_IN_EXP2):
5845 CASE_FLT_FN (BUILT_IN_EXPM1):
5846 CASE_FLT_FN (BUILT_IN_LOGB):
5847 CASE_FLT_FN (BUILT_IN_LOG):
5848 CASE_FLT_FN (BUILT_IN_LOG10):
5849 CASE_FLT_FN (BUILT_IN_LOG2):
5850 CASE_FLT_FN (BUILT_IN_LOG1P):
5851 CASE_FLT_FN (BUILT_IN_TAN):
5852 CASE_FLT_FN (BUILT_IN_ASIN):
5853 CASE_FLT_FN (BUILT_IN_ACOS):
5854 CASE_FLT_FN (BUILT_IN_ATAN):
5855 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5856 /* Treat these like sqrt only if unsafe math optimizations are allowed,
5857 because of possible accuracy problems. */
5858 if (! flag_unsafe_math_optimizations)
5859 break;
5860 CASE_FLT_FN (BUILT_IN_SQRT):
5861 CASE_FLT_FN (BUILT_IN_FLOOR):
5862 CASE_FLT_FN (BUILT_IN_CEIL):
5863 CASE_FLT_FN (BUILT_IN_TRUNC):
5864 CASE_FLT_FN (BUILT_IN_ROUND):
5865 CASE_FLT_FN (BUILT_IN_NEARBYINT):
5866 CASE_FLT_FN (BUILT_IN_RINT):
5867 target = expand_builtin_mathfn (exp, target, subtarget);
5868 if (target)
5869 return target;
5870 break;
5872 CASE_FLT_FN (BUILT_IN_FMA):
5873 target = expand_builtin_mathfn_ternary (exp, target, subtarget);
5874 if (target)
5875 return target;
5876 break;
5878 CASE_FLT_FN (BUILT_IN_ILOGB):
5879 if (! flag_unsafe_math_optimizations)
5880 break;
5881 CASE_FLT_FN (BUILT_IN_ISINF):
5882 CASE_FLT_FN (BUILT_IN_FINITE):
5883 case BUILT_IN_ISFINITE:
5884 case BUILT_IN_ISNORMAL:
5885 target = expand_builtin_interclass_mathfn (exp, target);
5886 if (target)
5887 return target;
5888 break;
5890 CASE_FLT_FN (BUILT_IN_ICEIL):
5891 CASE_FLT_FN (BUILT_IN_LCEIL):
5892 CASE_FLT_FN (BUILT_IN_LLCEIL):
5893 CASE_FLT_FN (BUILT_IN_LFLOOR):
5894 CASE_FLT_FN (BUILT_IN_IFLOOR):
5895 CASE_FLT_FN (BUILT_IN_LLFLOOR):
5896 target = expand_builtin_int_roundingfn (exp, target);
5897 if (target)
5898 return target;
5899 break;
5901 CASE_FLT_FN (BUILT_IN_IRINT):
5902 CASE_FLT_FN (BUILT_IN_LRINT):
5903 CASE_FLT_FN (BUILT_IN_LLRINT):
5904 CASE_FLT_FN (BUILT_IN_IROUND):
5905 CASE_FLT_FN (BUILT_IN_LROUND):
5906 CASE_FLT_FN (BUILT_IN_LLROUND):
5907 target = expand_builtin_int_roundingfn_2 (exp, target);
5908 if (target)
5909 return target;
5910 break;
5912 CASE_FLT_FN (BUILT_IN_POWI):
5913 target = expand_builtin_powi (exp, target);
5914 if (target)
5915 return target;
5916 break;
5918 CASE_FLT_FN (BUILT_IN_ATAN2):
5919 CASE_FLT_FN (BUILT_IN_LDEXP):
5920 CASE_FLT_FN (BUILT_IN_SCALB):
5921 CASE_FLT_FN (BUILT_IN_SCALBN):
5922 CASE_FLT_FN (BUILT_IN_SCALBLN):
5923 if (! flag_unsafe_math_optimizations)
5924 break;
5926 CASE_FLT_FN (BUILT_IN_FMOD):
5927 CASE_FLT_FN (BUILT_IN_REMAINDER):
5928 CASE_FLT_FN (BUILT_IN_DREM):
5929 CASE_FLT_FN (BUILT_IN_POW):
5930 target = expand_builtin_mathfn_2 (exp, target, subtarget);
5931 if (target)
5932 return target;
5933 break;
5935 CASE_FLT_FN (BUILT_IN_CEXPI):
5936 target = expand_builtin_cexpi (exp, target);
5937 gcc_assert (target);
5938 return target;
5940 CASE_FLT_FN (BUILT_IN_SIN):
5941 CASE_FLT_FN (BUILT_IN_COS):
5942 if (! flag_unsafe_math_optimizations)
5943 break;
5944 target = expand_builtin_mathfn_3 (exp, target, subtarget);
5945 if (target)
5946 return target;
5947 break;
5949 CASE_FLT_FN (BUILT_IN_SINCOS):
5950 if (! flag_unsafe_math_optimizations)
5951 break;
5952 target = expand_builtin_sincos (exp);
5953 if (target)
5954 return target;
5955 break;
5957 case BUILT_IN_APPLY_ARGS:
5958 return expand_builtin_apply_args ();
5960 /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5961 FUNCTION with a copy of the parameters described by
5962 ARGUMENTS, and ARGSIZE. It returns a block of memory
5963 allocated on the stack into which is stored all the registers
5964 that might possibly be used for returning the result of a
5965 function. ARGUMENTS is the value returned by
5966 __builtin_apply_args. ARGSIZE is the number of bytes of
5967 arguments that must be copied. ??? How should this value be
5968 computed? We'll also need a safe worst case value for varargs
5969 functions. */
5970 case BUILT_IN_APPLY:
5971 if (!validate_arglist (exp, POINTER_TYPE,
5972 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5973 && !validate_arglist (exp, REFERENCE_TYPE,
5974 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5975 return const0_rtx;
5976 else
5978 rtx ops[3];
5980 ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
5981 ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
5982 ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
5984 return expand_builtin_apply (ops[0], ops[1], ops[2]);
5987 /* __builtin_return (RESULT) causes the function to return the
5988 value described by RESULT. RESULT is address of the block of
5989 memory returned by __builtin_apply. */
5990 case BUILT_IN_RETURN:
5991 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5992 expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
5993 return const0_rtx;
5995 case BUILT_IN_SAVEREGS:
5996 return expand_builtin_saveregs ();
5998 case BUILT_IN_VA_ARG_PACK:
5999 /* All valid uses of __builtin_va_arg_pack () are removed during
6000 inlining. */
6001 error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6002 return const0_rtx;
6004 case BUILT_IN_VA_ARG_PACK_LEN:
6005 /* All valid uses of __builtin_va_arg_pack_len () are removed during
6006 inlining. */
6007 error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6008 return const0_rtx;
6010 /* Return the address of the first anonymous stack arg. */
6011 case BUILT_IN_NEXT_ARG:
6012 if (fold_builtin_next_arg (exp, false))
6013 return const0_rtx;
6014 return expand_builtin_next_arg ();
6016 case BUILT_IN_CLEAR_CACHE:
6017 target = expand_builtin___clear_cache (exp);
6018 if (target)
6019 return target;
6020 break;
6022 case BUILT_IN_CLASSIFY_TYPE:
6023 return expand_builtin_classify_type (exp);
6025 case BUILT_IN_CONSTANT_P:
6026 return const0_rtx;
6028 case BUILT_IN_FRAME_ADDRESS:
6029 case BUILT_IN_RETURN_ADDRESS:
6030 return expand_builtin_frame_address (fndecl, exp);
6032 /* Returns the address of the area where the structure is returned.
6033 0 otherwise. */
6034 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6035 if (call_expr_nargs (exp) != 0
6036 || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6037 || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6038 return const0_rtx;
6039 else
6040 return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6042 case BUILT_IN_ALLOCA:
6043 case BUILT_IN_ALLOCA_WITH_ALIGN:
6044 /* If the allocation stems from the declaration of a variable-sized
6045 object, it cannot accumulate. */
6046 target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp));
6047 if (target)
6048 return target;
6049 break;
6051 case BUILT_IN_STACK_SAVE:
6052 return expand_stack_save ();
6054 case BUILT_IN_STACK_RESTORE:
6055 expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6056 return const0_rtx;
6058 case BUILT_IN_BSWAP16:
6059 case BUILT_IN_BSWAP32:
6060 case BUILT_IN_BSWAP64:
6061 target = expand_builtin_bswap (target_mode, exp, target, subtarget);
6062 if (target)
6063 return target;
6064 break;
6066 CASE_INT_FN (BUILT_IN_FFS):
6067 case BUILT_IN_FFSIMAX:
6068 target = expand_builtin_unop (target_mode, exp, target,
6069 subtarget, ffs_optab);
6070 if (target)
6071 return target;
6072 break;
6074 CASE_INT_FN (BUILT_IN_CLZ):
6075 case BUILT_IN_CLZIMAX:
6076 target = expand_builtin_unop (target_mode, exp, target,
6077 subtarget, clz_optab);
6078 if (target)
6079 return target;
6080 break;
6082 CASE_INT_FN (BUILT_IN_CTZ):
6083 case BUILT_IN_CTZIMAX:
6084 target = expand_builtin_unop (target_mode, exp, target,
6085 subtarget, ctz_optab);
6086 if (target)
6087 return target;
6088 break;
6090 CASE_INT_FN (BUILT_IN_CLRSB):
6091 case BUILT_IN_CLRSBIMAX:
6092 target = expand_builtin_unop (target_mode, exp, target,
6093 subtarget, clrsb_optab);
6094 if (target)
6095 return target;
6096 break;
6098 CASE_INT_FN (BUILT_IN_POPCOUNT):
6099 case BUILT_IN_POPCOUNTIMAX:
6100 target = expand_builtin_unop (target_mode, exp, target,
6101 subtarget, popcount_optab);
6102 if (target)
6103 return target;
6104 break;
6106 CASE_INT_FN (BUILT_IN_PARITY):
6107 case BUILT_IN_PARITYIMAX:
6108 target = expand_builtin_unop (target_mode, exp, target,
6109 subtarget, parity_optab);
6110 if (target)
6111 return target;
6112 break;
6114 case BUILT_IN_STRLEN:
6115 target = expand_builtin_strlen (exp, target, target_mode);
6116 if (target)
6117 return target;
6118 break;
6120 case BUILT_IN_STRCPY:
6121 target = expand_builtin_strcpy (exp, target);
6122 if (target)
6123 return target;
6124 break;
6126 case BUILT_IN_STRNCPY:
6127 target = expand_builtin_strncpy (exp, target);
6128 if (target)
6129 return target;
6130 break;
6132 case BUILT_IN_STPCPY:
6133 target = expand_builtin_stpcpy (exp, target, mode);
6134 if (target)
6135 return target;
6136 break;
6138 case BUILT_IN_MEMCPY:
6139 target = expand_builtin_memcpy (exp, target);
6140 if (target)
6141 return target;
6142 break;
6144 case BUILT_IN_MEMPCPY:
6145 target = expand_builtin_mempcpy (exp, target, mode);
6146 if (target)
6147 return target;
6148 break;
6150 case BUILT_IN_MEMSET:
6151 target = expand_builtin_memset (exp, target, mode);
6152 if (target)
6153 return target;
6154 break;
6156 case BUILT_IN_BZERO:
6157 target = expand_builtin_bzero (exp);
6158 if (target)
6159 return target;
6160 break;
6162 case BUILT_IN_STRCMP:
6163 target = expand_builtin_strcmp (exp, target);
6164 if (target)
6165 return target;
6166 break;
6168 case BUILT_IN_STRNCMP:
6169 target = expand_builtin_strncmp (exp, target, mode);
6170 if (target)
6171 return target;
6172 break;
6174 case BUILT_IN_BCMP:
6175 case BUILT_IN_MEMCMP:
6176 target = expand_builtin_memcmp (exp, target, mode);
6177 if (target)
6178 return target;
6179 break;
6181 case BUILT_IN_SETJMP:
6182 /* This should have been lowered to the builtins below. */
6183 gcc_unreachable ();
6185 case BUILT_IN_SETJMP_SETUP:
6186 /* __builtin_setjmp_setup is passed a pointer to an array of five words
6187 and the receiver label. */
6188 if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6190 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6191 VOIDmode, EXPAND_NORMAL);
6192 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6193 rtx label_r = label_rtx (label);
6195 /* This is copied from the handling of non-local gotos. */
6196 expand_builtin_setjmp_setup (buf_addr, label_r);
6197 nonlocal_goto_handler_labels
6198 = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6199 nonlocal_goto_handler_labels);
6200 /* ??? Do not let expand_label treat us as such since we would
6201 not want to be both on the list of non-local labels and on
6202 the list of forced labels. */
6203 FORCED_LABEL (label) = 0;
6204 return const0_rtx;
6206 break;
6208 case BUILT_IN_SETJMP_DISPATCHER:
6209 /* __builtin_setjmp_dispatcher is passed the dispatcher label. */
6210 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6212 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6213 rtx label_r = label_rtx (label);
6215 /* Remove the dispatcher label from the list of non-local labels
6216 since the receiver labels have been added to it above. */
6217 remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6218 return const0_rtx;
6220 break;
6222 case BUILT_IN_SETJMP_RECEIVER:
6223 /* __builtin_setjmp_receiver is passed the receiver label. */
6224 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6226 tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6227 rtx label_r = label_rtx (label);
6229 expand_builtin_setjmp_receiver (label_r);
6230 return const0_rtx;
6232 break;
6234 /* __builtin_longjmp is passed a pointer to an array of five words.
6235 It's similar to the C library longjmp function but works with
6236 __builtin_setjmp above. */
6237 case BUILT_IN_LONGJMP:
6238 if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6240 rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6241 VOIDmode, EXPAND_NORMAL);
6242 rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6244 if (value != const1_rtx)
6246 error ("%<__builtin_longjmp%> second argument must be 1");
6247 return const0_rtx;
6250 expand_builtin_longjmp (buf_addr, value);
6251 return const0_rtx;
6253 break;
6255 case BUILT_IN_NONLOCAL_GOTO:
6256 target = expand_builtin_nonlocal_goto (exp);
6257 if (target)
6258 return target;
6259 break;
6261 /* This updates the setjmp buffer that is its argument with the value
6262 of the current stack pointer. */
6263 case BUILT_IN_UPDATE_SETJMP_BUF:
6264 if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6266 rtx buf_addr
6267 = expand_normal (CALL_EXPR_ARG (exp, 0));
6269 expand_builtin_update_setjmp_buf (buf_addr);
6270 return const0_rtx;
6272 break;
6274 case BUILT_IN_TRAP:
6275 expand_builtin_trap ();
6276 return const0_rtx;
6278 case BUILT_IN_UNREACHABLE:
6279 expand_builtin_unreachable ();
6280 return const0_rtx;
6282 CASE_FLT_FN (BUILT_IN_SIGNBIT):
6283 case BUILT_IN_SIGNBITD32:
6284 case BUILT_IN_SIGNBITD64:
6285 case BUILT_IN_SIGNBITD128:
6286 target = expand_builtin_signbit (exp, target);
6287 if (target)
6288 return target;
6289 break;
6291 /* Various hooks for the DWARF 2 __throw routine. */
6292 case BUILT_IN_UNWIND_INIT:
6293 expand_builtin_unwind_init ();
6294 return const0_rtx;
6295 case BUILT_IN_DWARF_CFA:
6296 return virtual_cfa_rtx;
6297 #ifdef DWARF2_UNWIND_INFO
6298 case BUILT_IN_DWARF_SP_COLUMN:
6299 return expand_builtin_dwarf_sp_column ();
6300 case BUILT_IN_INIT_DWARF_REG_SIZES:
6301 expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6302 return const0_rtx;
6303 #endif
6304 case BUILT_IN_FROB_RETURN_ADDR:
6305 return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6306 case BUILT_IN_EXTRACT_RETURN_ADDR:
6307 return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6308 case BUILT_IN_EH_RETURN:
6309 expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6310 CALL_EXPR_ARG (exp, 1));
6311 return const0_rtx;
6312 #ifdef EH_RETURN_DATA_REGNO
6313 case BUILT_IN_EH_RETURN_DATA_REGNO:
6314 return expand_builtin_eh_return_data_regno (exp);
6315 #endif
6316 case BUILT_IN_EXTEND_POINTER:
6317 return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6318 case BUILT_IN_EH_POINTER:
6319 return expand_builtin_eh_pointer (exp);
6320 case BUILT_IN_EH_FILTER:
6321 return expand_builtin_eh_filter (exp);
6322 case BUILT_IN_EH_COPY_VALUES:
6323 return expand_builtin_eh_copy_values (exp);
6325 case BUILT_IN_VA_START:
6326 return expand_builtin_va_start (exp);
6327 case BUILT_IN_VA_END:
6328 return expand_builtin_va_end (exp);
6329 case BUILT_IN_VA_COPY:
6330 return expand_builtin_va_copy (exp);
6331 case BUILT_IN_EXPECT:
6332 return expand_builtin_expect (exp, target);
6333 case BUILT_IN_ASSUME_ALIGNED:
6334 return expand_builtin_assume_aligned (exp, target);
6335 case BUILT_IN_PREFETCH:
6336 expand_builtin_prefetch (exp);
6337 return const0_rtx;
6339 case BUILT_IN_INIT_TRAMPOLINE:
6340 return expand_builtin_init_trampoline (exp, true);
6341 case BUILT_IN_INIT_HEAP_TRAMPOLINE:
6342 return expand_builtin_init_trampoline (exp, false);
6343 case BUILT_IN_ADJUST_TRAMPOLINE:
6344 return expand_builtin_adjust_trampoline (exp);
6346 case BUILT_IN_FORK:
6347 case BUILT_IN_EXECL:
6348 case BUILT_IN_EXECV:
6349 case BUILT_IN_EXECLP:
6350 case BUILT_IN_EXECLE:
6351 case BUILT_IN_EXECVP:
6352 case BUILT_IN_EXECVE:
6353 target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6354 if (target)
6355 return target;
6356 break;
6358 case BUILT_IN_SYNC_FETCH_AND_ADD_1:
6359 case BUILT_IN_SYNC_FETCH_AND_ADD_2:
6360 case BUILT_IN_SYNC_FETCH_AND_ADD_4:
6361 case BUILT_IN_SYNC_FETCH_AND_ADD_8:
6362 case BUILT_IN_SYNC_FETCH_AND_ADD_16:
6363 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1);
6364 target = expand_builtin_sync_operation (mode, exp, PLUS, false, target);
6365 if (target)
6366 return target;
6367 break;
6369 case BUILT_IN_SYNC_FETCH_AND_SUB_1:
6370 case BUILT_IN_SYNC_FETCH_AND_SUB_2:
6371 case BUILT_IN_SYNC_FETCH_AND_SUB_4:
6372 case BUILT_IN_SYNC_FETCH_AND_SUB_8:
6373 case BUILT_IN_SYNC_FETCH_AND_SUB_16:
6374 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1);
6375 target = expand_builtin_sync_operation (mode, exp, MINUS, false, target);
6376 if (target)
6377 return target;
6378 break;
6380 case BUILT_IN_SYNC_FETCH_AND_OR_1:
6381 case BUILT_IN_SYNC_FETCH_AND_OR_2:
6382 case BUILT_IN_SYNC_FETCH_AND_OR_4:
6383 case BUILT_IN_SYNC_FETCH_AND_OR_8:
6384 case BUILT_IN_SYNC_FETCH_AND_OR_16:
6385 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1);
6386 target = expand_builtin_sync_operation (mode, exp, IOR, false, target);
6387 if (target)
6388 return target;
6389 break;
6391 case BUILT_IN_SYNC_FETCH_AND_AND_1:
6392 case BUILT_IN_SYNC_FETCH_AND_AND_2:
6393 case BUILT_IN_SYNC_FETCH_AND_AND_4:
6394 case BUILT_IN_SYNC_FETCH_AND_AND_8:
6395 case BUILT_IN_SYNC_FETCH_AND_AND_16:
6396 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1);
6397 target = expand_builtin_sync_operation (mode, exp, AND, false, target);
6398 if (target)
6399 return target;
6400 break;
6402 case BUILT_IN_SYNC_FETCH_AND_XOR_1:
6403 case BUILT_IN_SYNC_FETCH_AND_XOR_2:
6404 case BUILT_IN_SYNC_FETCH_AND_XOR_4:
6405 case BUILT_IN_SYNC_FETCH_AND_XOR_8:
6406 case BUILT_IN_SYNC_FETCH_AND_XOR_16:
6407 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1);
6408 target = expand_builtin_sync_operation (mode, exp, XOR, false, target);
6409 if (target)
6410 return target;
6411 break;
6413 case BUILT_IN_SYNC_FETCH_AND_NAND_1:
6414 case BUILT_IN_SYNC_FETCH_AND_NAND_2:
6415 case BUILT_IN_SYNC_FETCH_AND_NAND_4:
6416 case BUILT_IN_SYNC_FETCH_AND_NAND_8:
6417 case BUILT_IN_SYNC_FETCH_AND_NAND_16:
6418 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1);
6419 target = expand_builtin_sync_operation (mode, exp, NOT, false, target);
6420 if (target)
6421 return target;
6422 break;
6424 case BUILT_IN_SYNC_ADD_AND_FETCH_1:
6425 case BUILT_IN_SYNC_ADD_AND_FETCH_2:
6426 case BUILT_IN_SYNC_ADD_AND_FETCH_4:
6427 case BUILT_IN_SYNC_ADD_AND_FETCH_8:
6428 case BUILT_IN_SYNC_ADD_AND_FETCH_16:
6429 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1);
6430 target = expand_builtin_sync_operation (mode, exp, PLUS, true, target);
6431 if (target)
6432 return target;
6433 break;
6435 case BUILT_IN_SYNC_SUB_AND_FETCH_1:
6436 case BUILT_IN_SYNC_SUB_AND_FETCH_2:
6437 case BUILT_IN_SYNC_SUB_AND_FETCH_4:
6438 case BUILT_IN_SYNC_SUB_AND_FETCH_8:
6439 case BUILT_IN_SYNC_SUB_AND_FETCH_16:
6440 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1);
6441 target = expand_builtin_sync_operation (mode, exp, MINUS, true, target);
6442 if (target)
6443 return target;
6444 break;
6446 case BUILT_IN_SYNC_OR_AND_FETCH_1:
6447 case BUILT_IN_SYNC_OR_AND_FETCH_2:
6448 case BUILT_IN_SYNC_OR_AND_FETCH_4:
6449 case BUILT_IN_SYNC_OR_AND_FETCH_8:
6450 case BUILT_IN_SYNC_OR_AND_FETCH_16:
6451 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1);
6452 target = expand_builtin_sync_operation (mode, exp, IOR, true, target);
6453 if (target)
6454 return target;
6455 break;
6457 case BUILT_IN_SYNC_AND_AND_FETCH_1:
6458 case BUILT_IN_SYNC_AND_AND_FETCH_2:
6459 case BUILT_IN_SYNC_AND_AND_FETCH_4:
6460 case BUILT_IN_SYNC_AND_AND_FETCH_8:
6461 case BUILT_IN_SYNC_AND_AND_FETCH_16:
6462 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1);
6463 target = expand_builtin_sync_operation (mode, exp, AND, true, target);
6464 if (target)
6465 return target;
6466 break;
6468 case BUILT_IN_SYNC_XOR_AND_FETCH_1:
6469 case BUILT_IN_SYNC_XOR_AND_FETCH_2:
6470 case BUILT_IN_SYNC_XOR_AND_FETCH_4:
6471 case BUILT_IN_SYNC_XOR_AND_FETCH_8:
6472 case BUILT_IN_SYNC_XOR_AND_FETCH_16:
6473 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1);
6474 target = expand_builtin_sync_operation (mode, exp, XOR, true, target);
6475 if (target)
6476 return target;
6477 break;
6479 case BUILT_IN_SYNC_NAND_AND_FETCH_1:
6480 case BUILT_IN_SYNC_NAND_AND_FETCH_2:
6481 case BUILT_IN_SYNC_NAND_AND_FETCH_4:
6482 case BUILT_IN_SYNC_NAND_AND_FETCH_8:
6483 case BUILT_IN_SYNC_NAND_AND_FETCH_16:
6484 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1);
6485 target = expand_builtin_sync_operation (mode, exp, NOT, true, target);
6486 if (target)
6487 return target;
6488 break;
6490 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
6491 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
6492 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
6493 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
6494 case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
6495 if (mode == VOIDmode)
6496 mode = TYPE_MODE (boolean_type_node);
6497 if (!target || !register_operand (target, mode))
6498 target = gen_reg_rtx (mode);
6500 mode = get_builtin_sync_mode
6501 (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1);
6502 target = expand_builtin_compare_and_swap (mode, exp, true, target);
6503 if (target)
6504 return target;
6505 break;
6507 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
6508 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
6509 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
6510 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
6511 case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
6512 mode = get_builtin_sync_mode
6513 (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1);
6514 target = expand_builtin_compare_and_swap (mode, exp, false, target);
6515 if (target)
6516 return target;
6517 break;
6519 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
6520 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
6521 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
6522 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
6523 case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
6524 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1);
6525 target = expand_builtin_sync_lock_test_and_set (mode, exp, target);
6526 if (target)
6527 return target;
6528 break;
6530 case BUILT_IN_SYNC_LOCK_RELEASE_1:
6531 case BUILT_IN_SYNC_LOCK_RELEASE_2:
6532 case BUILT_IN_SYNC_LOCK_RELEASE_4:
6533 case BUILT_IN_SYNC_LOCK_RELEASE_8:
6534 case BUILT_IN_SYNC_LOCK_RELEASE_16:
6535 mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1);
6536 expand_builtin_sync_lock_release (mode, exp);
6537 return const0_rtx;
6539 case BUILT_IN_SYNC_SYNCHRONIZE:
6540 expand_builtin_sync_synchronize ();
6541 return const0_rtx;
6543 case BUILT_IN_ATOMIC_EXCHANGE_1:
6544 case BUILT_IN_ATOMIC_EXCHANGE_2:
6545 case BUILT_IN_ATOMIC_EXCHANGE_4:
6546 case BUILT_IN_ATOMIC_EXCHANGE_8:
6547 case BUILT_IN_ATOMIC_EXCHANGE_16:
6548 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1);
6549 target = expand_builtin_atomic_exchange (mode, exp, target);
6550 if (target)
6551 return target;
6552 break;
6554 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
6555 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
6556 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
6557 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
6558 case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
6560 unsigned int nargs, z;
6561 VEC(tree,gc) *vec;
6563 mode =
6564 get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
6565 target = expand_builtin_atomic_compare_exchange (mode, exp, target);
6566 if (target)
6567 return target;
6569 /* If this is turned into an external library call, the weak parameter
6570 must be dropped to match the expected parameter list. */
6571 nargs = call_expr_nargs (exp);
6572 vec = VEC_alloc (tree, gc, nargs - 1);
6573 for (z = 0; z < 3; z++)
6574 VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6575 /* Skip the boolean weak parameter. */
6576 for (z = 4; z < 6; z++)
6577 VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6578 exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
6579 break;
6582 case BUILT_IN_ATOMIC_LOAD_1:
6583 case BUILT_IN_ATOMIC_LOAD_2:
6584 case BUILT_IN_ATOMIC_LOAD_4:
6585 case BUILT_IN_ATOMIC_LOAD_8:
6586 case BUILT_IN_ATOMIC_LOAD_16:
6587 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1);
6588 target = expand_builtin_atomic_load (mode, exp, target);
6589 if (target)
6590 return target;
6591 break;
6593 case BUILT_IN_ATOMIC_STORE_1:
6594 case BUILT_IN_ATOMIC_STORE_2:
6595 case BUILT_IN_ATOMIC_STORE_4:
6596 case BUILT_IN_ATOMIC_STORE_8:
6597 case BUILT_IN_ATOMIC_STORE_16:
6598 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1);
6599 target = expand_builtin_atomic_store (mode, exp);
6600 if (target)
6601 return const0_rtx;
6602 break;
6604 case BUILT_IN_ATOMIC_ADD_FETCH_1:
6605 case BUILT_IN_ATOMIC_ADD_FETCH_2:
6606 case BUILT_IN_ATOMIC_ADD_FETCH_4:
6607 case BUILT_IN_ATOMIC_ADD_FETCH_8:
6608 case BUILT_IN_ATOMIC_ADD_FETCH_16:
6610 enum built_in_function lib;
6611 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1);
6612 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 +
6613 (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1));
6614 target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true,
6615 ignore, lib);
6616 if (target)
6617 return target;
6618 break;
6620 case BUILT_IN_ATOMIC_SUB_FETCH_1:
6621 case BUILT_IN_ATOMIC_SUB_FETCH_2:
6622 case BUILT_IN_ATOMIC_SUB_FETCH_4:
6623 case BUILT_IN_ATOMIC_SUB_FETCH_8:
6624 case BUILT_IN_ATOMIC_SUB_FETCH_16:
6626 enum built_in_function lib;
6627 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1);
6628 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 +
6629 (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1));
6630 target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true,
6631 ignore, lib);
6632 if (target)
6633 return target;
6634 break;
6636 case BUILT_IN_ATOMIC_AND_FETCH_1:
6637 case BUILT_IN_ATOMIC_AND_FETCH_2:
6638 case BUILT_IN_ATOMIC_AND_FETCH_4:
6639 case BUILT_IN_ATOMIC_AND_FETCH_8:
6640 case BUILT_IN_ATOMIC_AND_FETCH_16:
6642 enum built_in_function lib;
6643 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1);
6644 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 +
6645 (fcode - BUILT_IN_ATOMIC_AND_FETCH_1));
6646 target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true,
6647 ignore, lib);
6648 if (target)
6649 return target;
6650 break;
6652 case BUILT_IN_ATOMIC_NAND_FETCH_1:
6653 case BUILT_IN_ATOMIC_NAND_FETCH_2:
6654 case BUILT_IN_ATOMIC_NAND_FETCH_4:
6655 case BUILT_IN_ATOMIC_NAND_FETCH_8:
6656 case BUILT_IN_ATOMIC_NAND_FETCH_16:
6658 enum built_in_function lib;
6659 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1);
6660 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 +
6661 (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1));
6662 target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true,
6663 ignore, lib);
6664 if (target)
6665 return target;
6666 break;
6668 case BUILT_IN_ATOMIC_XOR_FETCH_1:
6669 case BUILT_IN_ATOMIC_XOR_FETCH_2:
6670 case BUILT_IN_ATOMIC_XOR_FETCH_4:
6671 case BUILT_IN_ATOMIC_XOR_FETCH_8:
6672 case BUILT_IN_ATOMIC_XOR_FETCH_16:
6674 enum built_in_function lib;
6675 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1);
6676 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 +
6677 (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1));
6678 target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true,
6679 ignore, lib);
6680 if (target)
6681 return target;
6682 break;
6684 case BUILT_IN_ATOMIC_OR_FETCH_1:
6685 case BUILT_IN_ATOMIC_OR_FETCH_2:
6686 case BUILT_IN_ATOMIC_OR_FETCH_4:
6687 case BUILT_IN_ATOMIC_OR_FETCH_8:
6688 case BUILT_IN_ATOMIC_OR_FETCH_16:
6690 enum built_in_function lib;
6691 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1);
6692 lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 +
6693 (fcode - BUILT_IN_ATOMIC_OR_FETCH_1));
6694 target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true,
6695 ignore, lib);
6696 if (target)
6697 return target;
6698 break;
6700 case BUILT_IN_ATOMIC_FETCH_ADD_1:
6701 case BUILT_IN_ATOMIC_FETCH_ADD_2:
6702 case BUILT_IN_ATOMIC_FETCH_ADD_4:
6703 case BUILT_IN_ATOMIC_FETCH_ADD_8:
6704 case BUILT_IN_ATOMIC_FETCH_ADD_16:
6705 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1);
6706 target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false,
6707 ignore, BUILT_IN_NONE);
6708 if (target)
6709 return target;
6710 break;
6712 case BUILT_IN_ATOMIC_FETCH_SUB_1:
6713 case BUILT_IN_ATOMIC_FETCH_SUB_2:
6714 case BUILT_IN_ATOMIC_FETCH_SUB_4:
6715 case BUILT_IN_ATOMIC_FETCH_SUB_8:
6716 case BUILT_IN_ATOMIC_FETCH_SUB_16:
6717 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1);
6718 target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false,
6719 ignore, BUILT_IN_NONE);
6720 if (target)
6721 return target;
6722 break;
6724 case BUILT_IN_ATOMIC_FETCH_AND_1:
6725 case BUILT_IN_ATOMIC_FETCH_AND_2:
6726 case BUILT_IN_ATOMIC_FETCH_AND_4:
6727 case BUILT_IN_ATOMIC_FETCH_AND_8:
6728 case BUILT_IN_ATOMIC_FETCH_AND_16:
6729 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1);
6730 target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false,
6731 ignore, BUILT_IN_NONE);
6732 if (target)
6733 return target;
6734 break;
6736 case BUILT_IN_ATOMIC_FETCH_NAND_1:
6737 case BUILT_IN_ATOMIC_FETCH_NAND_2:
6738 case BUILT_IN_ATOMIC_FETCH_NAND_4:
6739 case BUILT_IN_ATOMIC_FETCH_NAND_8:
6740 case BUILT_IN_ATOMIC_FETCH_NAND_16:
6741 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1);
6742 target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false,
6743 ignore, BUILT_IN_NONE);
6744 if (target)
6745 return target;
6746 break;
6748 case BUILT_IN_ATOMIC_FETCH_XOR_1:
6749 case BUILT_IN_ATOMIC_FETCH_XOR_2:
6750 case BUILT_IN_ATOMIC_FETCH_XOR_4:
6751 case BUILT_IN_ATOMIC_FETCH_XOR_8:
6752 case BUILT_IN_ATOMIC_FETCH_XOR_16:
6753 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1);
6754 target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false,
6755 ignore, BUILT_IN_NONE);
6756 if (target)
6757 return target;
6758 break;
6760 case BUILT_IN_ATOMIC_FETCH_OR_1:
6761 case BUILT_IN_ATOMIC_FETCH_OR_2:
6762 case BUILT_IN_ATOMIC_FETCH_OR_4:
6763 case BUILT_IN_ATOMIC_FETCH_OR_8:
6764 case BUILT_IN_ATOMIC_FETCH_OR_16:
6765 mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1);
6766 target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false,
6767 ignore, BUILT_IN_NONE);
6768 if (target)
6769 return target;
6770 break;
6772 case BUILT_IN_ATOMIC_TEST_AND_SET:
6773 return expand_builtin_atomic_test_and_set (exp, target);
6775 case BUILT_IN_ATOMIC_CLEAR:
6776 return expand_builtin_atomic_clear (exp);
6778 case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
6779 return expand_builtin_atomic_always_lock_free (exp);
6781 case BUILT_IN_ATOMIC_IS_LOCK_FREE:
6782 target = expand_builtin_atomic_is_lock_free (exp);
6783 if (target)
6784 return target;
6785 break;
6787 case BUILT_IN_ATOMIC_THREAD_FENCE:
6788 expand_builtin_atomic_thread_fence (exp);
6789 return const0_rtx;
6791 case BUILT_IN_ATOMIC_SIGNAL_FENCE:
6792 expand_builtin_atomic_signal_fence (exp);
6793 return const0_rtx;
6795 case BUILT_IN_OBJECT_SIZE:
6796 return expand_builtin_object_size (exp);
6798 case BUILT_IN_MEMCPY_CHK:
6799 case BUILT_IN_MEMPCPY_CHK:
6800 case BUILT_IN_MEMMOVE_CHK:
6801 case BUILT_IN_MEMSET_CHK:
6802 target = expand_builtin_memory_chk (exp, target, mode, fcode);
6803 if (target)
6804 return target;
6805 break;
6807 case BUILT_IN_STRCPY_CHK:
6808 case BUILT_IN_STPCPY_CHK:
6809 case BUILT_IN_STRNCPY_CHK:
6810 case BUILT_IN_STPNCPY_CHK:
6811 case BUILT_IN_STRCAT_CHK:
6812 case BUILT_IN_STRNCAT_CHK:
6813 case BUILT_IN_SNPRINTF_CHK:
6814 case BUILT_IN_VSNPRINTF_CHK:
6815 maybe_emit_chk_warning (exp, fcode);
6816 break;
6818 case BUILT_IN_SPRINTF_CHK:
6819 case BUILT_IN_VSPRINTF_CHK:
6820 maybe_emit_sprintf_chk_warning (exp, fcode);
6821 break;
6823 case BUILT_IN_FREE:
6824 if (warn_free_nonheap_object)
6825 maybe_emit_free_warning (exp);
6826 break;
6828 default: /* just do library call, if unknown builtin */
6829 break;
6832 /* The switch statement above can drop through to cause the function
6833 to be called normally. */
6834 return expand_call (exp, target, ignore);
6837 /* Determine whether a tree node represents a call to a built-in
6838 function. If the tree T is a call to a built-in function with
6839 the right number of arguments of the appropriate types, return
6840 the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6841 Otherwise the return value is END_BUILTINS. */
6843 enum built_in_function
6844 builtin_mathfn_code (const_tree t)
6846 const_tree fndecl, arg, parmlist;
6847 const_tree argtype, parmtype;
6848 const_call_expr_arg_iterator iter;
6850 if (TREE_CODE (t) != CALL_EXPR
6851 || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6852 return END_BUILTINS;
6854 fndecl = get_callee_fndecl (t);
6855 if (fndecl == NULL_TREE
6856 || TREE_CODE (fndecl) != FUNCTION_DECL
6857 || ! DECL_BUILT_IN (fndecl)
6858 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6859 return END_BUILTINS;
6861 parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6862 init_const_call_expr_arg_iterator (t, &iter);
6863 for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6865 /* If a function doesn't take a variable number of arguments,
6866 the last element in the list will have type `void'. */
6867 parmtype = TREE_VALUE (parmlist);
6868 if (VOID_TYPE_P (parmtype))
6870 if (more_const_call_expr_args_p (&iter))
6871 return END_BUILTINS;
6872 return DECL_FUNCTION_CODE (fndecl);
6875 if (! more_const_call_expr_args_p (&iter))
6876 return END_BUILTINS;
6878 arg = next_const_call_expr_arg (&iter);
6879 argtype = TREE_TYPE (arg);
6881 if (SCALAR_FLOAT_TYPE_P (parmtype))
6883 if (! SCALAR_FLOAT_TYPE_P (argtype))
6884 return END_BUILTINS;
6886 else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6888 if (! COMPLEX_FLOAT_TYPE_P (argtype))
6889 return END_BUILTINS;
6891 else if (POINTER_TYPE_P (parmtype))
6893 if (! POINTER_TYPE_P (argtype))
6894 return END_BUILTINS;
6896 else if (INTEGRAL_TYPE_P (parmtype))
6898 if (! INTEGRAL_TYPE_P (argtype))
6899 return END_BUILTINS;
6901 else
6902 return END_BUILTINS;
6905 /* Variable-length argument list. */
6906 return DECL_FUNCTION_CODE (fndecl);
6909 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
6910 evaluate to a constant. */
6912 static tree
6913 fold_builtin_constant_p (tree arg)
6915 /* We return 1 for a numeric type that's known to be a constant
6916 value at compile-time or for an aggregate type that's a
6917 literal constant. */
6918 STRIP_NOPS (arg);
6920 /* If we know this is a constant, emit the constant of one. */
6921 if (CONSTANT_CLASS_P (arg)
6922 || (TREE_CODE (arg) == CONSTRUCTOR
6923 && TREE_CONSTANT (arg)))
6924 return integer_one_node;
6925 if (TREE_CODE (arg) == ADDR_EXPR)
6927 tree op = TREE_OPERAND (arg, 0);
6928 if (TREE_CODE (op) == STRING_CST
6929 || (TREE_CODE (op) == ARRAY_REF
6930 && integer_zerop (TREE_OPERAND (op, 1))
6931 && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6932 return integer_one_node;
6935 /* If this expression has side effects, show we don't know it to be a
6936 constant. Likewise if it's a pointer or aggregate type since in
6937 those case we only want literals, since those are only optimized
6938 when generating RTL, not later.
6939 And finally, if we are compiling an initializer, not code, we
6940 need to return a definite result now; there's not going to be any
6941 more optimization done. */
6942 if (TREE_SIDE_EFFECTS (arg)
6943 || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6944 || POINTER_TYPE_P (TREE_TYPE (arg))
6945 || cfun == 0
6946 || folding_initializer)
6947 return integer_zero_node;
6949 return NULL_TREE;
6952 /* Create builtin_expect with PRED and EXPECTED as its arguments and
6953 return it as a truthvalue. */
6955 static tree
6956 build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6958 tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6960 fn = builtin_decl_explicit (BUILT_IN_EXPECT);
6961 arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6962 ret_type = TREE_TYPE (TREE_TYPE (fn));
6963 pred_type = TREE_VALUE (arg_types);
6964 expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6966 pred = fold_convert_loc (loc, pred_type, pred);
6967 expected = fold_convert_loc (loc, expected_type, expected);
6968 call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
6970 return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6971 build_int_cst (ret_type, 0));
6974 /* Fold a call to builtin_expect with arguments ARG0 and ARG1. Return
6975 NULL_TREE if no simplification is possible. */
6977 static tree
6978 fold_builtin_expect (location_t loc, tree arg0, tree arg1)
6980 tree inner, fndecl, inner_arg0;
6981 enum tree_code code;
6983 /* Distribute the expected value over short-circuiting operators.
6984 See through the cast from truthvalue_type_node to long. */
6985 inner_arg0 = arg0;
6986 while (TREE_CODE (inner_arg0) == NOP_EXPR
6987 && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0))
6988 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0))))
6989 inner_arg0 = TREE_OPERAND (inner_arg0, 0);
6991 /* If this is a builtin_expect within a builtin_expect keep the
6992 inner one. See through a comparison against a constant. It
6993 might have been added to create a thruthvalue. */
6994 inner = inner_arg0;
6996 if (COMPARISON_CLASS_P (inner)
6997 && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6998 inner = TREE_OPERAND (inner, 0);
7000 if (TREE_CODE (inner) == CALL_EXPR
7001 && (fndecl = get_callee_fndecl (inner))
7002 && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7003 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7004 return arg0;
7006 inner = inner_arg0;
7007 code = TREE_CODE (inner);
7008 if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7010 tree op0 = TREE_OPERAND (inner, 0);
7011 tree op1 = TREE_OPERAND (inner, 1);
7013 op0 = build_builtin_expect_predicate (loc, op0, arg1);
7014 op1 = build_builtin_expect_predicate (loc, op1, arg1);
7015 inner = build2 (code, TREE_TYPE (inner), op0, op1);
7017 return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
7020 /* If the argument isn't invariant then there's nothing else we can do. */
7021 if (!TREE_CONSTANT (inner_arg0))
7022 return NULL_TREE;
7024 /* If we expect that a comparison against the argument will fold to
7025 a constant return the constant. In practice, this means a true
7026 constant or the address of a non-weak symbol. */
7027 inner = inner_arg0;
7028 STRIP_NOPS (inner);
7029 if (TREE_CODE (inner) == ADDR_EXPR)
7033 inner = TREE_OPERAND (inner, 0);
7035 while (TREE_CODE (inner) == COMPONENT_REF
7036 || TREE_CODE (inner) == ARRAY_REF);
7037 if ((TREE_CODE (inner) == VAR_DECL
7038 || TREE_CODE (inner) == FUNCTION_DECL)
7039 && DECL_WEAK (inner))
7040 return NULL_TREE;
7043 /* Otherwise, ARG0 already has the proper type for the return value. */
7044 return arg0;
7047 /* Fold a call to __builtin_classify_type with argument ARG. */
7049 static tree
7050 fold_builtin_classify_type (tree arg)
7052 if (arg == 0)
7053 return build_int_cst (integer_type_node, no_type_class);
7055 return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg)));
7058 /* Fold a call to __builtin_strlen with argument ARG. */
7060 static tree
7061 fold_builtin_strlen (location_t loc, tree type, tree arg)
7063 if (!validate_arg (arg, POINTER_TYPE))
7064 return NULL_TREE;
7065 else
7067 tree len = c_strlen (arg, 0);
7069 if (len)
7070 return fold_convert_loc (loc, type, len);
7072 return NULL_TREE;
7076 /* Fold a call to __builtin_inf or __builtin_huge_val. */
7078 static tree
7079 fold_builtin_inf (location_t loc, tree type, int warn)
7081 REAL_VALUE_TYPE real;
7083 /* __builtin_inff is intended to be usable to define INFINITY on all
7084 targets. If an infinity is not available, INFINITY expands "to a
7085 positive constant of type float that overflows at translation
7086 time", footnote "In this case, using INFINITY will violate the
7087 constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7088 Thus we pedwarn to ensure this constraint violation is
7089 diagnosed. */
7090 if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7091 pedwarn (loc, 0, "target format does not support infinity");
7093 real_inf (&real);
7094 return build_real (type, real);
7097 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG. */
7099 static tree
7100 fold_builtin_nan (tree arg, tree type, int quiet)
7102 REAL_VALUE_TYPE real;
7103 const char *str;
7105 if (!validate_arg (arg, POINTER_TYPE))
7106 return NULL_TREE;
7107 str = c_getstr (arg);
7108 if (!str)
7109 return NULL_TREE;
7111 if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7112 return NULL_TREE;
7114 return build_real (type, real);
7117 /* Return true if the floating point expression T has an integer value.
7118 We also allow +Inf, -Inf and NaN to be considered integer values. */
7120 static bool
7121 integer_valued_real_p (tree t)
7123 switch (TREE_CODE (t))
7125 case FLOAT_EXPR:
7126 return true;
7128 case ABS_EXPR:
7129 case SAVE_EXPR:
7130 return integer_valued_real_p (TREE_OPERAND (t, 0));
7132 case COMPOUND_EXPR:
7133 case MODIFY_EXPR:
7134 case BIND_EXPR:
7135 return integer_valued_real_p (TREE_OPERAND (t, 1));
7137 case PLUS_EXPR:
7138 case MINUS_EXPR:
7139 case MULT_EXPR:
7140 case MIN_EXPR:
7141 case MAX_EXPR:
7142 return integer_valued_real_p (TREE_OPERAND (t, 0))
7143 && integer_valued_real_p (TREE_OPERAND (t, 1));
7145 case COND_EXPR:
7146 return integer_valued_real_p (TREE_OPERAND (t, 1))
7147 && integer_valued_real_p (TREE_OPERAND (t, 2));
7149 case REAL_CST:
7150 return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7152 case NOP_EXPR:
7154 tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7155 if (TREE_CODE (type) == INTEGER_TYPE)
7156 return true;
7157 if (TREE_CODE (type) == REAL_TYPE)
7158 return integer_valued_real_p (TREE_OPERAND (t, 0));
7159 break;
7162 case CALL_EXPR:
7163 switch (builtin_mathfn_code (t))
7165 CASE_FLT_FN (BUILT_IN_CEIL):
7166 CASE_FLT_FN (BUILT_IN_FLOOR):
7167 CASE_FLT_FN (BUILT_IN_NEARBYINT):
7168 CASE_FLT_FN (BUILT_IN_RINT):
7169 CASE_FLT_FN (BUILT_IN_ROUND):
7170 CASE_FLT_FN (BUILT_IN_TRUNC):
7171 return true;
7173 CASE_FLT_FN (BUILT_IN_FMIN):
7174 CASE_FLT_FN (BUILT_IN_FMAX):
7175 return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7176 && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7178 default:
7179 break;
7181 break;
7183 default:
7184 break;
7186 return false;
7189 /* FNDECL is assumed to be a builtin where truncation can be propagated
7190 across (for instance floor((double)f) == (double)floorf (f).
7191 Do the transformation for a call with argument ARG. */
7193 static tree
7194 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7196 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7198 if (!validate_arg (arg, REAL_TYPE))
7199 return NULL_TREE;
7201 /* Integer rounding functions are idempotent. */
7202 if (fcode == builtin_mathfn_code (arg))
7203 return arg;
7205 /* If argument is already integer valued, and we don't need to worry
7206 about setting errno, there's no need to perform rounding. */
7207 if (! flag_errno_math && integer_valued_real_p (arg))
7208 return arg;
7210 if (optimize)
7212 tree arg0 = strip_float_extensions (arg);
7213 tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7214 tree newtype = TREE_TYPE (arg0);
7215 tree decl;
7217 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7218 && (decl = mathfn_built_in (newtype, fcode)))
7219 return fold_convert_loc (loc, ftype,
7220 build_call_expr_loc (loc, decl, 1,
7221 fold_convert_loc (loc,
7222 newtype,
7223 arg0)));
7225 return NULL_TREE;
7228 /* FNDECL is assumed to be builtin which can narrow the FP type of
7229 the argument, for instance lround((double)f) -> lroundf (f).
7230 Do the transformation for a call with argument ARG. */
7232 static tree
7233 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7235 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7237 if (!validate_arg (arg, REAL_TYPE))
7238 return NULL_TREE;
7240 /* If argument is already integer valued, and we don't need to worry
7241 about setting errno, there's no need to perform rounding. */
7242 if (! flag_errno_math && integer_valued_real_p (arg))
7243 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7244 TREE_TYPE (TREE_TYPE (fndecl)), arg);
7246 if (optimize)
7248 tree ftype = TREE_TYPE (arg);
7249 tree arg0 = strip_float_extensions (arg);
7250 tree newtype = TREE_TYPE (arg0);
7251 tree decl;
7253 if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7254 && (decl = mathfn_built_in (newtype, fcode)))
7255 return build_call_expr_loc (loc, decl, 1,
7256 fold_convert_loc (loc, newtype, arg0));
7259 /* Canonicalize iround (x) to lround (x) on ILP32 targets where
7260 sizeof (int) == sizeof (long). */
7261 if (TYPE_PRECISION (integer_type_node)
7262 == TYPE_PRECISION (long_integer_type_node))
7264 tree newfn = NULL_TREE;
7265 switch (fcode)
7267 CASE_FLT_FN (BUILT_IN_ICEIL):
7268 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7269 break;
7271 CASE_FLT_FN (BUILT_IN_IFLOOR):
7272 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7273 break;
7275 CASE_FLT_FN (BUILT_IN_IROUND):
7276 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7277 break;
7279 CASE_FLT_FN (BUILT_IN_IRINT):
7280 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7281 break;
7283 default:
7284 break;
7287 if (newfn)
7289 tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7290 return fold_convert_loc (loc,
7291 TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7295 /* Canonicalize llround (x) to lround (x) on LP64 targets where
7296 sizeof (long long) == sizeof (long). */
7297 if (TYPE_PRECISION (long_long_integer_type_node)
7298 == TYPE_PRECISION (long_integer_type_node))
7300 tree newfn = NULL_TREE;
7301 switch (fcode)
7303 CASE_FLT_FN (BUILT_IN_LLCEIL):
7304 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7305 break;
7307 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7308 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7309 break;
7311 CASE_FLT_FN (BUILT_IN_LLROUND):
7312 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7313 break;
7315 CASE_FLT_FN (BUILT_IN_LLRINT):
7316 newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7317 break;
7319 default:
7320 break;
7323 if (newfn)
7325 tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7326 return fold_convert_loc (loc,
7327 TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7331 return NULL_TREE;
7334 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG. TYPE is the
7335 return type. Return NULL_TREE if no simplification can be made. */
7337 static tree
7338 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7340 tree res;
7342 if (!validate_arg (arg, COMPLEX_TYPE)
7343 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7344 return NULL_TREE;
7346 /* Calculate the result when the argument is a constant. */
7347 if (TREE_CODE (arg) == COMPLEX_CST
7348 && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7349 type, mpfr_hypot)))
7350 return res;
7352 if (TREE_CODE (arg) == COMPLEX_EXPR)
7354 tree real = TREE_OPERAND (arg, 0);
7355 tree imag = TREE_OPERAND (arg, 1);
7357 /* If either part is zero, cabs is fabs of the other. */
7358 if (real_zerop (real))
7359 return fold_build1_loc (loc, ABS_EXPR, type, imag);
7360 if (real_zerop (imag))
7361 return fold_build1_loc (loc, ABS_EXPR, type, real);
7363 /* cabs(x+xi) -> fabs(x)*sqrt(2). */
7364 if (flag_unsafe_math_optimizations
7365 && operand_equal_p (real, imag, OEP_PURE_SAME))
7367 const REAL_VALUE_TYPE sqrt2_trunc
7368 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7369 STRIP_NOPS (real);
7370 return fold_build2_loc (loc, MULT_EXPR, type,
7371 fold_build1_loc (loc, ABS_EXPR, type, real),
7372 build_real (type, sqrt2_trunc));
7376 /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z). */
7377 if (TREE_CODE (arg) == NEGATE_EXPR
7378 || TREE_CODE (arg) == CONJ_EXPR)
7379 return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7381 /* Don't do this when optimizing for size. */
7382 if (flag_unsafe_math_optimizations
7383 && optimize && optimize_function_for_speed_p (cfun))
7385 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7387 if (sqrtfn != NULL_TREE)
7389 tree rpart, ipart, result;
7391 arg = builtin_save_expr (arg);
7393 rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7394 ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7396 rpart = builtin_save_expr (rpart);
7397 ipart = builtin_save_expr (ipart);
7399 result = fold_build2_loc (loc, PLUS_EXPR, type,
7400 fold_build2_loc (loc, MULT_EXPR, type,
7401 rpart, rpart),
7402 fold_build2_loc (loc, MULT_EXPR, type,
7403 ipart, ipart));
7405 return build_call_expr_loc (loc, sqrtfn, 1, result);
7409 return NULL_TREE;
7412 /* Build a complex (inf +- 0i) for the result of cproj. TYPE is the
7413 complex tree type of the result. If NEG is true, the imaginary
7414 zero is negative. */
7416 static tree
7417 build_complex_cproj (tree type, bool neg)
7419 REAL_VALUE_TYPE rinf, rzero = dconst0;
7421 real_inf (&rinf);
7422 rzero.sign = neg;
7423 return build_complex (type, build_real (TREE_TYPE (type), rinf),
7424 build_real (TREE_TYPE (type), rzero));
7427 /* Fold call to builtin cproj, cprojf or cprojl with argument ARG. TYPE is the
7428 return type. Return NULL_TREE if no simplification can be made. */
7430 static tree
7431 fold_builtin_cproj (location_t loc, tree arg, tree type)
7433 if (!validate_arg (arg, COMPLEX_TYPE)
7434 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7435 return NULL_TREE;
7437 /* If there are no infinities, return arg. */
7438 if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
7439 return non_lvalue_loc (loc, arg);
7441 /* Calculate the result when the argument is a constant. */
7442 if (TREE_CODE (arg) == COMPLEX_CST)
7444 const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
7445 const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
7447 if (real_isinf (real) || real_isinf (imag))
7448 return build_complex_cproj (type, imag->sign);
7449 else
7450 return arg;
7452 else if (TREE_CODE (arg) == COMPLEX_EXPR)
7454 tree real = TREE_OPERAND (arg, 0);
7455 tree imag = TREE_OPERAND (arg, 1);
7457 STRIP_NOPS (real);
7458 STRIP_NOPS (imag);
7460 /* If the real part is inf and the imag part is known to be
7461 nonnegative, return (inf + 0i). Remember side-effects are
7462 possible in the imag part. */
7463 if (TREE_CODE (real) == REAL_CST
7464 && real_isinf (TREE_REAL_CST_PTR (real))
7465 && tree_expr_nonnegative_p (imag))
7466 return omit_one_operand_loc (loc, type,
7467 build_complex_cproj (type, false),
7468 arg);
7470 /* If the imag part is inf, return (inf+I*copysign(0,imag)).
7471 Remember side-effects are possible in the real part. */
7472 if (TREE_CODE (imag) == REAL_CST
7473 && real_isinf (TREE_REAL_CST_PTR (imag)))
7474 return
7475 omit_one_operand_loc (loc, type,
7476 build_complex_cproj (type, TREE_REAL_CST_PTR
7477 (imag)->sign), arg);
7480 return NULL_TREE;
7483 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7484 Return NULL_TREE if no simplification can be made. */
7486 static tree
7487 fold_builtin_sqrt (location_t loc, tree arg, tree type)
7490 enum built_in_function fcode;
7491 tree res;
7493 if (!validate_arg (arg, REAL_TYPE))
7494 return NULL_TREE;
7496 /* Calculate the result when the argument is a constant. */
7497 if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7498 return res;
7500 /* Optimize sqrt(expN(x)) = expN(x*0.5). */
7501 fcode = builtin_mathfn_code (arg);
7502 if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7504 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7505 arg = fold_build2_loc (loc, MULT_EXPR, type,
7506 CALL_EXPR_ARG (arg, 0),
7507 build_real (type, dconsthalf));
7508 return build_call_expr_loc (loc, expfn, 1, arg);
7511 /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)). */
7512 if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7514 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7516 if (powfn)
7518 tree arg0 = CALL_EXPR_ARG (arg, 0);
7519 tree tree_root;
7520 /* The inner root was either sqrt or cbrt. */
7521 /* This was a conditional expression but it triggered a bug
7522 in Sun C 5.5. */
7523 REAL_VALUE_TYPE dconstroot;
7524 if (BUILTIN_SQRT_P (fcode))
7525 dconstroot = dconsthalf;
7526 else
7527 dconstroot = dconst_third ();
7529 /* Adjust for the outer root. */
7530 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7531 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7532 tree_root = build_real (type, dconstroot);
7533 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7537 /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5). */
7538 if (flag_unsafe_math_optimizations
7539 && (fcode == BUILT_IN_POW
7540 || fcode == BUILT_IN_POWF
7541 || fcode == BUILT_IN_POWL))
7543 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7544 tree arg0 = CALL_EXPR_ARG (arg, 0);
7545 tree arg1 = CALL_EXPR_ARG (arg, 1);
7546 tree narg1;
7547 if (!tree_expr_nonnegative_p (arg0))
7548 arg0 = build1 (ABS_EXPR, type, arg0);
7549 narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7550 build_real (type, dconsthalf));
7551 return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7554 return NULL_TREE;
7557 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7558 Return NULL_TREE if no simplification can be made. */
7560 static tree
7561 fold_builtin_cbrt (location_t loc, tree arg, tree type)
7563 const enum built_in_function fcode = builtin_mathfn_code (arg);
7564 tree res;
7566 if (!validate_arg (arg, REAL_TYPE))
7567 return NULL_TREE;
7569 /* Calculate the result when the argument is a constant. */
7570 if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7571 return res;
7573 if (flag_unsafe_math_optimizations)
7575 /* Optimize cbrt(expN(x)) -> expN(x/3). */
7576 if (BUILTIN_EXPONENT_P (fcode))
7578 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7579 const REAL_VALUE_TYPE third_trunc =
7580 real_value_truncate (TYPE_MODE (type), dconst_third ());
7581 arg = fold_build2_loc (loc, MULT_EXPR, type,
7582 CALL_EXPR_ARG (arg, 0),
7583 build_real (type, third_trunc));
7584 return build_call_expr_loc (loc, expfn, 1, arg);
7587 /* Optimize cbrt(sqrt(x)) -> pow(x,1/6). */
7588 if (BUILTIN_SQRT_P (fcode))
7590 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7592 if (powfn)
7594 tree arg0 = CALL_EXPR_ARG (arg, 0);
7595 tree tree_root;
7596 REAL_VALUE_TYPE dconstroot = dconst_third ();
7598 SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7599 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7600 tree_root = build_real (type, dconstroot);
7601 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7605 /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative. */
7606 if (BUILTIN_CBRT_P (fcode))
7608 tree arg0 = CALL_EXPR_ARG (arg, 0);
7609 if (tree_expr_nonnegative_p (arg0))
7611 tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7613 if (powfn)
7615 tree tree_root;
7616 REAL_VALUE_TYPE dconstroot;
7618 real_arithmetic (&dconstroot, MULT_EXPR,
7619 dconst_third_ptr (), dconst_third_ptr ());
7620 dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7621 tree_root = build_real (type, dconstroot);
7622 return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7627 /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative. */
7628 if (fcode == BUILT_IN_POW
7629 || fcode == BUILT_IN_POWF
7630 || fcode == BUILT_IN_POWL)
7632 tree arg00 = CALL_EXPR_ARG (arg, 0);
7633 tree arg01 = CALL_EXPR_ARG (arg, 1);
7634 if (tree_expr_nonnegative_p (arg00))
7636 tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7637 const REAL_VALUE_TYPE dconstroot
7638 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7639 tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7640 build_real (type, dconstroot));
7641 return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7645 return NULL_TREE;
7648 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7649 TYPE is the type of the return value. Return NULL_TREE if no
7650 simplification can be made. */
7652 static tree
7653 fold_builtin_cos (location_t loc,
7654 tree arg, tree type, tree fndecl)
7656 tree res, narg;
7658 if (!validate_arg (arg, REAL_TYPE))
7659 return NULL_TREE;
7661 /* Calculate the result when the argument is a constant. */
7662 if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7663 return res;
7665 /* Optimize cos(-x) into cos (x). */
7666 if ((narg = fold_strip_sign_ops (arg)))
7667 return build_call_expr_loc (loc, fndecl, 1, narg);
7669 return NULL_TREE;
7672 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7673 Return NULL_TREE if no simplification can be made. */
7675 static tree
7676 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7678 if (validate_arg (arg, REAL_TYPE))
7680 tree res, narg;
7682 /* Calculate the result when the argument is a constant. */
7683 if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7684 return res;
7686 /* Optimize cosh(-x) into cosh (x). */
7687 if ((narg = fold_strip_sign_ops (arg)))
7688 return build_call_expr_loc (loc, fndecl, 1, narg);
7691 return NULL_TREE;
7694 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7695 argument ARG. TYPE is the type of the return value. Return
7696 NULL_TREE if no simplification can be made. */
7698 static tree
7699 fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl,
7700 bool hyper)
7702 if (validate_arg (arg, COMPLEX_TYPE)
7703 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7705 tree tmp;
7707 /* Calculate the result when the argument is a constant. */
7708 if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7709 return tmp;
7711 /* Optimize fn(-x) into fn(x). */
7712 if ((tmp = fold_strip_sign_ops (arg)))
7713 return build_call_expr_loc (loc, fndecl, 1, tmp);
7716 return NULL_TREE;
7719 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7720 Return NULL_TREE if no simplification can be made. */
7722 static tree
7723 fold_builtin_tan (tree arg, tree type)
7725 enum built_in_function fcode;
7726 tree res;
7728 if (!validate_arg (arg, REAL_TYPE))
7729 return NULL_TREE;
7731 /* Calculate the result when the argument is a constant. */
7732 if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7733 return res;
7735 /* Optimize tan(atan(x)) = x. */
7736 fcode = builtin_mathfn_code (arg);
7737 if (flag_unsafe_math_optimizations
7738 && (fcode == BUILT_IN_ATAN
7739 || fcode == BUILT_IN_ATANF
7740 || fcode == BUILT_IN_ATANL))
7741 return CALL_EXPR_ARG (arg, 0);
7743 return NULL_TREE;
7746 /* Fold function call to builtin sincos, sincosf, or sincosl. Return
7747 NULL_TREE if no simplification can be made. */
7749 static tree
7750 fold_builtin_sincos (location_t loc,
7751 tree arg0, tree arg1, tree arg2)
7753 tree type;
7754 tree res, fn, call;
7756 if (!validate_arg (arg0, REAL_TYPE)
7757 || !validate_arg (arg1, POINTER_TYPE)
7758 || !validate_arg (arg2, POINTER_TYPE))
7759 return NULL_TREE;
7761 type = TREE_TYPE (arg0);
7763 /* Calculate the result when the argument is a constant. */
7764 if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7765 return res;
7767 /* Canonicalize sincos to cexpi. */
7768 if (!TARGET_C99_FUNCTIONS)
7769 return NULL_TREE;
7770 fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7771 if (!fn)
7772 return NULL_TREE;
7774 call = build_call_expr_loc (loc, fn, 1, arg0);
7775 call = builtin_save_expr (call);
7777 return build2 (COMPOUND_EXPR, void_type_node,
7778 build2 (MODIFY_EXPR, void_type_node,
7779 build_fold_indirect_ref_loc (loc, arg1),
7780 build1 (IMAGPART_EXPR, type, call)),
7781 build2 (MODIFY_EXPR, void_type_node,
7782 build_fold_indirect_ref_loc (loc, arg2),
7783 build1 (REALPART_EXPR, type, call)));
7786 /* Fold function call to builtin cexp, cexpf, or cexpl. Return
7787 NULL_TREE if no simplification can be made. */
7789 static tree
7790 fold_builtin_cexp (location_t loc, tree arg0, tree type)
7792 tree rtype;
7793 tree realp, imagp, ifn;
7794 tree res;
7796 if (!validate_arg (arg0, COMPLEX_TYPE)
7797 || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7798 return NULL_TREE;
7800 /* Calculate the result when the argument is a constant. */
7801 if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7802 return res;
7804 rtype = TREE_TYPE (TREE_TYPE (arg0));
7806 /* In case we can figure out the real part of arg0 and it is constant zero
7807 fold to cexpi. */
7808 if (!TARGET_C99_FUNCTIONS)
7809 return NULL_TREE;
7810 ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7811 if (!ifn)
7812 return NULL_TREE;
7814 if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7815 && real_zerop (realp))
7817 tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7818 return build_call_expr_loc (loc, ifn, 1, narg);
7821 /* In case we can easily decompose real and imaginary parts split cexp
7822 to exp (r) * cexpi (i). */
7823 if (flag_unsafe_math_optimizations
7824 && realp)
7826 tree rfn, rcall, icall;
7828 rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7829 if (!rfn)
7830 return NULL_TREE;
7832 imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7833 if (!imagp)
7834 return NULL_TREE;
7836 icall = build_call_expr_loc (loc, ifn, 1, imagp);
7837 icall = builtin_save_expr (icall);
7838 rcall = build_call_expr_loc (loc, rfn, 1, realp);
7839 rcall = builtin_save_expr (rcall);
7840 return fold_build2_loc (loc, COMPLEX_EXPR, type,
7841 fold_build2_loc (loc, MULT_EXPR, rtype,
7842 rcall,
7843 fold_build1_loc (loc, REALPART_EXPR,
7844 rtype, icall)),
7845 fold_build2_loc (loc, MULT_EXPR, rtype,
7846 rcall,
7847 fold_build1_loc (loc, IMAGPART_EXPR,
7848 rtype, icall)));
7851 return NULL_TREE;
7854 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7855 Return NULL_TREE if no simplification can be made. */
7857 static tree
7858 fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7860 if (!validate_arg (arg, REAL_TYPE))
7861 return NULL_TREE;
7863 /* Optimize trunc of constant value. */
7864 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7866 REAL_VALUE_TYPE r, x;
7867 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7869 x = TREE_REAL_CST (arg);
7870 real_trunc (&r, TYPE_MODE (type), &x);
7871 return build_real (type, r);
7874 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7877 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7878 Return NULL_TREE if no simplification can be made. */
7880 static tree
7881 fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7883 if (!validate_arg (arg, REAL_TYPE))
7884 return NULL_TREE;
7886 /* Optimize floor of constant value. */
7887 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7889 REAL_VALUE_TYPE x;
7891 x = TREE_REAL_CST (arg);
7892 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7894 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7895 REAL_VALUE_TYPE r;
7897 real_floor (&r, TYPE_MODE (type), &x);
7898 return build_real (type, r);
7902 /* Fold floor (x) where x is nonnegative to trunc (x). */
7903 if (tree_expr_nonnegative_p (arg))
7905 tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7906 if (truncfn)
7907 return build_call_expr_loc (loc, truncfn, 1, arg);
7910 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7913 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7914 Return NULL_TREE if no simplification can be made. */
7916 static tree
7917 fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7919 if (!validate_arg (arg, REAL_TYPE))
7920 return NULL_TREE;
7922 /* Optimize ceil of constant value. */
7923 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7925 REAL_VALUE_TYPE x;
7927 x = TREE_REAL_CST (arg);
7928 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7930 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7931 REAL_VALUE_TYPE r;
7933 real_ceil (&r, TYPE_MODE (type), &x);
7934 return build_real (type, r);
7938 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7941 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7942 Return NULL_TREE if no simplification can be made. */
7944 static tree
7945 fold_builtin_round (location_t loc, tree fndecl, tree arg)
7947 if (!validate_arg (arg, REAL_TYPE))
7948 return NULL_TREE;
7950 /* Optimize round of constant value. */
7951 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7953 REAL_VALUE_TYPE x;
7955 x = TREE_REAL_CST (arg);
7956 if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7958 tree type = TREE_TYPE (TREE_TYPE (fndecl));
7959 REAL_VALUE_TYPE r;
7961 real_round (&r, TYPE_MODE (type), &x);
7962 return build_real (type, r);
7966 return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7969 /* Fold function call to builtin lround, lroundf or lroundl (or the
7970 corresponding long long versions) and other rounding functions. ARG
7971 is the argument to the call. Return NULL_TREE if no simplification
7972 can be made. */
7974 static tree
7975 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
7977 if (!validate_arg (arg, REAL_TYPE))
7978 return NULL_TREE;
7980 /* Optimize lround of constant value. */
7981 if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7983 const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7985 if (real_isfinite (&x))
7987 tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7988 tree ftype = TREE_TYPE (arg);
7989 double_int val;
7990 REAL_VALUE_TYPE r;
7992 switch (DECL_FUNCTION_CODE (fndecl))
7994 CASE_FLT_FN (BUILT_IN_IFLOOR):
7995 CASE_FLT_FN (BUILT_IN_LFLOOR):
7996 CASE_FLT_FN (BUILT_IN_LLFLOOR):
7997 real_floor (&r, TYPE_MODE (ftype), &x);
7998 break;
8000 CASE_FLT_FN (BUILT_IN_ICEIL):
8001 CASE_FLT_FN (BUILT_IN_LCEIL):
8002 CASE_FLT_FN (BUILT_IN_LLCEIL):
8003 real_ceil (&r, TYPE_MODE (ftype), &x);
8004 break;
8006 CASE_FLT_FN (BUILT_IN_IROUND):
8007 CASE_FLT_FN (BUILT_IN_LROUND):
8008 CASE_FLT_FN (BUILT_IN_LLROUND):
8009 real_round (&r, TYPE_MODE (ftype), &x);
8010 break;
8012 default:
8013 gcc_unreachable ();
8016 real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
8017 if (double_int_fits_to_tree_p (itype, val))
8018 return double_int_to_tree (itype, val);
8022 switch (DECL_FUNCTION_CODE (fndecl))
8024 CASE_FLT_FN (BUILT_IN_LFLOOR):
8025 CASE_FLT_FN (BUILT_IN_LLFLOOR):
8026 /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x). */
8027 if (tree_expr_nonnegative_p (arg))
8028 return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8029 TREE_TYPE (TREE_TYPE (fndecl)), arg);
8030 break;
8031 default:;
8034 return fold_fixed_mathfn (loc, fndecl, arg);
8037 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8038 and their long and long long variants (i.e. ffsl and ffsll). ARG is
8039 the argument to the call. Return NULL_TREE if no simplification can
8040 be made. */
8042 static tree
8043 fold_builtin_bitop (tree fndecl, tree arg)
8045 if (!validate_arg (arg, INTEGER_TYPE))
8046 return NULL_TREE;
8048 /* Optimize for constant argument. */
8049 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8051 HOST_WIDE_INT hi, width, result;
8052 unsigned HOST_WIDE_INT lo;
8053 tree type;
8055 type = TREE_TYPE (arg);
8056 width = TYPE_PRECISION (type);
8057 lo = TREE_INT_CST_LOW (arg);
8059 /* Clear all the bits that are beyond the type's precision. */
8060 if (width > HOST_BITS_PER_WIDE_INT)
8062 hi = TREE_INT_CST_HIGH (arg);
8063 if (width < HOST_BITS_PER_DOUBLE_INT)
8064 hi &= ~((unsigned HOST_WIDE_INT) (-1)
8065 << (width - HOST_BITS_PER_WIDE_INT));
8067 else
8069 hi = 0;
8070 if (width < HOST_BITS_PER_WIDE_INT)
8071 lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8074 switch (DECL_FUNCTION_CODE (fndecl))
8076 CASE_INT_FN (BUILT_IN_FFS):
8077 if (lo != 0)
8078 result = ffs_hwi (lo);
8079 else if (hi != 0)
8080 result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
8081 else
8082 result = 0;
8083 break;
8085 CASE_INT_FN (BUILT_IN_CLZ):
8086 if (hi != 0)
8087 result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8088 else if (lo != 0)
8089 result = width - floor_log2 (lo) - 1;
8090 else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8091 result = width;
8092 break;
8094 CASE_INT_FN (BUILT_IN_CTZ):
8095 if (lo != 0)
8096 result = ctz_hwi (lo);
8097 else if (hi != 0)
8098 result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
8099 else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8100 result = width;
8101 break;
8103 CASE_INT_FN (BUILT_IN_CLRSB):
8104 if (width > HOST_BITS_PER_WIDE_INT
8105 && (hi & ((unsigned HOST_WIDE_INT) 1
8106 << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
8108 hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
8109 << (width - HOST_BITS_PER_WIDE_INT - 1));
8110 lo = ~lo;
8112 else if (width <= HOST_BITS_PER_WIDE_INT
8113 && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
8114 lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
8115 if (hi != 0)
8116 result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
8117 else if (lo != 0)
8118 result = width - floor_log2 (lo) - 2;
8119 else
8120 result = width - 1;
8121 break;
8123 CASE_INT_FN (BUILT_IN_POPCOUNT):
8124 result = 0;
8125 while (lo)
8126 result++, lo &= lo - 1;
8127 while (hi)
8128 result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8129 break;
8131 CASE_INT_FN (BUILT_IN_PARITY):
8132 result = 0;
8133 while (lo)
8134 result++, lo &= lo - 1;
8135 while (hi)
8136 result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8137 result &= 1;
8138 break;
8140 default:
8141 gcc_unreachable ();
8144 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8147 return NULL_TREE;
8150 /* Fold function call to builtin_bswap and the short, long and long long
8151 variants. Return NULL_TREE if no simplification can be made. */
8152 static tree
8153 fold_builtin_bswap (tree fndecl, tree arg)
8155 if (! validate_arg (arg, INTEGER_TYPE))
8156 return NULL_TREE;
8158 /* Optimize constant value. */
8159 if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8161 HOST_WIDE_INT hi, width, r_hi = 0;
8162 unsigned HOST_WIDE_INT lo, r_lo = 0;
8163 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8165 width = TYPE_PRECISION (type);
8166 lo = TREE_INT_CST_LOW (arg);
8167 hi = TREE_INT_CST_HIGH (arg);
8169 switch (DECL_FUNCTION_CODE (fndecl))
8171 case BUILT_IN_BSWAP16:
8172 case BUILT_IN_BSWAP32:
8173 case BUILT_IN_BSWAP64:
8175 int s;
8177 for (s = 0; s < width; s += 8)
8179 int d = width - s - 8;
8180 unsigned HOST_WIDE_INT byte;
8182 if (s < HOST_BITS_PER_WIDE_INT)
8183 byte = (lo >> s) & 0xff;
8184 else
8185 byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8187 if (d < HOST_BITS_PER_WIDE_INT)
8188 r_lo |= byte << d;
8189 else
8190 r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8194 break;
8196 default:
8197 gcc_unreachable ();
8200 if (width < HOST_BITS_PER_WIDE_INT)
8201 return build_int_cst (type, r_lo);
8202 else
8203 return build_int_cst_wide (type, r_lo, r_hi);
8206 return NULL_TREE;
8209 /* A subroutine of fold_builtin to fold the various logarithmic
8210 functions. Return NULL_TREE if no simplification can me made.
8211 FUNC is the corresponding MPFR logarithm function. */
8213 static tree
8214 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
8215 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8217 if (validate_arg (arg, REAL_TYPE))
8219 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8220 tree res;
8221 const enum built_in_function fcode = builtin_mathfn_code (arg);
8223 /* Calculate the result when the argument is a constant. */
8224 if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8225 return res;
8227 /* Special case, optimize logN(expN(x)) = x. */
8228 if (flag_unsafe_math_optimizations
8229 && ((func == mpfr_log
8230 && (fcode == BUILT_IN_EXP
8231 || fcode == BUILT_IN_EXPF
8232 || fcode == BUILT_IN_EXPL))
8233 || (func == mpfr_log2
8234 && (fcode == BUILT_IN_EXP2
8235 || fcode == BUILT_IN_EXP2F
8236 || fcode == BUILT_IN_EXP2L))
8237 || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8238 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8240 /* Optimize logN(func()) for various exponential functions. We
8241 want to determine the value "x" and the power "exponent" in
8242 order to transform logN(x**exponent) into exponent*logN(x). */
8243 if (flag_unsafe_math_optimizations)
8245 tree exponent = 0, x = 0;
8247 switch (fcode)
8249 CASE_FLT_FN (BUILT_IN_EXP):
8250 /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
8251 x = build_real (type, real_value_truncate (TYPE_MODE (type),
8252 dconst_e ()));
8253 exponent = CALL_EXPR_ARG (arg, 0);
8254 break;
8255 CASE_FLT_FN (BUILT_IN_EXP2):
8256 /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
8257 x = build_real (type, dconst2);
8258 exponent = CALL_EXPR_ARG (arg, 0);
8259 break;
8260 CASE_FLT_FN (BUILT_IN_EXP10):
8261 CASE_FLT_FN (BUILT_IN_POW10):
8262 /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
8264 REAL_VALUE_TYPE dconst10;
8265 real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8266 x = build_real (type, dconst10);
8268 exponent = CALL_EXPR_ARG (arg, 0);
8269 break;
8270 CASE_FLT_FN (BUILT_IN_SQRT):
8271 /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
8272 x = CALL_EXPR_ARG (arg, 0);
8273 exponent = build_real (type, dconsthalf);
8274 break;
8275 CASE_FLT_FN (BUILT_IN_CBRT):
8276 /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
8277 x = CALL_EXPR_ARG (arg, 0);
8278 exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8279 dconst_third ()));
8280 break;
8281 CASE_FLT_FN (BUILT_IN_POW):
8282 /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
8283 x = CALL_EXPR_ARG (arg, 0);
8284 exponent = CALL_EXPR_ARG (arg, 1);
8285 break;
8286 default:
8287 break;
8290 /* Now perform the optimization. */
8291 if (x && exponent)
8293 tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8294 return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8299 return NULL_TREE;
8302 /* Fold a builtin function call to hypot, hypotf, or hypotl. Return
8303 NULL_TREE if no simplification can be made. */
8305 static tree
8306 fold_builtin_hypot (location_t loc, tree fndecl,
8307 tree arg0, tree arg1, tree type)
8309 tree res, narg0, narg1;
8311 if (!validate_arg (arg0, REAL_TYPE)
8312 || !validate_arg (arg1, REAL_TYPE))
8313 return NULL_TREE;
8315 /* Calculate the result when the argument is a constant. */
8316 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8317 return res;
8319 /* If either argument to hypot has a negate or abs, strip that off.
8320 E.g. hypot(-x,fabs(y)) -> hypot(x,y). */
8321 narg0 = fold_strip_sign_ops (arg0);
8322 narg1 = fold_strip_sign_ops (arg1);
8323 if (narg0 || narg1)
8325 return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
8326 narg1 ? narg1 : arg1);
8329 /* If either argument is zero, hypot is fabs of the other. */
8330 if (real_zerop (arg0))
8331 return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8332 else if (real_zerop (arg1))
8333 return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8335 /* hypot(x,x) -> fabs(x)*sqrt(2). */
8336 if (flag_unsafe_math_optimizations
8337 && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8339 const REAL_VALUE_TYPE sqrt2_trunc
8340 = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8341 return fold_build2_loc (loc, MULT_EXPR, type,
8342 fold_build1_loc (loc, ABS_EXPR, type, arg0),
8343 build_real (type, sqrt2_trunc));
8346 return NULL_TREE;
8350 /* Fold a builtin function call to pow, powf, or powl. Return
8351 NULL_TREE if no simplification can be made. */
8352 static tree
8353 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8355 tree res;
8357 if (!validate_arg (arg0, REAL_TYPE)
8358 || !validate_arg (arg1, REAL_TYPE))
8359 return NULL_TREE;
8361 /* Calculate the result when the argument is a constant. */
8362 if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8363 return res;
8365 /* Optimize pow(1.0,y) = 1.0. */
8366 if (real_onep (arg0))
8367 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8369 if (TREE_CODE (arg1) == REAL_CST
8370 && !TREE_OVERFLOW (arg1))
8372 REAL_VALUE_TYPE cint;
8373 REAL_VALUE_TYPE c;
8374 HOST_WIDE_INT n;
8376 c = TREE_REAL_CST (arg1);
8378 /* Optimize pow(x,0.0) = 1.0. */
8379 if (REAL_VALUES_EQUAL (c, dconst0))
8380 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8381 arg0);
8383 /* Optimize pow(x,1.0) = x. */
8384 if (REAL_VALUES_EQUAL (c, dconst1))
8385 return arg0;
8387 /* Optimize pow(x,-1.0) = 1.0/x. */
8388 if (REAL_VALUES_EQUAL (c, dconstm1))
8389 return fold_build2_loc (loc, RDIV_EXPR, type,
8390 build_real (type, dconst1), arg0);
8392 /* Optimize pow(x,0.5) = sqrt(x). */
8393 if (flag_unsafe_math_optimizations
8394 && REAL_VALUES_EQUAL (c, dconsthalf))
8396 tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8398 if (sqrtfn != NULL_TREE)
8399 return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8402 /* Optimize pow(x,1.0/3.0) = cbrt(x). */
8403 if (flag_unsafe_math_optimizations)
8405 const REAL_VALUE_TYPE dconstroot
8406 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8408 if (REAL_VALUES_EQUAL (c, dconstroot))
8410 tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8411 if (cbrtfn != NULL_TREE)
8412 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8416 /* Check for an integer exponent. */
8417 n = real_to_integer (&c);
8418 real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8419 if (real_identical (&c, &cint))
8421 /* Attempt to evaluate pow at compile-time, unless this should
8422 raise an exception. */
8423 if (TREE_CODE (arg0) == REAL_CST
8424 && !TREE_OVERFLOW (arg0)
8425 && (n > 0
8426 || (!flag_trapping_math && !flag_errno_math)
8427 || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8429 REAL_VALUE_TYPE x;
8430 bool inexact;
8432 x = TREE_REAL_CST (arg0);
8433 inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8434 if (flag_unsafe_math_optimizations || !inexact)
8435 return build_real (type, x);
8438 /* Strip sign ops from even integer powers. */
8439 if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8441 tree narg0 = fold_strip_sign_ops (arg0);
8442 if (narg0)
8443 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8448 if (flag_unsafe_math_optimizations)
8450 const enum built_in_function fcode = builtin_mathfn_code (arg0);
8452 /* Optimize pow(expN(x),y) = expN(x*y). */
8453 if (BUILTIN_EXPONENT_P (fcode))
8455 tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8456 tree arg = CALL_EXPR_ARG (arg0, 0);
8457 arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8458 return build_call_expr_loc (loc, expfn, 1, arg);
8461 /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
8462 if (BUILTIN_SQRT_P (fcode))
8464 tree narg0 = CALL_EXPR_ARG (arg0, 0);
8465 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8466 build_real (type, dconsthalf));
8467 return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8470 /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative. */
8471 if (BUILTIN_CBRT_P (fcode))
8473 tree arg = CALL_EXPR_ARG (arg0, 0);
8474 if (tree_expr_nonnegative_p (arg))
8476 const REAL_VALUE_TYPE dconstroot
8477 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8478 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8479 build_real (type, dconstroot));
8480 return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8484 /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative. */
8485 if (fcode == BUILT_IN_POW
8486 || fcode == BUILT_IN_POWF
8487 || fcode == BUILT_IN_POWL)
8489 tree arg00 = CALL_EXPR_ARG (arg0, 0);
8490 if (tree_expr_nonnegative_p (arg00))
8492 tree arg01 = CALL_EXPR_ARG (arg0, 1);
8493 tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8494 return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8499 return NULL_TREE;
8502 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8503 Return NULL_TREE if no simplification can be made. */
8504 static tree
8505 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8506 tree arg0, tree arg1, tree type)
8508 if (!validate_arg (arg0, REAL_TYPE)
8509 || !validate_arg (arg1, INTEGER_TYPE))
8510 return NULL_TREE;
8512 /* Optimize pow(1.0,y) = 1.0. */
8513 if (real_onep (arg0))
8514 return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8516 if (host_integerp (arg1, 0))
8518 HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8520 /* Evaluate powi at compile-time. */
8521 if (TREE_CODE (arg0) == REAL_CST
8522 && !TREE_OVERFLOW (arg0))
8524 REAL_VALUE_TYPE x;
8525 x = TREE_REAL_CST (arg0);
8526 real_powi (&x, TYPE_MODE (type), &x, c);
8527 return build_real (type, x);
8530 /* Optimize pow(x,0) = 1.0. */
8531 if (c == 0)
8532 return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8533 arg0);
8535 /* Optimize pow(x,1) = x. */
8536 if (c == 1)
8537 return arg0;
8539 /* Optimize pow(x,-1) = 1.0/x. */
8540 if (c == -1)
8541 return fold_build2_loc (loc, RDIV_EXPR, type,
8542 build_real (type, dconst1), arg0);
8545 return NULL_TREE;
8548 /* A subroutine of fold_builtin to fold the various exponent
8549 functions. Return NULL_TREE if no simplification can be made.
8550 FUNC is the corresponding MPFR exponent function. */
8552 static tree
8553 fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8554 int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8556 if (validate_arg (arg, REAL_TYPE))
8558 tree type = TREE_TYPE (TREE_TYPE (fndecl));
8559 tree res;
8561 /* Calculate the result when the argument is a constant. */
8562 if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8563 return res;
8565 /* Optimize expN(logN(x)) = x. */
8566 if (flag_unsafe_math_optimizations)
8568 const enum built_in_function fcode = builtin_mathfn_code (arg);
8570 if ((func == mpfr_exp
8571 && (fcode == BUILT_IN_LOG
8572 || fcode == BUILT_IN_LOGF
8573 || fcode == BUILT_IN_LOGL))
8574 || (func == mpfr_exp2
8575 && (fcode == BUILT_IN_LOG2
8576 || fcode == BUILT_IN_LOG2F
8577 || fcode == BUILT_IN_LOG2L))
8578 || (func == mpfr_exp10
8579 && (fcode == BUILT_IN_LOG10
8580 || fcode == BUILT_IN_LOG10F
8581 || fcode == BUILT_IN_LOG10L)))
8582 return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8586 return NULL_TREE;
8589 /* Return true if VAR is a VAR_DECL or a component thereof. */
8591 static bool
8592 var_decl_component_p (tree var)
8594 tree inner = var;
8595 while (handled_component_p (inner))
8596 inner = TREE_OPERAND (inner, 0);
8597 return SSA_VAR_P (inner);
8600 /* Fold function call to builtin memset. Return
8601 NULL_TREE if no simplification can be made. */
8603 static tree
8604 fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8605 tree type, bool ignore)
8607 tree var, ret, etype;
8608 unsigned HOST_WIDE_INT length, cval;
8610 if (! validate_arg (dest, POINTER_TYPE)
8611 || ! validate_arg (c, INTEGER_TYPE)
8612 || ! validate_arg (len, INTEGER_TYPE))
8613 return NULL_TREE;
8615 if (! host_integerp (len, 1))
8616 return NULL_TREE;
8618 /* If the LEN parameter is zero, return DEST. */
8619 if (integer_zerop (len))
8620 return omit_one_operand_loc (loc, type, dest, c);
8622 if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
8623 return NULL_TREE;
8625 var = dest;
8626 STRIP_NOPS (var);
8627 if (TREE_CODE (var) != ADDR_EXPR)
8628 return NULL_TREE;
8630 var = TREE_OPERAND (var, 0);
8631 if (TREE_THIS_VOLATILE (var))
8632 return NULL_TREE;
8634 etype = TREE_TYPE (var);
8635 if (TREE_CODE (etype) == ARRAY_TYPE)
8636 etype = TREE_TYPE (etype);
8638 if (!INTEGRAL_TYPE_P (etype)
8639 && !POINTER_TYPE_P (etype))
8640 return NULL_TREE;
8642 if (! var_decl_component_p (var))
8643 return NULL_TREE;
8645 length = tree_low_cst (len, 1);
8646 if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8647 || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
8648 return NULL_TREE;
8650 if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8651 return NULL_TREE;
8653 if (integer_zerop (c))
8654 cval = 0;
8655 else
8657 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8658 return NULL_TREE;
8660 cval = TREE_INT_CST_LOW (c);
8661 cval &= 0xff;
8662 cval |= cval << 8;
8663 cval |= cval << 16;
8664 cval |= (cval << 31) << 1;
8667 ret = build_int_cst_type (etype, cval);
8668 var = build_fold_indirect_ref_loc (loc,
8669 fold_convert_loc (loc,
8670 build_pointer_type (etype),
8671 dest));
8672 ret = build2 (MODIFY_EXPR, etype, var, ret);
8673 if (ignore)
8674 return ret;
8676 return omit_one_operand_loc (loc, type, dest, ret);
8679 /* Fold function call to builtin memset. Return
8680 NULL_TREE if no simplification can be made. */
8682 static tree
8683 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8685 if (! validate_arg (dest, POINTER_TYPE)
8686 || ! validate_arg (size, INTEGER_TYPE))
8687 return NULL_TREE;
8689 if (!ignore)
8690 return NULL_TREE;
8692 /* New argument list transforming bzero(ptr x, int y) to
8693 memset(ptr x, int 0, size_t y). This is done this way
8694 so that if it isn't expanded inline, we fallback to
8695 calling bzero instead of memset. */
8697 return fold_builtin_memset (loc, dest, integer_zero_node,
8698 fold_convert_loc (loc, size_type_node, size),
8699 void_type_node, ignore);
8702 /* Fold function call to builtin mem{{,p}cpy,move}. Return
8703 NULL_TREE if no simplification can be made.
8704 If ENDP is 0, return DEST (like memcpy).
8705 If ENDP is 1, return DEST+LEN (like mempcpy).
8706 If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8707 If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8708 (memmove). */
8710 static tree
8711 fold_builtin_memory_op (location_t loc, tree dest, tree src,
8712 tree len, tree type, bool ignore, int endp)
8714 tree destvar, srcvar, expr;
8716 if (! validate_arg (dest, POINTER_TYPE)
8717 || ! validate_arg (src, POINTER_TYPE)
8718 || ! validate_arg (len, INTEGER_TYPE))
8719 return NULL_TREE;
8721 /* If the LEN parameter is zero, return DEST. */
8722 if (integer_zerop (len))
8723 return omit_one_operand_loc (loc, type, dest, src);
8725 /* If SRC and DEST are the same (and not volatile), return
8726 DEST{,+LEN,+LEN-1}. */
8727 if (operand_equal_p (src, dest, 0))
8728 expr = len;
8729 else
8731 tree srctype, desttype;
8732 unsigned int src_align, dest_align;
8733 tree off0;
8735 if (endp == 3)
8737 src_align = get_pointer_alignment (src);
8738 dest_align = get_pointer_alignment (dest);
8740 /* Both DEST and SRC must be pointer types.
8741 ??? This is what old code did. Is the testing for pointer types
8742 really mandatory?
8744 If either SRC is readonly or length is 1, we can use memcpy. */
8745 if (!dest_align || !src_align)
8746 return NULL_TREE;
8747 if (readonly_data_expr (src)
8748 || (host_integerp (len, 1)
8749 && (MIN (src_align, dest_align) / BITS_PER_UNIT
8750 >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
8752 tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8753 if (!fn)
8754 return NULL_TREE;
8755 return build_call_expr_loc (loc, fn, 3, dest, src, len);
8758 /* If *src and *dest can't overlap, optimize into memcpy as well. */
8759 if (TREE_CODE (src) == ADDR_EXPR
8760 && TREE_CODE (dest) == ADDR_EXPR)
8762 tree src_base, dest_base, fn;
8763 HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8764 HOST_WIDE_INT size = -1;
8765 HOST_WIDE_INT maxsize = -1;
8767 srcvar = TREE_OPERAND (src, 0);
8768 src_base = get_ref_base_and_extent (srcvar, &src_offset,
8769 &size, &maxsize);
8770 destvar = TREE_OPERAND (dest, 0);
8771 dest_base = get_ref_base_and_extent (destvar, &dest_offset,
8772 &size, &maxsize);
8773 if (host_integerp (len, 1))
8774 maxsize = tree_low_cst (len, 1);
8775 else
8776 maxsize = -1;
8777 src_offset /= BITS_PER_UNIT;
8778 dest_offset /= BITS_PER_UNIT;
8779 if (SSA_VAR_P (src_base)
8780 && SSA_VAR_P (dest_base))
8782 if (operand_equal_p (src_base, dest_base, 0)
8783 && ranges_overlap_p (src_offset, maxsize,
8784 dest_offset, maxsize))
8785 return NULL_TREE;
8787 else if (TREE_CODE (src_base) == MEM_REF
8788 && TREE_CODE (dest_base) == MEM_REF)
8790 double_int off;
8791 if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8792 TREE_OPERAND (dest_base, 0), 0))
8793 return NULL_TREE;
8794 off = double_int_add (mem_ref_offset (src_base),
8795 shwi_to_double_int (src_offset));
8796 if (!double_int_fits_in_shwi_p (off))
8797 return NULL_TREE;
8798 src_offset = off.low;
8799 off = double_int_add (mem_ref_offset (dest_base),
8800 shwi_to_double_int (dest_offset));
8801 if (!double_int_fits_in_shwi_p (off))
8802 return NULL_TREE;
8803 dest_offset = off.low;
8804 if (ranges_overlap_p (src_offset, maxsize,
8805 dest_offset, maxsize))
8806 return NULL_TREE;
8808 else
8809 return NULL_TREE;
8811 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8812 if (!fn)
8813 return NULL_TREE;
8814 return build_call_expr_loc (loc, fn, 3, dest, src, len);
8817 /* If the destination and source do not alias optimize into
8818 memcpy as well. */
8819 if ((is_gimple_min_invariant (dest)
8820 || TREE_CODE (dest) == SSA_NAME)
8821 && (is_gimple_min_invariant (src)
8822 || TREE_CODE (src) == SSA_NAME))
8824 ao_ref destr, srcr;
8825 ao_ref_init_from_ptr_and_size (&destr, dest, len);
8826 ao_ref_init_from_ptr_and_size (&srcr, src, len);
8827 if (!refs_may_alias_p_1 (&destr, &srcr, false))
8829 tree fn;
8830 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8831 if (!fn)
8832 return NULL_TREE;
8833 return build_call_expr_loc (loc, fn, 3, dest, src, len);
8837 return NULL_TREE;
8840 if (!host_integerp (len, 0))
8841 return NULL_TREE;
8842 /* FIXME:
8843 This logic lose for arguments like (type *)malloc (sizeof (type)),
8844 since we strip the casts of up to VOID return value from malloc.
8845 Perhaps we ought to inherit type from non-VOID argument here? */
8846 STRIP_NOPS (src);
8847 STRIP_NOPS (dest);
8848 if (!POINTER_TYPE_P (TREE_TYPE (src))
8849 || !POINTER_TYPE_P (TREE_TYPE (dest)))
8850 return NULL_TREE;
8851 /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */
8852 if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8854 tree tem = TREE_OPERAND (src, 0);
8855 STRIP_NOPS (tem);
8856 if (tem != TREE_OPERAND (src, 0))
8857 src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8859 if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8861 tree tem = TREE_OPERAND (dest, 0);
8862 STRIP_NOPS (tem);
8863 if (tem != TREE_OPERAND (dest, 0))
8864 dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8866 srctype = TREE_TYPE (TREE_TYPE (src));
8867 if (TREE_CODE (srctype) == ARRAY_TYPE
8868 && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8870 srctype = TREE_TYPE (srctype);
8871 STRIP_NOPS (src);
8872 src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8874 desttype = TREE_TYPE (TREE_TYPE (dest));
8875 if (TREE_CODE (desttype) == ARRAY_TYPE
8876 && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8878 desttype = TREE_TYPE (desttype);
8879 STRIP_NOPS (dest);
8880 dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8882 if (TREE_ADDRESSABLE (srctype)
8883 || TREE_ADDRESSABLE (desttype))
8884 return NULL_TREE;
8886 src_align = get_pointer_alignment (src);
8887 dest_align = get_pointer_alignment (dest);
8888 if (dest_align < TYPE_ALIGN (desttype)
8889 || src_align < TYPE_ALIGN (srctype))
8890 return NULL_TREE;
8892 if (!ignore)
8893 dest = builtin_save_expr (dest);
8895 /* Build accesses at offset zero with a ref-all character type. */
8896 off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
8897 ptr_mode, true), 0);
8899 destvar = dest;
8900 STRIP_NOPS (destvar);
8901 if (TREE_CODE (destvar) == ADDR_EXPR
8902 && var_decl_component_p (TREE_OPERAND (destvar, 0))
8903 && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8904 destvar = fold_build2 (MEM_REF, desttype, destvar, off0);
8905 else
8906 destvar = NULL_TREE;
8908 srcvar = src;
8909 STRIP_NOPS (srcvar);
8910 if (TREE_CODE (srcvar) == ADDR_EXPR
8911 && var_decl_component_p (TREE_OPERAND (srcvar, 0))
8912 && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8914 if (!destvar
8915 || src_align >= TYPE_ALIGN (desttype))
8916 srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
8917 srcvar, off0);
8918 else if (!STRICT_ALIGNMENT)
8920 srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8921 src_align);
8922 srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0);
8924 else
8925 srcvar = NULL_TREE;
8927 else
8928 srcvar = NULL_TREE;
8930 if (srcvar == NULL_TREE && destvar == NULL_TREE)
8931 return NULL_TREE;
8933 if (srcvar == NULL_TREE)
8935 STRIP_NOPS (src);
8936 if (src_align >= TYPE_ALIGN (desttype))
8937 srcvar = fold_build2 (MEM_REF, desttype, src, off0);
8938 else
8940 if (STRICT_ALIGNMENT)
8941 return NULL_TREE;
8942 srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8943 src_align);
8944 srcvar = fold_build2 (MEM_REF, srctype, src, off0);
8947 else if (destvar == NULL_TREE)
8949 STRIP_NOPS (dest);
8950 if (dest_align >= TYPE_ALIGN (srctype))
8951 destvar = fold_build2 (MEM_REF, srctype, dest, off0);
8952 else
8954 if (STRICT_ALIGNMENT)
8955 return NULL_TREE;
8956 desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
8957 dest_align);
8958 destvar = fold_build2 (MEM_REF, desttype, dest, off0);
8962 expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar);
8965 if (ignore)
8966 return expr;
8968 if (endp == 0 || endp == 3)
8969 return omit_one_operand_loc (loc, type, dest, expr);
8971 if (expr == len)
8972 expr = NULL_TREE;
8974 if (endp == 2)
8975 len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
8976 ssize_int (1));
8978 dest = fold_build_pointer_plus_loc (loc, dest, len);
8979 dest = fold_convert_loc (loc, type, dest);
8980 if (expr)
8981 dest = omit_one_operand_loc (loc, type, dest, expr);
8982 return dest;
8985 /* Fold function call to builtin strcpy with arguments DEST and SRC.
8986 If LEN is not NULL, it represents the length of the string to be
8987 copied. Return NULL_TREE if no simplification can be made. */
8989 tree
8990 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
8992 tree fn;
8994 if (!validate_arg (dest, POINTER_TYPE)
8995 || !validate_arg (src, POINTER_TYPE))
8996 return NULL_TREE;
8998 /* If SRC and DEST are the same (and not volatile), return DEST. */
8999 if (operand_equal_p (src, dest, 0))
9000 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
9002 if (optimize_function_for_size_p (cfun))
9003 return NULL_TREE;
9005 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9006 if (!fn)
9007 return NULL_TREE;
9009 if (!len)
9011 len = c_strlen (src, 1);
9012 if (! len || TREE_SIDE_EFFECTS (len))
9013 return NULL_TREE;
9016 len = fold_convert_loc (loc, size_type_node, len);
9017 len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
9018 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9019 build_call_expr_loc (loc, fn, 3, dest, src, len));
9022 /* Fold function call to builtin stpcpy with arguments DEST and SRC.
9023 Return NULL_TREE if no simplification can be made. */
9025 static tree
9026 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
9028 tree fn, len, lenp1, call, type;
9030 if (!validate_arg (dest, POINTER_TYPE)
9031 || !validate_arg (src, POINTER_TYPE))
9032 return NULL_TREE;
9034 len = c_strlen (src, 1);
9035 if (!len
9036 || TREE_CODE (len) != INTEGER_CST)
9037 return NULL_TREE;
9039 if (optimize_function_for_size_p (cfun)
9040 /* If length is zero it's small enough. */
9041 && !integer_zerop (len))
9042 return NULL_TREE;
9044 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9045 if (!fn)
9046 return NULL_TREE;
9048 lenp1 = size_binop_loc (loc, PLUS_EXPR,
9049 fold_convert_loc (loc, size_type_node, len),
9050 build_int_cst (size_type_node, 1));
9051 /* We use dest twice in building our expression. Save it from
9052 multiple expansions. */
9053 dest = builtin_save_expr (dest);
9054 call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
9056 type = TREE_TYPE (TREE_TYPE (fndecl));
9057 dest = fold_build_pointer_plus_loc (loc, dest, len);
9058 dest = fold_convert_loc (loc, type, dest);
9059 dest = omit_one_operand_loc (loc, type, dest, call);
9060 return dest;
9063 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9064 If SLEN is not NULL, it represents the length of the source string.
9065 Return NULL_TREE if no simplification can be made. */
9067 tree
9068 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9069 tree src, tree len, tree slen)
9071 tree fn;
9073 if (!validate_arg (dest, POINTER_TYPE)
9074 || !validate_arg (src, POINTER_TYPE)
9075 || !validate_arg (len, INTEGER_TYPE))
9076 return NULL_TREE;
9078 /* If the LEN parameter is zero, return DEST. */
9079 if (integer_zerop (len))
9080 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9082 /* We can't compare slen with len as constants below if len is not a
9083 constant. */
9084 if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9085 return NULL_TREE;
9087 if (!slen)
9088 slen = c_strlen (src, 1);
9090 /* Now, we must be passed a constant src ptr parameter. */
9091 if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9092 return NULL_TREE;
9094 slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
9096 /* We do not support simplification of this case, though we do
9097 support it when expanding trees into RTL. */
9098 /* FIXME: generate a call to __builtin_memset. */
9099 if (tree_int_cst_lt (slen, len))
9100 return NULL_TREE;
9102 /* OK transform into builtin memcpy. */
9103 fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9104 if (!fn)
9105 return NULL_TREE;
9107 len = fold_convert_loc (loc, size_type_node, len);
9108 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9109 build_call_expr_loc (loc, fn, 3, dest, src, len));
9112 /* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
9113 arguments to the call, and TYPE is its return type.
9114 Return NULL_TREE if no simplification can be made. */
9116 static tree
9117 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
9119 if (!validate_arg (arg1, POINTER_TYPE)
9120 || !validate_arg (arg2, INTEGER_TYPE)
9121 || !validate_arg (len, INTEGER_TYPE))
9122 return NULL_TREE;
9123 else
9125 const char *p1;
9127 if (TREE_CODE (arg2) != INTEGER_CST
9128 || !host_integerp (len, 1))
9129 return NULL_TREE;
9131 p1 = c_getstr (arg1);
9132 if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9134 char c;
9135 const char *r;
9136 tree tem;
9138 if (target_char_cast (arg2, &c))
9139 return NULL_TREE;
9141 r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
9143 if (r == NULL)
9144 return build_int_cst (TREE_TYPE (arg1), 0);
9146 tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1);
9147 return fold_convert_loc (loc, type, tem);
9149 return NULL_TREE;
9153 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9154 Return NULL_TREE if no simplification can be made. */
9156 static tree
9157 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9159 const char *p1, *p2;
9161 if (!validate_arg (arg1, POINTER_TYPE)
9162 || !validate_arg (arg2, POINTER_TYPE)
9163 || !validate_arg (len, INTEGER_TYPE))
9164 return NULL_TREE;
9166 /* If the LEN parameter is zero, return zero. */
9167 if (integer_zerop (len))
9168 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9169 arg1, arg2);
9171 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9172 if (operand_equal_p (arg1, arg2, 0))
9173 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9175 p1 = c_getstr (arg1);
9176 p2 = c_getstr (arg2);
9178 /* If all arguments are constant, and the value of len is not greater
9179 than the lengths of arg1 and arg2, evaluate at compile-time. */
9180 if (host_integerp (len, 1) && p1 && p2
9181 && compare_tree_int (len, strlen (p1) + 1) <= 0
9182 && compare_tree_int (len, strlen (p2) + 1) <= 0)
9184 const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9186 if (r > 0)
9187 return integer_one_node;
9188 else if (r < 0)
9189 return integer_minus_one_node;
9190 else
9191 return integer_zero_node;
9194 /* If len parameter is one, return an expression corresponding to
9195 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9196 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9198 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9199 tree cst_uchar_ptr_node
9200 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9202 tree ind1
9203 = fold_convert_loc (loc, integer_type_node,
9204 build1 (INDIRECT_REF, cst_uchar_node,
9205 fold_convert_loc (loc,
9206 cst_uchar_ptr_node,
9207 arg1)));
9208 tree ind2
9209 = fold_convert_loc (loc, integer_type_node,
9210 build1 (INDIRECT_REF, cst_uchar_node,
9211 fold_convert_loc (loc,
9212 cst_uchar_ptr_node,
9213 arg2)));
9214 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9217 return NULL_TREE;
9220 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9221 Return NULL_TREE if no simplification can be made. */
9223 static tree
9224 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9226 const char *p1, *p2;
9228 if (!validate_arg (arg1, POINTER_TYPE)
9229 || !validate_arg (arg2, POINTER_TYPE))
9230 return NULL_TREE;
9232 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9233 if (operand_equal_p (arg1, arg2, 0))
9234 return integer_zero_node;
9236 p1 = c_getstr (arg1);
9237 p2 = c_getstr (arg2);
9239 if (p1 && p2)
9241 const int i = strcmp (p1, p2);
9242 if (i < 0)
9243 return integer_minus_one_node;
9244 else if (i > 0)
9245 return integer_one_node;
9246 else
9247 return integer_zero_node;
9250 /* If the second arg is "", return *(const unsigned char*)arg1. */
9251 if (p2 && *p2 == '\0')
9253 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9254 tree cst_uchar_ptr_node
9255 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9257 return fold_convert_loc (loc, integer_type_node,
9258 build1 (INDIRECT_REF, cst_uchar_node,
9259 fold_convert_loc (loc,
9260 cst_uchar_ptr_node,
9261 arg1)));
9264 /* If the first arg is "", return -*(const unsigned char*)arg2. */
9265 if (p1 && *p1 == '\0')
9267 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9268 tree cst_uchar_ptr_node
9269 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9271 tree temp
9272 = fold_convert_loc (loc, integer_type_node,
9273 build1 (INDIRECT_REF, cst_uchar_node,
9274 fold_convert_loc (loc,
9275 cst_uchar_ptr_node,
9276 arg2)));
9277 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9280 return NULL_TREE;
9283 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9284 Return NULL_TREE if no simplification can be made. */
9286 static tree
9287 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9289 const char *p1, *p2;
9291 if (!validate_arg (arg1, POINTER_TYPE)
9292 || !validate_arg (arg2, POINTER_TYPE)
9293 || !validate_arg (len, INTEGER_TYPE))
9294 return NULL_TREE;
9296 /* If the LEN parameter is zero, return zero. */
9297 if (integer_zerop (len))
9298 return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9299 arg1, arg2);
9301 /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
9302 if (operand_equal_p (arg1, arg2, 0))
9303 return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9305 p1 = c_getstr (arg1);
9306 p2 = c_getstr (arg2);
9308 if (host_integerp (len, 1) && p1 && p2)
9310 const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9311 if (i > 0)
9312 return integer_one_node;
9313 else if (i < 0)
9314 return integer_minus_one_node;
9315 else
9316 return integer_zero_node;
9319 /* If the second arg is "", and the length is greater than zero,
9320 return *(const unsigned char*)arg1. */
9321 if (p2 && *p2 == '\0'
9322 && TREE_CODE (len) == INTEGER_CST
9323 && tree_int_cst_sgn (len) == 1)
9325 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9326 tree cst_uchar_ptr_node
9327 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9329 return fold_convert_loc (loc, integer_type_node,
9330 build1 (INDIRECT_REF, cst_uchar_node,
9331 fold_convert_loc (loc,
9332 cst_uchar_ptr_node,
9333 arg1)));
9336 /* If the first arg is "", and the length is greater than zero,
9337 return -*(const unsigned char*)arg2. */
9338 if (p1 && *p1 == '\0'
9339 && TREE_CODE (len) == INTEGER_CST
9340 && tree_int_cst_sgn (len) == 1)
9342 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9343 tree cst_uchar_ptr_node
9344 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9346 tree temp = fold_convert_loc (loc, integer_type_node,
9347 build1 (INDIRECT_REF, cst_uchar_node,
9348 fold_convert_loc (loc,
9349 cst_uchar_ptr_node,
9350 arg2)));
9351 return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9354 /* If len parameter is one, return an expression corresponding to
9355 (*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
9356 if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9358 tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9359 tree cst_uchar_ptr_node
9360 = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9362 tree ind1 = fold_convert_loc (loc, integer_type_node,
9363 build1 (INDIRECT_REF, cst_uchar_node,
9364 fold_convert_loc (loc,
9365 cst_uchar_ptr_node,
9366 arg1)));
9367 tree ind2 = fold_convert_loc (loc, integer_type_node,
9368 build1 (INDIRECT_REF, cst_uchar_node,
9369 fold_convert_loc (loc,
9370 cst_uchar_ptr_node,
9371 arg2)));
9372 return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9375 return NULL_TREE;
9378 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9379 ARG. Return NULL_TREE if no simplification can be made. */
9381 static tree
9382 fold_builtin_signbit (location_t loc, tree arg, tree type)
9384 if (!validate_arg (arg, REAL_TYPE))
9385 return NULL_TREE;
9387 /* If ARG is a compile-time constant, determine the result. */
9388 if (TREE_CODE (arg) == REAL_CST
9389 && !TREE_OVERFLOW (arg))
9391 REAL_VALUE_TYPE c;
9393 c = TREE_REAL_CST (arg);
9394 return (REAL_VALUE_NEGATIVE (c)
9395 ? build_one_cst (type)
9396 : build_zero_cst (type));
9399 /* If ARG is non-negative, the result is always zero. */
9400 if (tree_expr_nonnegative_p (arg))
9401 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9403 /* If ARG's format doesn't have signed zeros, return "arg < 0.0". */
9404 if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9405 return fold_convert (type,
9406 fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
9407 build_real (TREE_TYPE (arg), dconst0)));
9409 return NULL_TREE;
9412 /* Fold function call to builtin copysign, copysignf or copysignl with
9413 arguments ARG1 and ARG2. Return NULL_TREE if no simplification can
9414 be made. */
9416 static tree
9417 fold_builtin_copysign (location_t loc, tree fndecl,
9418 tree arg1, tree arg2, tree type)
9420 tree tem;
9422 if (!validate_arg (arg1, REAL_TYPE)
9423 || !validate_arg (arg2, REAL_TYPE))
9424 return NULL_TREE;
9426 /* copysign(X,X) is X. */
9427 if (operand_equal_p (arg1, arg2, 0))
9428 return fold_convert_loc (loc, type, arg1);
9430 /* If ARG1 and ARG2 are compile-time constants, determine the result. */
9431 if (TREE_CODE (arg1) == REAL_CST
9432 && TREE_CODE (arg2) == REAL_CST
9433 && !TREE_OVERFLOW (arg1)
9434 && !TREE_OVERFLOW (arg2))
9436 REAL_VALUE_TYPE c1, c2;
9438 c1 = TREE_REAL_CST (arg1);
9439 c2 = TREE_REAL_CST (arg2);
9440 /* c1.sign := c2.sign. */
9441 real_copysign (&c1, &c2);
9442 return build_real (type, c1);
9445 /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9446 Remember to evaluate Y for side-effects. */
9447 if (tree_expr_nonnegative_p (arg2))
9448 return omit_one_operand_loc (loc, type,
9449 fold_build1_loc (loc, ABS_EXPR, type, arg1),
9450 arg2);
9452 /* Strip sign changing operations for the first argument. */
9453 tem = fold_strip_sign_ops (arg1);
9454 if (tem)
9455 return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9457 return NULL_TREE;
9460 /* Fold a call to builtin isascii with argument ARG. */
9462 static tree
9463 fold_builtin_isascii (location_t loc, tree arg)
9465 if (!validate_arg (arg, INTEGER_TYPE))
9466 return NULL_TREE;
9467 else
9469 /* Transform isascii(c) -> ((c & ~0x7f) == 0). */
9470 arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9471 build_int_cst (integer_type_node,
9472 ~ (unsigned HOST_WIDE_INT) 0x7f));
9473 return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9474 arg, integer_zero_node);
9478 /* Fold a call to builtin toascii with argument ARG. */
9480 static tree
9481 fold_builtin_toascii (location_t loc, tree arg)
9483 if (!validate_arg (arg, INTEGER_TYPE))
9484 return NULL_TREE;
9486 /* Transform toascii(c) -> (c & 0x7f). */
9487 return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9488 build_int_cst (integer_type_node, 0x7f));
9491 /* Fold a call to builtin isdigit with argument ARG. */
9493 static tree
9494 fold_builtin_isdigit (location_t loc, tree arg)
9496 if (!validate_arg (arg, INTEGER_TYPE))
9497 return NULL_TREE;
9498 else
9500 /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9. */
9501 /* According to the C standard, isdigit is unaffected by locale.
9502 However, it definitely is affected by the target character set. */
9503 unsigned HOST_WIDE_INT target_digit0
9504 = lang_hooks.to_target_charset ('0');
9506 if (target_digit0 == 0)
9507 return NULL_TREE;
9509 arg = fold_convert_loc (loc, unsigned_type_node, arg);
9510 arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9511 build_int_cst (unsigned_type_node, target_digit0));
9512 return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9513 build_int_cst (unsigned_type_node, 9));
9517 /* Fold a call to fabs, fabsf or fabsl with argument ARG. */
9519 static tree
9520 fold_builtin_fabs (location_t loc, tree arg, tree type)
9522 if (!validate_arg (arg, REAL_TYPE))
9523 return NULL_TREE;
9525 arg = fold_convert_loc (loc, type, arg);
9526 if (TREE_CODE (arg) == REAL_CST)
9527 return fold_abs_const (arg, type);
9528 return fold_build1_loc (loc, ABS_EXPR, type, arg);
9531 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG. */
9533 static tree
9534 fold_builtin_abs (location_t loc, tree arg, tree type)
9536 if (!validate_arg (arg, INTEGER_TYPE))
9537 return NULL_TREE;
9539 arg = fold_convert_loc (loc, type, arg);
9540 if (TREE_CODE (arg) == INTEGER_CST)
9541 return fold_abs_const (arg, type);
9542 return fold_build1_loc (loc, ABS_EXPR, type, arg);
9545 /* Fold a fma operation with arguments ARG[012]. */
9547 tree
9548 fold_fma (location_t loc ATTRIBUTE_UNUSED,
9549 tree type, tree arg0, tree arg1, tree arg2)
9551 if (TREE_CODE (arg0) == REAL_CST
9552 && TREE_CODE (arg1) == REAL_CST
9553 && TREE_CODE (arg2) == REAL_CST)
9554 return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
9556 return NULL_TREE;
9559 /* Fold a call to fma, fmaf, or fmal with arguments ARG[012]. */
9561 static tree
9562 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
9564 if (validate_arg (arg0, REAL_TYPE)
9565 && validate_arg(arg1, REAL_TYPE)
9566 && validate_arg(arg2, REAL_TYPE))
9568 tree tem = fold_fma (loc, type, arg0, arg1, arg2);
9569 if (tem)
9570 return tem;
9572 /* ??? Only expand to FMA_EXPR if it's directly supported. */
9573 if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
9574 return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2);
9576 return NULL_TREE;
9579 /* Fold a call to builtin fmin or fmax. */
9581 static tree
9582 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9583 tree type, bool max)
9585 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9587 /* Calculate the result when the argument is a constant. */
9588 tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9590 if (res)
9591 return res;
9593 /* If either argument is NaN, return the other one. Avoid the
9594 transformation if we get (and honor) a signalling NaN. Using
9595 omit_one_operand() ensures we create a non-lvalue. */
9596 if (TREE_CODE (arg0) == REAL_CST
9597 && real_isnan (&TREE_REAL_CST (arg0))
9598 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9599 || ! TREE_REAL_CST (arg0).signalling))
9600 return omit_one_operand_loc (loc, type, arg1, arg0);
9601 if (TREE_CODE (arg1) == REAL_CST
9602 && real_isnan (&TREE_REAL_CST (arg1))
9603 && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9604 || ! TREE_REAL_CST (arg1).signalling))
9605 return omit_one_operand_loc (loc, type, arg0, arg1);
9607 /* Transform fmin/fmax(x,x) -> x. */
9608 if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9609 return omit_one_operand_loc (loc, type, arg0, arg1);
9611 /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR. C99 requires these
9612 functions to return the numeric arg if the other one is NaN.
9613 These tree codes don't honor that, so only transform if
9614 -ffinite-math-only is set. C99 doesn't require -0.0 to be
9615 handled, so we don't have to worry about it either. */
9616 if (flag_finite_math_only)
9617 return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9618 fold_convert_loc (loc, type, arg0),
9619 fold_convert_loc (loc, type, arg1));
9621 return NULL_TREE;
9624 /* Fold a call to builtin carg(a+bi) -> atan2(b,a). */
9626 static tree
9627 fold_builtin_carg (location_t loc, tree arg, tree type)
9629 if (validate_arg (arg, COMPLEX_TYPE)
9630 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9632 tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9634 if (atan2_fn)
9636 tree new_arg = builtin_save_expr (arg);
9637 tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9638 tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9639 return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9643 return NULL_TREE;
9646 /* Fold a call to builtin logb/ilogb. */
9648 static tree
9649 fold_builtin_logb (location_t loc, tree arg, tree rettype)
9651 if (! validate_arg (arg, REAL_TYPE))
9652 return NULL_TREE;
9654 STRIP_NOPS (arg);
9656 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9658 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9660 switch (value->cl)
9662 case rvc_nan:
9663 case rvc_inf:
9664 /* If arg is Inf or NaN and we're logb, return it. */
9665 if (TREE_CODE (rettype) == REAL_TYPE)
9666 return fold_convert_loc (loc, rettype, arg);
9667 /* Fall through... */
9668 case rvc_zero:
9669 /* Zero may set errno and/or raise an exception for logb, also
9670 for ilogb we don't know FP_ILOGB0. */
9671 return NULL_TREE;
9672 case rvc_normal:
9673 /* For normal numbers, proceed iff radix == 2. In GCC,
9674 normalized significands are in the range [0.5, 1.0). We
9675 want the exponent as if they were [1.0, 2.0) so get the
9676 exponent and subtract 1. */
9677 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9678 return fold_convert_loc (loc, rettype,
9679 build_int_cst (integer_type_node,
9680 REAL_EXP (value)-1));
9681 break;
9685 return NULL_TREE;
9688 /* Fold a call to builtin significand, if radix == 2. */
9690 static tree
9691 fold_builtin_significand (location_t loc, tree arg, tree rettype)
9693 if (! validate_arg (arg, REAL_TYPE))
9694 return NULL_TREE;
9696 STRIP_NOPS (arg);
9698 if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9700 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9702 switch (value->cl)
9704 case rvc_zero:
9705 case rvc_nan:
9706 case rvc_inf:
9707 /* If arg is +-0, +-Inf or +-NaN, then return it. */
9708 return fold_convert_loc (loc, rettype, arg);
9709 case rvc_normal:
9710 /* For normal numbers, proceed iff radix == 2. */
9711 if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9713 REAL_VALUE_TYPE result = *value;
9714 /* In GCC, normalized significands are in the range [0.5,
9715 1.0). We want them to be [1.0, 2.0) so set the
9716 exponent to 1. */
9717 SET_REAL_EXP (&result, 1);
9718 return build_real (rettype, result);
9720 break;
9724 return NULL_TREE;
9727 /* Fold a call to builtin frexp, we can assume the base is 2. */
9729 static tree
9730 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9732 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9733 return NULL_TREE;
9735 STRIP_NOPS (arg0);
9737 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9738 return NULL_TREE;
9740 arg1 = build_fold_indirect_ref_loc (loc, arg1);
9742 /* Proceed if a valid pointer type was passed in. */
9743 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9745 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9746 tree frac, exp;
9748 switch (value->cl)
9750 case rvc_zero:
9751 /* For +-0, return (*exp = 0, +-0). */
9752 exp = integer_zero_node;
9753 frac = arg0;
9754 break;
9755 case rvc_nan:
9756 case rvc_inf:
9757 /* For +-NaN or +-Inf, *exp is unspecified, return arg0. */
9758 return omit_one_operand_loc (loc, rettype, arg0, arg1);
9759 case rvc_normal:
9761 /* Since the frexp function always expects base 2, and in
9762 GCC normalized significands are already in the range
9763 [0.5, 1.0), we have exactly what frexp wants. */
9764 REAL_VALUE_TYPE frac_rvt = *value;
9765 SET_REAL_EXP (&frac_rvt, 0);
9766 frac = build_real (rettype, frac_rvt);
9767 exp = build_int_cst (integer_type_node, REAL_EXP (value));
9769 break;
9770 default:
9771 gcc_unreachable ();
9774 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9775 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9776 TREE_SIDE_EFFECTS (arg1) = 1;
9777 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9780 return NULL_TREE;
9783 /* Fold a call to builtin ldexp or scalbn/scalbln. If LDEXP is true
9784 then we can assume the base is two. If it's false, then we have to
9785 check the mode of the TYPE parameter in certain cases. */
9787 static tree
9788 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9789 tree type, bool ldexp)
9791 if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9793 STRIP_NOPS (arg0);
9794 STRIP_NOPS (arg1);
9796 /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0. */
9797 if (real_zerop (arg0) || integer_zerop (arg1)
9798 || (TREE_CODE (arg0) == REAL_CST
9799 && !real_isfinite (&TREE_REAL_CST (arg0))))
9800 return omit_one_operand_loc (loc, type, arg0, arg1);
9802 /* If both arguments are constant, then try to evaluate it. */
9803 if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9804 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9805 && host_integerp (arg1, 0))
9807 /* Bound the maximum adjustment to twice the range of the
9808 mode's valid exponents. Use abs to ensure the range is
9809 positive as a sanity check. */
9810 const long max_exp_adj = 2 *
9811 labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9812 - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9814 /* Get the user-requested adjustment. */
9815 const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9817 /* The requested adjustment must be inside this range. This
9818 is a preliminary cap to avoid things like overflow, we
9819 may still fail to compute the result for other reasons. */
9820 if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9822 REAL_VALUE_TYPE initial_result;
9824 real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9826 /* Ensure we didn't overflow. */
9827 if (! real_isinf (&initial_result))
9829 const REAL_VALUE_TYPE trunc_result
9830 = real_value_truncate (TYPE_MODE (type), initial_result);
9832 /* Only proceed if the target mode can hold the
9833 resulting value. */
9834 if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9835 return build_real (type, trunc_result);
9841 return NULL_TREE;
9844 /* Fold a call to builtin modf. */
9846 static tree
9847 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9849 if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9850 return NULL_TREE;
9852 STRIP_NOPS (arg0);
9854 if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9855 return NULL_TREE;
9857 arg1 = build_fold_indirect_ref_loc (loc, arg1);
9859 /* Proceed if a valid pointer type was passed in. */
9860 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9862 const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9863 REAL_VALUE_TYPE trunc, frac;
9865 switch (value->cl)
9867 case rvc_nan:
9868 case rvc_zero:
9869 /* For +-NaN or +-0, return (*arg1 = arg0, arg0). */
9870 trunc = frac = *value;
9871 break;
9872 case rvc_inf:
9873 /* For +-Inf, return (*arg1 = arg0, +-0). */
9874 frac = dconst0;
9875 frac.sign = value->sign;
9876 trunc = *value;
9877 break;
9878 case rvc_normal:
9879 /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)). */
9880 real_trunc (&trunc, VOIDmode, value);
9881 real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9882 /* If the original number was negative and already
9883 integral, then the fractional part is -0.0. */
9884 if (value->sign && frac.cl == rvc_zero)
9885 frac.sign = value->sign;
9886 break;
9889 /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9890 arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9891 build_real (rettype, trunc));
9892 TREE_SIDE_EFFECTS (arg1) = 1;
9893 return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9894 build_real (rettype, frac));
9897 return NULL_TREE;
9900 /* Given a location LOC, an interclass builtin function decl FNDECL
9901 and its single argument ARG, return an folded expression computing
9902 the same, or NULL_TREE if we either couldn't or didn't want to fold
9903 (the latter happen if there's an RTL instruction available). */
9905 static tree
9906 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9908 enum machine_mode mode;
9910 if (!validate_arg (arg, REAL_TYPE))
9911 return NULL_TREE;
9913 if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9914 return NULL_TREE;
9916 mode = TYPE_MODE (TREE_TYPE (arg));
9918 /* If there is no optab, try generic code. */
9919 switch (DECL_FUNCTION_CODE (fndecl))
9921 tree result;
9923 CASE_FLT_FN (BUILT_IN_ISINF):
9925 /* isinf(x) -> isgreater(fabs(x),DBL_MAX). */
9926 tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER);
9927 tree const type = TREE_TYPE (arg);
9928 REAL_VALUE_TYPE r;
9929 char buf[128];
9931 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9932 real_from_string (&r, buf);
9933 result = build_call_expr (isgr_fn, 2,
9934 fold_build1_loc (loc, ABS_EXPR, type, arg),
9935 build_real (type, r));
9936 return result;
9938 CASE_FLT_FN (BUILT_IN_FINITE):
9939 case BUILT_IN_ISFINITE:
9941 /* isfinite(x) -> islessequal(fabs(x),DBL_MAX). */
9942 tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9943 tree const type = TREE_TYPE (arg);
9944 REAL_VALUE_TYPE r;
9945 char buf[128];
9947 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9948 real_from_string (&r, buf);
9949 result = build_call_expr (isle_fn, 2,
9950 fold_build1_loc (loc, ABS_EXPR, type, arg),
9951 build_real (type, r));
9952 /*result = fold_build2_loc (loc, UNGT_EXPR,
9953 TREE_TYPE (TREE_TYPE (fndecl)),
9954 fold_build1_loc (loc, ABS_EXPR, type, arg),
9955 build_real (type, r));
9956 result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9957 TREE_TYPE (TREE_TYPE (fndecl)),
9958 result);*/
9959 return result;
9961 case BUILT_IN_ISNORMAL:
9963 /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9964 islessequal(fabs(x),DBL_MAX). */
9965 tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9966 tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL);
9967 tree const type = TREE_TYPE (arg);
9968 REAL_VALUE_TYPE rmax, rmin;
9969 char buf[128];
9971 get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9972 real_from_string (&rmax, buf);
9973 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9974 real_from_string (&rmin, buf);
9975 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9976 result = build_call_expr (isle_fn, 2, arg,
9977 build_real (type, rmax));
9978 result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9979 build_call_expr (isge_fn, 2, arg,
9980 build_real (type, rmin)));
9981 return result;
9983 default:
9984 break;
9987 return NULL_TREE;
9990 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9991 ARG is the argument for the call. */
9993 static tree
9994 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
9996 tree type = TREE_TYPE (TREE_TYPE (fndecl));
9997 REAL_VALUE_TYPE r;
9999 if (!validate_arg (arg, REAL_TYPE))
10000 return NULL_TREE;
10002 switch (builtin_index)
10004 case BUILT_IN_ISINF:
10005 if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10006 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10008 if (TREE_CODE (arg) == REAL_CST)
10010 r = TREE_REAL_CST (arg);
10011 if (real_isinf (&r))
10012 return real_compare (GT_EXPR, &r, &dconst0)
10013 ? integer_one_node : integer_minus_one_node;
10014 else
10015 return integer_zero_node;
10018 return NULL_TREE;
10020 case BUILT_IN_ISINF_SIGN:
10022 /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10023 /* In a boolean context, GCC will fold the inner COND_EXPR to
10024 1. So e.g. "if (isinf_sign(x))" would be folded to just
10025 "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10026 tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10027 tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF);
10028 tree tmp = NULL_TREE;
10030 arg = builtin_save_expr (arg);
10032 if (signbit_fn && isinf_fn)
10034 tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10035 tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
10037 signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10038 signbit_call, integer_zero_node);
10039 isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10040 isinf_call, integer_zero_node);
10042 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
10043 integer_minus_one_node, integer_one_node);
10044 tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10045 isinf_call, tmp,
10046 integer_zero_node);
10049 return tmp;
10052 case BUILT_IN_ISFINITE:
10053 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10054 && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10055 return omit_one_operand_loc (loc, type, integer_one_node, arg);
10057 if (TREE_CODE (arg) == REAL_CST)
10059 r = TREE_REAL_CST (arg);
10060 return real_isfinite (&r) ? integer_one_node : integer_zero_node;
10063 return NULL_TREE;
10065 case BUILT_IN_ISNAN:
10066 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
10067 return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10069 if (TREE_CODE (arg) == REAL_CST)
10071 r = TREE_REAL_CST (arg);
10072 return real_isnan (&r) ? integer_one_node : integer_zero_node;
10075 arg = builtin_save_expr (arg);
10076 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
10078 default:
10079 gcc_unreachable ();
10083 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10084 This builtin will generate code to return the appropriate floating
10085 point classification depending on the value of the floating point
10086 number passed in. The possible return values must be supplied as
10087 int arguments to the call in the following order: FP_NAN, FP_INFINITE,
10088 FP_NORMAL, FP_SUBNORMAL and FP_ZERO. The ellipses is for exactly
10089 one floating point argument which is "type generic". */
10091 static tree
10092 fold_builtin_fpclassify (location_t loc, tree exp)
10094 tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10095 arg, type, res, tmp;
10096 enum machine_mode mode;
10097 REAL_VALUE_TYPE r;
10098 char buf[128];
10100 /* Verify the required arguments in the original call. */
10101 if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10102 INTEGER_TYPE, INTEGER_TYPE,
10103 INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10104 return NULL_TREE;
10106 fp_nan = CALL_EXPR_ARG (exp, 0);
10107 fp_infinite = CALL_EXPR_ARG (exp, 1);
10108 fp_normal = CALL_EXPR_ARG (exp, 2);
10109 fp_subnormal = CALL_EXPR_ARG (exp, 3);
10110 fp_zero = CALL_EXPR_ARG (exp, 4);
10111 arg = CALL_EXPR_ARG (exp, 5);
10112 type = TREE_TYPE (arg);
10113 mode = TYPE_MODE (type);
10114 arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10116 /* fpclassify(x) ->
10117 isnan(x) ? FP_NAN :
10118 (fabs(x) == Inf ? FP_INFINITE :
10119 (fabs(x) >= DBL_MIN ? FP_NORMAL :
10120 (x == 0 ? FP_ZERO : FP_SUBNORMAL))). */
10122 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10123 build_real (type, dconst0));
10124 res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10125 tmp, fp_zero, fp_subnormal);
10127 sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10128 real_from_string (&r, buf);
10129 tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10130 arg, build_real (type, r));
10131 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
10133 if (HONOR_INFINITIES (mode))
10135 real_inf (&r);
10136 tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10137 build_real (type, r));
10138 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10139 fp_infinite, res);
10142 if (HONOR_NANS (mode))
10144 tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10145 res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
10148 return res;
10151 /* Fold a call to an unordered comparison function such as
10152 __builtin_isgreater(). FNDECL is the FUNCTION_DECL for the function
10153 being called and ARG0 and ARG1 are the arguments for the call.
10154 UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10155 the opposite of the desired result. UNORDERED_CODE is used
10156 for modes that can hold NaNs and ORDERED_CODE is used for
10157 the rest. */
10159 static tree
10160 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
10161 enum tree_code unordered_code,
10162 enum tree_code ordered_code)
10164 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10165 enum tree_code code;
10166 tree type0, type1;
10167 enum tree_code code0, code1;
10168 tree cmp_type = NULL_TREE;
10170 type0 = TREE_TYPE (arg0);
10171 type1 = TREE_TYPE (arg1);
10173 code0 = TREE_CODE (type0);
10174 code1 = TREE_CODE (type1);
10176 if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10177 /* Choose the wider of two real types. */
10178 cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10179 ? type0 : type1;
10180 else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10181 cmp_type = type0;
10182 else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10183 cmp_type = type1;
10185 arg0 = fold_convert_loc (loc, cmp_type, arg0);
10186 arg1 = fold_convert_loc (loc, cmp_type, arg1);
10188 if (unordered_code == UNORDERED_EXPR)
10190 if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10191 return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10192 return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
10195 code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10196 : ordered_code;
10197 return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10198 fold_build2_loc (loc, code, type, arg0, arg1));
10201 /* Fold a call to built-in function FNDECL with 0 arguments.
10202 IGNORE is true if the result of the function call is ignored. This
10203 function returns NULL_TREE if no simplification was possible. */
10205 static tree
10206 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10208 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10209 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10210 switch (fcode)
10212 CASE_FLT_FN (BUILT_IN_INF):
10213 case BUILT_IN_INFD32:
10214 case BUILT_IN_INFD64:
10215 case BUILT_IN_INFD128:
10216 return fold_builtin_inf (loc, type, true);
10218 CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10219 return fold_builtin_inf (loc, type, false);
10221 case BUILT_IN_CLASSIFY_TYPE:
10222 return fold_builtin_classify_type (NULL_TREE);
10224 default:
10225 break;
10227 return NULL_TREE;
10230 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10231 IGNORE is true if the result of the function call is ignored. This
10232 function returns NULL_TREE if no simplification was possible. */
10234 static tree
10235 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
10237 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10238 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10239 switch (fcode)
10241 case BUILT_IN_CONSTANT_P:
10243 tree val = fold_builtin_constant_p (arg0);
10245 /* Gimplification will pull the CALL_EXPR for the builtin out of
10246 an if condition. When not optimizing, we'll not CSE it back.
10247 To avoid link error types of regressions, return false now. */
10248 if (!val && !optimize)
10249 val = integer_zero_node;
10251 return val;
10254 case BUILT_IN_CLASSIFY_TYPE:
10255 return fold_builtin_classify_type (arg0);
10257 case BUILT_IN_STRLEN:
10258 return fold_builtin_strlen (loc, type, arg0);
10260 CASE_FLT_FN (BUILT_IN_FABS):
10261 return fold_builtin_fabs (loc, arg0, type);
10263 case BUILT_IN_ABS:
10264 case BUILT_IN_LABS:
10265 case BUILT_IN_LLABS:
10266 case BUILT_IN_IMAXABS:
10267 return fold_builtin_abs (loc, arg0, type);
10269 CASE_FLT_FN (BUILT_IN_CONJ):
10270 if (validate_arg (arg0, COMPLEX_TYPE)
10271 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10272 return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
10273 break;
10275 CASE_FLT_FN (BUILT_IN_CREAL):
10276 if (validate_arg (arg0, COMPLEX_TYPE)
10277 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10278 return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10279 break;
10281 CASE_FLT_FN (BUILT_IN_CIMAG):
10282 if (validate_arg (arg0, COMPLEX_TYPE)
10283 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10284 return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10285 break;
10287 CASE_FLT_FN (BUILT_IN_CCOS):
10288 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10290 CASE_FLT_FN (BUILT_IN_CCOSH):
10291 return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10293 CASE_FLT_FN (BUILT_IN_CPROJ):
10294 return fold_builtin_cproj(loc, arg0, type);
10296 CASE_FLT_FN (BUILT_IN_CSIN):
10297 if (validate_arg (arg0, COMPLEX_TYPE)
10298 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10299 return do_mpc_arg1 (arg0, type, mpc_sin);
10300 break;
10302 CASE_FLT_FN (BUILT_IN_CSINH):
10303 if (validate_arg (arg0, COMPLEX_TYPE)
10304 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10305 return do_mpc_arg1 (arg0, type, mpc_sinh);
10306 break;
10308 CASE_FLT_FN (BUILT_IN_CTAN):
10309 if (validate_arg (arg0, COMPLEX_TYPE)
10310 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10311 return do_mpc_arg1 (arg0, type, mpc_tan);
10312 break;
10314 CASE_FLT_FN (BUILT_IN_CTANH):
10315 if (validate_arg (arg0, COMPLEX_TYPE)
10316 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10317 return do_mpc_arg1 (arg0, type, mpc_tanh);
10318 break;
10320 CASE_FLT_FN (BUILT_IN_CLOG):
10321 if (validate_arg (arg0, COMPLEX_TYPE)
10322 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10323 return do_mpc_arg1 (arg0, type, mpc_log);
10324 break;
10326 CASE_FLT_FN (BUILT_IN_CSQRT):
10327 if (validate_arg (arg0, COMPLEX_TYPE)
10328 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10329 return do_mpc_arg1 (arg0, type, mpc_sqrt);
10330 break;
10332 CASE_FLT_FN (BUILT_IN_CASIN):
10333 if (validate_arg (arg0, COMPLEX_TYPE)
10334 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10335 return do_mpc_arg1 (arg0, type, mpc_asin);
10336 break;
10338 CASE_FLT_FN (BUILT_IN_CACOS):
10339 if (validate_arg (arg0, COMPLEX_TYPE)
10340 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10341 return do_mpc_arg1 (arg0, type, mpc_acos);
10342 break;
10344 CASE_FLT_FN (BUILT_IN_CATAN):
10345 if (validate_arg (arg0, COMPLEX_TYPE)
10346 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10347 return do_mpc_arg1 (arg0, type, mpc_atan);
10348 break;
10350 CASE_FLT_FN (BUILT_IN_CASINH):
10351 if (validate_arg (arg0, COMPLEX_TYPE)
10352 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10353 return do_mpc_arg1 (arg0, type, mpc_asinh);
10354 break;
10356 CASE_FLT_FN (BUILT_IN_CACOSH):
10357 if (validate_arg (arg0, COMPLEX_TYPE)
10358 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10359 return do_mpc_arg1 (arg0, type, mpc_acosh);
10360 break;
10362 CASE_FLT_FN (BUILT_IN_CATANH):
10363 if (validate_arg (arg0, COMPLEX_TYPE)
10364 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10365 return do_mpc_arg1 (arg0, type, mpc_atanh);
10366 break;
10368 CASE_FLT_FN (BUILT_IN_CABS):
10369 return fold_builtin_cabs (loc, arg0, type, fndecl);
10371 CASE_FLT_FN (BUILT_IN_CARG):
10372 return fold_builtin_carg (loc, arg0, type);
10374 CASE_FLT_FN (BUILT_IN_SQRT):
10375 return fold_builtin_sqrt (loc, arg0, type);
10377 CASE_FLT_FN (BUILT_IN_CBRT):
10378 return fold_builtin_cbrt (loc, arg0, type);
10380 CASE_FLT_FN (BUILT_IN_ASIN):
10381 if (validate_arg (arg0, REAL_TYPE))
10382 return do_mpfr_arg1 (arg0, type, mpfr_asin,
10383 &dconstm1, &dconst1, true);
10384 break;
10386 CASE_FLT_FN (BUILT_IN_ACOS):
10387 if (validate_arg (arg0, REAL_TYPE))
10388 return do_mpfr_arg1 (arg0, type, mpfr_acos,
10389 &dconstm1, &dconst1, true);
10390 break;
10392 CASE_FLT_FN (BUILT_IN_ATAN):
10393 if (validate_arg (arg0, REAL_TYPE))
10394 return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10395 break;
10397 CASE_FLT_FN (BUILT_IN_ASINH):
10398 if (validate_arg (arg0, REAL_TYPE))
10399 return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10400 break;
10402 CASE_FLT_FN (BUILT_IN_ACOSH):
10403 if (validate_arg (arg0, REAL_TYPE))
10404 return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10405 &dconst1, NULL, true);
10406 break;
10408 CASE_FLT_FN (BUILT_IN_ATANH):
10409 if (validate_arg (arg0, REAL_TYPE))
10410 return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10411 &dconstm1, &dconst1, false);
10412 break;
10414 CASE_FLT_FN (BUILT_IN_SIN):
10415 if (validate_arg (arg0, REAL_TYPE))
10416 return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10417 break;
10419 CASE_FLT_FN (BUILT_IN_COS):
10420 return fold_builtin_cos (loc, arg0, type, fndecl);
10422 CASE_FLT_FN (BUILT_IN_TAN):
10423 return fold_builtin_tan (arg0, type);
10425 CASE_FLT_FN (BUILT_IN_CEXP):
10426 return fold_builtin_cexp (loc, arg0, type);
10428 CASE_FLT_FN (BUILT_IN_CEXPI):
10429 if (validate_arg (arg0, REAL_TYPE))
10430 return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10431 break;
10433 CASE_FLT_FN (BUILT_IN_SINH):
10434 if (validate_arg (arg0, REAL_TYPE))
10435 return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10436 break;
10438 CASE_FLT_FN (BUILT_IN_COSH):
10439 return fold_builtin_cosh (loc, arg0, type, fndecl);
10441 CASE_FLT_FN (BUILT_IN_TANH):
10442 if (validate_arg (arg0, REAL_TYPE))
10443 return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10444 break;
10446 CASE_FLT_FN (BUILT_IN_ERF):
10447 if (validate_arg (arg0, REAL_TYPE))
10448 return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10449 break;
10451 CASE_FLT_FN (BUILT_IN_ERFC):
10452 if (validate_arg (arg0, REAL_TYPE))
10453 return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10454 break;
10456 CASE_FLT_FN (BUILT_IN_TGAMMA):
10457 if (validate_arg (arg0, REAL_TYPE))
10458 return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10459 break;
10461 CASE_FLT_FN (BUILT_IN_EXP):
10462 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10464 CASE_FLT_FN (BUILT_IN_EXP2):
10465 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10467 CASE_FLT_FN (BUILT_IN_EXP10):
10468 CASE_FLT_FN (BUILT_IN_POW10):
10469 return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10471 CASE_FLT_FN (BUILT_IN_EXPM1):
10472 if (validate_arg (arg0, REAL_TYPE))
10473 return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10474 break;
10476 CASE_FLT_FN (BUILT_IN_LOG):
10477 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10479 CASE_FLT_FN (BUILT_IN_LOG2):
10480 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10482 CASE_FLT_FN (BUILT_IN_LOG10):
10483 return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10485 CASE_FLT_FN (BUILT_IN_LOG1P):
10486 if (validate_arg (arg0, REAL_TYPE))
10487 return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10488 &dconstm1, NULL, false);
10489 break;
10491 CASE_FLT_FN (BUILT_IN_J0):
10492 if (validate_arg (arg0, REAL_TYPE))
10493 return do_mpfr_arg1 (arg0, type, mpfr_j0,
10494 NULL, NULL, 0);
10495 break;
10497 CASE_FLT_FN (BUILT_IN_J1):
10498 if (validate_arg (arg0, REAL_TYPE))
10499 return do_mpfr_arg1 (arg0, type, mpfr_j1,
10500 NULL, NULL, 0);
10501 break;
10503 CASE_FLT_FN (BUILT_IN_Y0):
10504 if (validate_arg (arg0, REAL_TYPE))
10505 return do_mpfr_arg1 (arg0, type, mpfr_y0,
10506 &dconst0, NULL, false);
10507 break;
10509 CASE_FLT_FN (BUILT_IN_Y1):
10510 if (validate_arg (arg0, REAL_TYPE))
10511 return do_mpfr_arg1 (arg0, type, mpfr_y1,
10512 &dconst0, NULL, false);
10513 break;
10515 CASE_FLT_FN (BUILT_IN_NAN):
10516 case BUILT_IN_NAND32:
10517 case BUILT_IN_NAND64:
10518 case BUILT_IN_NAND128:
10519 return fold_builtin_nan (arg0, type, true);
10521 CASE_FLT_FN (BUILT_IN_NANS):
10522 return fold_builtin_nan (arg0, type, false);
10524 CASE_FLT_FN (BUILT_IN_FLOOR):
10525 return fold_builtin_floor (loc, fndecl, arg0);
10527 CASE_FLT_FN (BUILT_IN_CEIL):
10528 return fold_builtin_ceil (loc, fndecl, arg0);
10530 CASE_FLT_FN (BUILT_IN_TRUNC):
10531 return fold_builtin_trunc (loc, fndecl, arg0);
10533 CASE_FLT_FN (BUILT_IN_ROUND):
10534 return fold_builtin_round (loc, fndecl, arg0);
10536 CASE_FLT_FN (BUILT_IN_NEARBYINT):
10537 CASE_FLT_FN (BUILT_IN_RINT):
10538 return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10540 CASE_FLT_FN (BUILT_IN_ICEIL):
10541 CASE_FLT_FN (BUILT_IN_LCEIL):
10542 CASE_FLT_FN (BUILT_IN_LLCEIL):
10543 CASE_FLT_FN (BUILT_IN_LFLOOR):
10544 CASE_FLT_FN (BUILT_IN_IFLOOR):
10545 CASE_FLT_FN (BUILT_IN_LLFLOOR):
10546 CASE_FLT_FN (BUILT_IN_IROUND):
10547 CASE_FLT_FN (BUILT_IN_LROUND):
10548 CASE_FLT_FN (BUILT_IN_LLROUND):
10549 return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10551 CASE_FLT_FN (BUILT_IN_IRINT):
10552 CASE_FLT_FN (BUILT_IN_LRINT):
10553 CASE_FLT_FN (BUILT_IN_LLRINT):
10554 return fold_fixed_mathfn (loc, fndecl, arg0);
10556 case BUILT_IN_BSWAP16:
10557 case BUILT_IN_BSWAP32:
10558 case BUILT_IN_BSWAP64:
10559 return fold_builtin_bswap (fndecl, arg0);
10561 CASE_INT_FN (BUILT_IN_FFS):
10562 CASE_INT_FN (BUILT_IN_CLZ):
10563 CASE_INT_FN (BUILT_IN_CTZ):
10564 CASE_INT_FN (BUILT_IN_CLRSB):
10565 CASE_INT_FN (BUILT_IN_POPCOUNT):
10566 CASE_INT_FN (BUILT_IN_PARITY):
10567 return fold_builtin_bitop (fndecl, arg0);
10569 CASE_FLT_FN (BUILT_IN_SIGNBIT):
10570 return fold_builtin_signbit (loc, arg0, type);
10572 CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10573 return fold_builtin_significand (loc, arg0, type);
10575 CASE_FLT_FN (BUILT_IN_ILOGB):
10576 CASE_FLT_FN (BUILT_IN_LOGB):
10577 return fold_builtin_logb (loc, arg0, type);
10579 case BUILT_IN_ISASCII:
10580 return fold_builtin_isascii (loc, arg0);
10582 case BUILT_IN_TOASCII:
10583 return fold_builtin_toascii (loc, arg0);
10585 case BUILT_IN_ISDIGIT:
10586 return fold_builtin_isdigit (loc, arg0);
10588 CASE_FLT_FN (BUILT_IN_FINITE):
10589 case BUILT_IN_FINITED32:
10590 case BUILT_IN_FINITED64:
10591 case BUILT_IN_FINITED128:
10592 case BUILT_IN_ISFINITE:
10594 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10595 if (ret)
10596 return ret;
10597 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10600 CASE_FLT_FN (BUILT_IN_ISINF):
10601 case BUILT_IN_ISINFD32:
10602 case BUILT_IN_ISINFD64:
10603 case BUILT_IN_ISINFD128:
10605 tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10606 if (ret)
10607 return ret;
10608 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10611 case BUILT_IN_ISNORMAL:
10612 return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10614 case BUILT_IN_ISINF_SIGN:
10615 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10617 CASE_FLT_FN (BUILT_IN_ISNAN):
10618 case BUILT_IN_ISNAND32:
10619 case BUILT_IN_ISNAND64:
10620 case BUILT_IN_ISNAND128:
10621 return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10623 case BUILT_IN_PRINTF:
10624 case BUILT_IN_PRINTF_UNLOCKED:
10625 case BUILT_IN_VPRINTF:
10626 return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10628 case BUILT_IN_FREE:
10629 if (integer_zerop (arg0))
10630 return build_empty_stmt (loc);
10631 break;
10633 default:
10634 break;
10637 return NULL_TREE;
10641 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10642 IGNORE is true if the result of the function call is ignored. This
10643 function returns NULL_TREE if no simplification was possible. */
10645 static tree
10646 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10648 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10649 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10651 switch (fcode)
10653 CASE_FLT_FN (BUILT_IN_JN):
10654 if (validate_arg (arg0, INTEGER_TYPE)
10655 && validate_arg (arg1, REAL_TYPE))
10656 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10657 break;
10659 CASE_FLT_FN (BUILT_IN_YN):
10660 if (validate_arg (arg0, INTEGER_TYPE)
10661 && validate_arg (arg1, REAL_TYPE))
10662 return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10663 &dconst0, false);
10664 break;
10666 CASE_FLT_FN (BUILT_IN_DREM):
10667 CASE_FLT_FN (BUILT_IN_REMAINDER):
10668 if (validate_arg (arg0, REAL_TYPE)
10669 && validate_arg(arg1, REAL_TYPE))
10670 return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10671 break;
10673 CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10674 CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10675 if (validate_arg (arg0, REAL_TYPE)
10676 && validate_arg(arg1, POINTER_TYPE))
10677 return do_mpfr_lgamma_r (arg0, arg1, type);
10678 break;
10680 CASE_FLT_FN (BUILT_IN_ATAN2):
10681 if (validate_arg (arg0, REAL_TYPE)
10682 && validate_arg(arg1, REAL_TYPE))
10683 return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10684 break;
10686 CASE_FLT_FN (BUILT_IN_FDIM):
10687 if (validate_arg (arg0, REAL_TYPE)
10688 && validate_arg(arg1, REAL_TYPE))
10689 return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10690 break;
10692 CASE_FLT_FN (BUILT_IN_HYPOT):
10693 return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10695 CASE_FLT_FN (BUILT_IN_CPOW):
10696 if (validate_arg (arg0, COMPLEX_TYPE)
10697 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10698 && validate_arg (arg1, COMPLEX_TYPE)
10699 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10700 return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10701 break;
10703 CASE_FLT_FN (BUILT_IN_LDEXP):
10704 return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10705 CASE_FLT_FN (BUILT_IN_SCALBN):
10706 CASE_FLT_FN (BUILT_IN_SCALBLN):
10707 return fold_builtin_load_exponent (loc, arg0, arg1,
10708 type, /*ldexp=*/false);
10710 CASE_FLT_FN (BUILT_IN_FREXP):
10711 return fold_builtin_frexp (loc, arg0, arg1, type);
10713 CASE_FLT_FN (BUILT_IN_MODF):
10714 return fold_builtin_modf (loc, arg0, arg1, type);
10716 case BUILT_IN_BZERO:
10717 return fold_builtin_bzero (loc, arg0, arg1, ignore);
10719 case BUILT_IN_FPUTS:
10720 return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10722 case BUILT_IN_FPUTS_UNLOCKED:
10723 return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10725 case BUILT_IN_STRSTR:
10726 return fold_builtin_strstr (loc, arg0, arg1, type);
10728 case BUILT_IN_STRCAT:
10729 return fold_builtin_strcat (loc, arg0, arg1);
10731 case BUILT_IN_STRSPN:
10732 return fold_builtin_strspn (loc, arg0, arg1);
10734 case BUILT_IN_STRCSPN:
10735 return fold_builtin_strcspn (loc, arg0, arg1);
10737 case BUILT_IN_STRCHR:
10738 case BUILT_IN_INDEX:
10739 return fold_builtin_strchr (loc, arg0, arg1, type);
10741 case BUILT_IN_STRRCHR:
10742 case BUILT_IN_RINDEX:
10743 return fold_builtin_strrchr (loc, arg0, arg1, type);
10745 case BUILT_IN_STRCPY:
10746 return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10748 case BUILT_IN_STPCPY:
10749 if (ignore)
10751 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
10752 if (!fn)
10753 break;
10755 return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10757 else
10758 return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10759 break;
10761 case BUILT_IN_STRCMP:
10762 return fold_builtin_strcmp (loc, arg0, arg1);
10764 case BUILT_IN_STRPBRK:
10765 return fold_builtin_strpbrk (loc, arg0, arg1, type);
10767 case BUILT_IN_EXPECT:
10768 return fold_builtin_expect (loc, arg0, arg1);
10770 CASE_FLT_FN (BUILT_IN_POW):
10771 return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10773 CASE_FLT_FN (BUILT_IN_POWI):
10774 return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10776 CASE_FLT_FN (BUILT_IN_COPYSIGN):
10777 return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10779 CASE_FLT_FN (BUILT_IN_FMIN):
10780 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10782 CASE_FLT_FN (BUILT_IN_FMAX):
10783 return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10785 case BUILT_IN_ISGREATER:
10786 return fold_builtin_unordered_cmp (loc, fndecl,
10787 arg0, arg1, UNLE_EXPR, LE_EXPR);
10788 case BUILT_IN_ISGREATEREQUAL:
10789 return fold_builtin_unordered_cmp (loc, fndecl,
10790 arg0, arg1, UNLT_EXPR, LT_EXPR);
10791 case BUILT_IN_ISLESS:
10792 return fold_builtin_unordered_cmp (loc, fndecl,
10793 arg0, arg1, UNGE_EXPR, GE_EXPR);
10794 case BUILT_IN_ISLESSEQUAL:
10795 return fold_builtin_unordered_cmp (loc, fndecl,
10796 arg0, arg1, UNGT_EXPR, GT_EXPR);
10797 case BUILT_IN_ISLESSGREATER:
10798 return fold_builtin_unordered_cmp (loc, fndecl,
10799 arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10800 case BUILT_IN_ISUNORDERED:
10801 return fold_builtin_unordered_cmp (loc, fndecl,
10802 arg0, arg1, UNORDERED_EXPR,
10803 NOP_EXPR);
10805 /* We do the folding for va_start in the expander. */
10806 case BUILT_IN_VA_START:
10807 break;
10809 case BUILT_IN_SPRINTF:
10810 return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10812 case BUILT_IN_OBJECT_SIZE:
10813 return fold_builtin_object_size (arg0, arg1);
10815 case BUILT_IN_PRINTF:
10816 case BUILT_IN_PRINTF_UNLOCKED:
10817 case BUILT_IN_VPRINTF:
10818 return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10820 case BUILT_IN_PRINTF_CHK:
10821 case BUILT_IN_VPRINTF_CHK:
10822 if (!validate_arg (arg0, INTEGER_TYPE)
10823 || TREE_SIDE_EFFECTS (arg0))
10824 return NULL_TREE;
10825 else
10826 return fold_builtin_printf (loc, fndecl,
10827 arg1, NULL_TREE, ignore, fcode);
10828 break;
10830 case BUILT_IN_FPRINTF:
10831 case BUILT_IN_FPRINTF_UNLOCKED:
10832 case BUILT_IN_VFPRINTF:
10833 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10834 ignore, fcode);
10836 case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
10837 return fold_builtin_atomic_always_lock_free (arg0, arg1);
10839 case BUILT_IN_ATOMIC_IS_LOCK_FREE:
10840 return fold_builtin_atomic_is_lock_free (arg0, arg1);
10842 default:
10843 break;
10845 return NULL_TREE;
10848 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10849 and ARG2. IGNORE is true if the result of the function call is ignored.
10850 This function returns NULL_TREE if no simplification was possible. */
10852 static tree
10853 fold_builtin_3 (location_t loc, tree fndecl,
10854 tree arg0, tree arg1, tree arg2, bool ignore)
10856 tree type = TREE_TYPE (TREE_TYPE (fndecl));
10857 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10858 switch (fcode)
10861 CASE_FLT_FN (BUILT_IN_SINCOS):
10862 return fold_builtin_sincos (loc, arg0, arg1, arg2);
10864 CASE_FLT_FN (BUILT_IN_FMA):
10865 return fold_builtin_fma (loc, arg0, arg1, arg2, type);
10866 break;
10868 CASE_FLT_FN (BUILT_IN_REMQUO):
10869 if (validate_arg (arg0, REAL_TYPE)
10870 && validate_arg(arg1, REAL_TYPE)
10871 && validate_arg(arg2, POINTER_TYPE))
10872 return do_mpfr_remquo (arg0, arg1, arg2);
10873 break;
10875 case BUILT_IN_MEMSET:
10876 return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10878 case BUILT_IN_BCOPY:
10879 return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10880 void_type_node, true, /*endp=*/3);
10882 case BUILT_IN_MEMCPY:
10883 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10884 type, ignore, /*endp=*/0);
10886 case BUILT_IN_MEMPCPY:
10887 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10888 type, ignore, /*endp=*/1);
10890 case BUILT_IN_MEMMOVE:
10891 return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10892 type, ignore, /*endp=*/3);
10894 case BUILT_IN_STRNCAT:
10895 return fold_builtin_strncat (loc, arg0, arg1, arg2);
10897 case BUILT_IN_STRNCPY:
10898 return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10900 case BUILT_IN_STRNCMP:
10901 return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10903 case BUILT_IN_MEMCHR:
10904 return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10906 case BUILT_IN_BCMP:
10907 case BUILT_IN_MEMCMP:
10908 return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10910 case BUILT_IN_SPRINTF:
10911 return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10913 case BUILT_IN_SNPRINTF:
10914 return fold_builtin_snprintf (loc, arg0, arg1, arg2, NULL_TREE, ignore);
10916 case BUILT_IN_STRCPY_CHK:
10917 case BUILT_IN_STPCPY_CHK:
10918 return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10919 ignore, fcode);
10921 case BUILT_IN_STRCAT_CHK:
10922 return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10924 case BUILT_IN_PRINTF_CHK:
10925 case BUILT_IN_VPRINTF_CHK:
10926 if (!validate_arg (arg0, INTEGER_TYPE)
10927 || TREE_SIDE_EFFECTS (arg0))
10928 return NULL_TREE;
10929 else
10930 return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10931 break;
10933 case BUILT_IN_FPRINTF:
10934 case BUILT_IN_FPRINTF_UNLOCKED:
10935 case BUILT_IN_VFPRINTF:
10936 return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10937 ignore, fcode);
10939 case BUILT_IN_FPRINTF_CHK:
10940 case BUILT_IN_VFPRINTF_CHK:
10941 if (!validate_arg (arg1, INTEGER_TYPE)
10942 || TREE_SIDE_EFFECTS (arg1))
10943 return NULL_TREE;
10944 else
10945 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
10946 ignore, fcode);
10948 default:
10949 break;
10951 return NULL_TREE;
10954 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10955 ARG2, and ARG3. IGNORE is true if the result of the function call is
10956 ignored. This function returns NULL_TREE if no simplification was
10957 possible. */
10959 static tree
10960 fold_builtin_4 (location_t loc, tree fndecl,
10961 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
10963 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10965 switch (fcode)
10967 case BUILT_IN_MEMCPY_CHK:
10968 case BUILT_IN_MEMPCPY_CHK:
10969 case BUILT_IN_MEMMOVE_CHK:
10970 case BUILT_IN_MEMSET_CHK:
10971 return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
10972 NULL_TREE, ignore,
10973 DECL_FUNCTION_CODE (fndecl));
10975 case BUILT_IN_STRNCPY_CHK:
10976 case BUILT_IN_STPNCPY_CHK:
10977 return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE,
10978 ignore, fcode);
10980 case BUILT_IN_STRNCAT_CHK:
10981 return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
10983 case BUILT_IN_SNPRINTF:
10984 return fold_builtin_snprintf (loc, arg0, arg1, arg2, arg3, ignore);
10986 case BUILT_IN_FPRINTF_CHK:
10987 case BUILT_IN_VFPRINTF_CHK:
10988 if (!validate_arg (arg1, INTEGER_TYPE)
10989 || TREE_SIDE_EFFECTS (arg1))
10990 return NULL_TREE;
10991 else
10992 return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
10993 ignore, fcode);
10994 break;
10996 default:
10997 break;
10999 return NULL_TREE;
11002 /* Fold a call to built-in function FNDECL. ARGS is an array of NARGS
11003 arguments, where NARGS <= 4. IGNORE is true if the result of the
11004 function call is ignored. This function returns NULL_TREE if no
11005 simplification was possible. Note that this only folds builtins with
11006 fixed argument patterns. Foldings that do varargs-to-varargs
11007 transformations, or that match calls with more than 4 arguments,
11008 need to be handled with fold_builtin_varargs instead. */
11010 #define MAX_ARGS_TO_FOLD_BUILTIN 4
11012 static tree
11013 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
11015 tree ret = NULL_TREE;
11017 switch (nargs)
11019 case 0:
11020 ret = fold_builtin_0 (loc, fndecl, ignore);
11021 break;
11022 case 1:
11023 ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
11024 break;
11025 case 2:
11026 ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
11027 break;
11028 case 3:
11029 ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
11030 break;
11031 case 4:
11032 ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
11033 ignore);
11034 break;
11035 default:
11036 break;
11038 if (ret)
11040 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11041 SET_EXPR_LOCATION (ret, loc);
11042 TREE_NO_WARNING (ret) = 1;
11043 return ret;
11045 return NULL_TREE;
11048 /* Builtins with folding operations that operate on "..." arguments
11049 need special handling; we need to store the arguments in a convenient
11050 data structure before attempting any folding. Fortunately there are
11051 only a few builtins that fall into this category. FNDECL is the
11052 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11053 result of the function call is ignored. */
11055 static tree
11056 fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11057 bool ignore ATTRIBUTE_UNUSED)
11059 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11060 tree ret = NULL_TREE;
11062 switch (fcode)
11064 case BUILT_IN_SPRINTF_CHK:
11065 case BUILT_IN_VSPRINTF_CHK:
11066 ret = fold_builtin_sprintf_chk (loc, exp, fcode);
11067 break;
11069 case BUILT_IN_SNPRINTF_CHK:
11070 case BUILT_IN_VSNPRINTF_CHK:
11071 ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
11072 break;
11074 case BUILT_IN_FPCLASSIFY:
11075 ret = fold_builtin_fpclassify (loc, exp);
11076 break;
11078 default:
11079 break;
11081 if (ret)
11083 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11084 SET_EXPR_LOCATION (ret, loc);
11085 TREE_NO_WARNING (ret) = 1;
11086 return ret;
11088 return NULL_TREE;
11091 /* Return true if FNDECL shouldn't be folded right now.
11092 If a built-in function has an inline attribute always_inline
11093 wrapper, defer folding it after always_inline functions have
11094 been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11095 might not be performed. */
11097 bool
11098 avoid_folding_inline_builtin (tree fndecl)
11100 return (DECL_DECLARED_INLINE_P (fndecl)
11101 && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11102 && cfun
11103 && !cfun->always_inline_functions_inlined
11104 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11107 /* A wrapper function for builtin folding that prevents warnings for
11108 "statement without effect" and the like, caused by removing the
11109 call node earlier than the warning is generated. */
11111 tree
11112 fold_call_expr (location_t loc, tree exp, bool ignore)
11114 tree ret = NULL_TREE;
11115 tree fndecl = get_callee_fndecl (exp);
11116 if (fndecl
11117 && TREE_CODE (fndecl) == FUNCTION_DECL
11118 && DECL_BUILT_IN (fndecl)
11119 /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11120 yet. Defer folding until we see all the arguments
11121 (after inlining). */
11122 && !CALL_EXPR_VA_ARG_PACK (exp))
11124 int nargs = call_expr_nargs (exp);
11126 /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11127 instead last argument is __builtin_va_arg_pack (). Defer folding
11128 even in that case, until arguments are finalized. */
11129 if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11131 tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11132 if (fndecl2
11133 && TREE_CODE (fndecl2) == FUNCTION_DECL
11134 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11135 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11136 return NULL_TREE;
11139 if (avoid_folding_inline_builtin (fndecl))
11140 return NULL_TREE;
11142 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11143 return targetm.fold_builtin (fndecl, call_expr_nargs (exp),
11144 CALL_EXPR_ARGP (exp), ignore);
11145 else
11147 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11149 tree *args = CALL_EXPR_ARGP (exp);
11150 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
11152 if (!ret)
11153 ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
11154 if (ret)
11155 return ret;
11158 return NULL_TREE;
11161 /* Conveniently construct a function call expression. FNDECL names the
11162 function to be called and N arguments are passed in the array
11163 ARGARRAY. */
11165 tree
11166 build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
11168 tree fntype = TREE_TYPE (fndecl);
11169 tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11171 return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
11174 /* Conveniently construct a function call expression. FNDECL names the
11175 function to be called and the arguments are passed in the vector
11176 VEC. */
11178 tree
11179 build_call_expr_loc_vec (location_t loc, tree fndecl, VEC(tree,gc) *vec)
11181 return build_call_expr_loc_array (loc, fndecl, VEC_length (tree, vec),
11182 VEC_address (tree, vec));
11186 /* Conveniently construct a function call expression. FNDECL names the
11187 function to be called, N is the number of arguments, and the "..."
11188 parameters are the argument expressions. */
11190 tree
11191 build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
11193 va_list ap;
11194 tree *argarray = XALLOCAVEC (tree, n);
11195 int i;
11197 va_start (ap, n);
11198 for (i = 0; i < n; i++)
11199 argarray[i] = va_arg (ap, tree);
11200 va_end (ap);
11201 return build_call_expr_loc_array (loc, fndecl, n, argarray);
11204 /* Like build_call_expr_loc (UNKNOWN_LOCATION, ...). Duplicated because
11205 varargs macros aren't supported by all bootstrap compilers. */
11207 tree
11208 build_call_expr (tree fndecl, int n, ...)
11210 va_list ap;
11211 tree *argarray = XALLOCAVEC (tree, n);
11212 int i;
11214 va_start (ap, n);
11215 for (i = 0; i < n; i++)
11216 argarray[i] = va_arg (ap, tree);
11217 va_end (ap);
11218 return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
11221 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
11222 N arguments are passed in the array ARGARRAY. */
11224 tree
11225 fold_builtin_call_array (location_t loc, tree type,
11226 tree fn,
11227 int n,
11228 tree *argarray)
11230 tree ret = NULL_TREE;
11231 tree exp;
11233 if (TREE_CODE (fn) == ADDR_EXPR)
11235 tree fndecl = TREE_OPERAND (fn, 0);
11236 if (TREE_CODE (fndecl) == FUNCTION_DECL
11237 && DECL_BUILT_IN (fndecl))
11239 /* If last argument is __builtin_va_arg_pack (), arguments to this
11240 function are not finalized yet. Defer folding until they are. */
11241 if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11243 tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11244 if (fndecl2
11245 && TREE_CODE (fndecl2) == FUNCTION_DECL
11246 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11247 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11248 return build_call_array_loc (loc, type, fn, n, argarray);
11250 if (avoid_folding_inline_builtin (fndecl))
11251 return build_call_array_loc (loc, type, fn, n, argarray);
11252 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11254 ret = targetm.fold_builtin (fndecl, n, argarray, false);
11255 if (ret)
11256 return ret;
11258 return build_call_array_loc (loc, type, fn, n, argarray);
11260 else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11262 /* First try the transformations that don't require consing up
11263 an exp. */
11264 ret = fold_builtin_n (loc, fndecl, argarray, n, false);
11265 if (ret)
11266 return ret;
11269 /* If we got this far, we need to build an exp. */
11270 exp = build_call_array_loc (loc, type, fn, n, argarray);
11271 ret = fold_builtin_varargs (loc, fndecl, exp, false);
11272 return ret ? ret : exp;
11276 return build_call_array_loc (loc, type, fn, n, argarray);
11279 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11280 list ARGS along with N new arguments in NEWARGS. SKIP is the number
11281 of arguments in ARGS to be omitted. OLDNARGS is the number of
11282 elements in ARGS. */
11284 static tree
11285 rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
11286 int skip, tree fndecl, int n, va_list newargs)
11288 int nargs = oldnargs - skip + n;
11289 tree *buffer;
11291 if (n > 0)
11293 int i, j;
11295 buffer = XALLOCAVEC (tree, nargs);
11296 for (i = 0; i < n; i++)
11297 buffer[i] = va_arg (newargs, tree);
11298 for (j = skip; j < oldnargs; j++, i++)
11299 buffer[i] = args[j];
11301 else
11302 buffer = args + skip;
11304 return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
11307 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11308 list ARGS along with N new arguments specified as the "..."
11309 parameters. SKIP is the number of arguments in ARGS to be omitted.
11310 OLDNARGS is the number of elements in ARGS. */
11312 static tree
11313 rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
11314 int skip, tree fndecl, int n, ...)
11316 va_list ap;
11317 tree t;
11319 va_start (ap, n);
11320 t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
11321 va_end (ap);
11323 return t;
11326 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
11327 along with N new arguments specified as the "..." parameters. SKIP
11328 is the number of arguments in EXP to be omitted. This function is used
11329 to do varargs-to-varargs transformations. */
11331 static tree
11332 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
11334 va_list ap;
11335 tree t;
11337 va_start (ap, n);
11338 t = rewrite_call_expr_valist (loc, call_expr_nargs (exp),
11339 CALL_EXPR_ARGP (exp), skip, fndecl, n, ap);
11340 va_end (ap);
11342 return t;
11345 /* Validate a single argument ARG against a tree code CODE representing
11346 a type. */
11348 static bool
11349 validate_arg (const_tree arg, enum tree_code code)
11351 if (!arg)
11352 return false;
11353 else if (code == POINTER_TYPE)
11354 return POINTER_TYPE_P (TREE_TYPE (arg));
11355 else if (code == INTEGER_TYPE)
11356 return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11357 return code == TREE_CODE (TREE_TYPE (arg));
11360 /* This function validates the types of a function call argument list
11361 against a specified list of tree_codes. If the last specifier is a 0,
11362 that represents an ellipses, otherwise the last specifier must be a
11363 VOID_TYPE.
11365 This is the GIMPLE version of validate_arglist. Eventually we want to
11366 completely convert builtins.c to work from GIMPLEs and the tree based
11367 validate_arglist will then be removed. */
11369 bool
11370 validate_gimple_arglist (const_gimple call, ...)
11372 enum tree_code code;
11373 bool res = 0;
11374 va_list ap;
11375 const_tree arg;
11376 size_t i;
11378 va_start (ap, call);
11379 i = 0;
11383 code = (enum tree_code) va_arg (ap, int);
11384 switch (code)
11386 case 0:
11387 /* This signifies an ellipses, any further arguments are all ok. */
11388 res = true;
11389 goto end;
11390 case VOID_TYPE:
11391 /* This signifies an endlink, if no arguments remain, return
11392 true, otherwise return false. */
11393 res = (i == gimple_call_num_args (call));
11394 goto end;
11395 default:
11396 /* If no parameters remain or the parameter's code does not
11397 match the specified code, return false. Otherwise continue
11398 checking any remaining arguments. */
11399 arg = gimple_call_arg (call, i++);
11400 if (!validate_arg (arg, code))
11401 goto end;
11402 break;
11405 while (1);
11407 /* We need gotos here since we can only have one VA_CLOSE in a
11408 function. */
11409 end: ;
11410 va_end (ap);
11412 return res;
11415 /* This function validates the types of a function call argument list
11416 against a specified list of tree_codes. If the last specifier is a 0,
11417 that represents an ellipses, otherwise the last specifier must be a
11418 VOID_TYPE. */
11420 bool
11421 validate_arglist (const_tree callexpr, ...)
11423 enum tree_code code;
11424 bool res = 0;
11425 va_list ap;
11426 const_call_expr_arg_iterator iter;
11427 const_tree arg;
11429 va_start (ap, callexpr);
11430 init_const_call_expr_arg_iterator (callexpr, &iter);
11434 code = (enum tree_code) va_arg (ap, int);
11435 switch (code)
11437 case 0:
11438 /* This signifies an ellipses, any further arguments are all ok. */
11439 res = true;
11440 goto end;
11441 case VOID_TYPE:
11442 /* This signifies an endlink, if no arguments remain, return
11443 true, otherwise return false. */
11444 res = !more_const_call_expr_args_p (&iter);
11445 goto end;
11446 default:
11447 /* If no parameters remain or the parameter's code does not
11448 match the specified code, return false. Otherwise continue
11449 checking any remaining arguments. */
11450 arg = next_const_call_expr_arg (&iter);
11451 if (!validate_arg (arg, code))
11452 goto end;
11453 break;
11456 while (1);
11458 /* We need gotos here since we can only have one VA_CLOSE in a
11459 function. */
11460 end: ;
11461 va_end (ap);
11463 return res;
11466 /* Default target-specific builtin expander that does nothing. */
11469 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11470 rtx target ATTRIBUTE_UNUSED,
11471 rtx subtarget ATTRIBUTE_UNUSED,
11472 enum machine_mode mode ATTRIBUTE_UNUSED,
11473 int ignore ATTRIBUTE_UNUSED)
11475 return NULL_RTX;
11478 /* Returns true is EXP represents data that would potentially reside
11479 in a readonly section. */
11481 static bool
11482 readonly_data_expr (tree exp)
11484 STRIP_NOPS (exp);
11486 if (TREE_CODE (exp) != ADDR_EXPR)
11487 return false;
11489 exp = get_base_address (TREE_OPERAND (exp, 0));
11490 if (!exp)
11491 return false;
11493 /* Make sure we call decl_readonly_section only for trees it
11494 can handle (since it returns true for everything it doesn't
11495 understand). */
11496 if (TREE_CODE (exp) == STRING_CST
11497 || TREE_CODE (exp) == CONSTRUCTOR
11498 || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11499 return decl_readonly_section (exp, 0);
11500 else
11501 return false;
11504 /* Simplify a call to the strstr builtin. S1 and S2 are the arguments
11505 to the call, and TYPE is its return type.
11507 Return NULL_TREE if no simplification was possible, otherwise return the
11508 simplified form of the call as a tree.
11510 The simplified form may be a constant or other expression which
11511 computes the same value, but in a more efficient manner (including
11512 calls to other builtin functions).
11514 The call may contain arguments which need to be evaluated, but
11515 which are not useful to determine the result of the call. In
11516 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11517 COMPOUND_EXPR will be an argument which must be evaluated.
11518 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11519 COMPOUND_EXPR in the chain will contain the tree for the simplified
11520 form of the builtin function call. */
11522 static tree
11523 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11525 if (!validate_arg (s1, POINTER_TYPE)
11526 || !validate_arg (s2, POINTER_TYPE))
11527 return NULL_TREE;
11528 else
11530 tree fn;
11531 const char *p1, *p2;
11533 p2 = c_getstr (s2);
11534 if (p2 == NULL)
11535 return NULL_TREE;
11537 p1 = c_getstr (s1);
11538 if (p1 != NULL)
11540 const char *r = strstr (p1, p2);
11541 tree tem;
11543 if (r == NULL)
11544 return build_int_cst (TREE_TYPE (s1), 0);
11546 /* Return an offset into the constant string argument. */
11547 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11548 return fold_convert_loc (loc, type, tem);
11551 /* The argument is const char *, and the result is char *, so we need
11552 a type conversion here to avoid a warning. */
11553 if (p2[0] == '\0')
11554 return fold_convert_loc (loc, type, s1);
11556 if (p2[1] != '\0')
11557 return NULL_TREE;
11559 fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11560 if (!fn)
11561 return NULL_TREE;
11563 /* New argument list transforming strstr(s1, s2) to
11564 strchr(s1, s2[0]). */
11565 return build_call_expr_loc (loc, fn, 2, s1,
11566 build_int_cst (integer_type_node, p2[0]));
11570 /* Simplify a call to the strchr builtin. S1 and S2 are the arguments to
11571 the call, and TYPE is its return type.
11573 Return NULL_TREE if no simplification was possible, otherwise return the
11574 simplified form of the call as a tree.
11576 The simplified form may be a constant or other expression which
11577 computes the same value, but in a more efficient manner (including
11578 calls to other builtin functions).
11580 The call may contain arguments which need to be evaluated, but
11581 which are not useful to determine the result of the call. In
11582 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11583 COMPOUND_EXPR will be an argument which must be evaluated.
11584 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11585 COMPOUND_EXPR in the chain will contain the tree for the simplified
11586 form of the builtin function call. */
11588 static tree
11589 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11591 if (!validate_arg (s1, POINTER_TYPE)
11592 || !validate_arg (s2, INTEGER_TYPE))
11593 return NULL_TREE;
11594 else
11596 const char *p1;
11598 if (TREE_CODE (s2) != INTEGER_CST)
11599 return NULL_TREE;
11601 p1 = c_getstr (s1);
11602 if (p1 != NULL)
11604 char c;
11605 const char *r;
11606 tree tem;
11608 if (target_char_cast (s2, &c))
11609 return NULL_TREE;
11611 r = strchr (p1, c);
11613 if (r == NULL)
11614 return build_int_cst (TREE_TYPE (s1), 0);
11616 /* Return an offset into the constant string argument. */
11617 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11618 return fold_convert_loc (loc, type, tem);
11620 return NULL_TREE;
11624 /* Simplify a call to the strrchr builtin. S1 and S2 are the arguments to
11625 the call, and TYPE is its return type.
11627 Return NULL_TREE if no simplification was possible, otherwise return the
11628 simplified form of the call as a tree.
11630 The simplified form may be a constant or other expression which
11631 computes the same value, but in a more efficient manner (including
11632 calls to other builtin functions).
11634 The call may contain arguments which need to be evaluated, but
11635 which are not useful to determine the result of the call. In
11636 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11637 COMPOUND_EXPR will be an argument which must be evaluated.
11638 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11639 COMPOUND_EXPR in the chain will contain the tree for the simplified
11640 form of the builtin function call. */
11642 static tree
11643 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11645 if (!validate_arg (s1, POINTER_TYPE)
11646 || !validate_arg (s2, INTEGER_TYPE))
11647 return NULL_TREE;
11648 else
11650 tree fn;
11651 const char *p1;
11653 if (TREE_CODE (s2) != INTEGER_CST)
11654 return NULL_TREE;
11656 p1 = c_getstr (s1);
11657 if (p1 != NULL)
11659 char c;
11660 const char *r;
11661 tree tem;
11663 if (target_char_cast (s2, &c))
11664 return NULL_TREE;
11666 r = strrchr (p1, c);
11668 if (r == NULL)
11669 return build_int_cst (TREE_TYPE (s1), 0);
11671 /* Return an offset into the constant string argument. */
11672 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11673 return fold_convert_loc (loc, type, tem);
11676 if (! integer_zerop (s2))
11677 return NULL_TREE;
11679 fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11680 if (!fn)
11681 return NULL_TREE;
11683 /* Transform strrchr(s1, '\0') to strchr(s1, '\0'). */
11684 return build_call_expr_loc (loc, fn, 2, s1, s2);
11688 /* Simplify a call to the strpbrk builtin. S1 and S2 are the arguments
11689 to the call, and TYPE is its return type.
11691 Return NULL_TREE if no simplification was possible, otherwise return the
11692 simplified form of the call as a tree.
11694 The simplified form may be a constant or other expression which
11695 computes the same value, but in a more efficient manner (including
11696 calls to other builtin functions).
11698 The call may contain arguments which need to be evaluated, but
11699 which are not useful to determine the result of the call. In
11700 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11701 COMPOUND_EXPR will be an argument which must be evaluated.
11702 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11703 COMPOUND_EXPR in the chain will contain the tree for the simplified
11704 form of the builtin function call. */
11706 static tree
11707 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11709 if (!validate_arg (s1, POINTER_TYPE)
11710 || !validate_arg (s2, POINTER_TYPE))
11711 return NULL_TREE;
11712 else
11714 tree fn;
11715 const char *p1, *p2;
11717 p2 = c_getstr (s2);
11718 if (p2 == NULL)
11719 return NULL_TREE;
11721 p1 = c_getstr (s1);
11722 if (p1 != NULL)
11724 const char *r = strpbrk (p1, p2);
11725 tree tem;
11727 if (r == NULL)
11728 return build_int_cst (TREE_TYPE (s1), 0);
11730 /* Return an offset into the constant string argument. */
11731 tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11732 return fold_convert_loc (loc, type, tem);
11735 if (p2[0] == '\0')
11736 /* strpbrk(x, "") == NULL.
11737 Evaluate and ignore s1 in case it had side-effects. */
11738 return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11740 if (p2[1] != '\0')
11741 return NULL_TREE; /* Really call strpbrk. */
11743 fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11744 if (!fn)
11745 return NULL_TREE;
11747 /* New argument list transforming strpbrk(s1, s2) to
11748 strchr(s1, s2[0]). */
11749 return build_call_expr_loc (loc, fn, 2, s1,
11750 build_int_cst (integer_type_node, p2[0]));
11754 /* Simplify a call to the strcat builtin. DST and SRC are the arguments
11755 to the call.
11757 Return NULL_TREE if no simplification was possible, otherwise return the
11758 simplified form of the call as a tree.
11760 The simplified form may be a constant or other expression which
11761 computes the same value, but in a more efficient manner (including
11762 calls to other builtin functions).
11764 The call may contain arguments which need to be evaluated, but
11765 which are not useful to determine the result of the call. In
11766 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11767 COMPOUND_EXPR will be an argument which must be evaluated.
11768 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11769 COMPOUND_EXPR in the chain will contain the tree for the simplified
11770 form of the builtin function call. */
11772 static tree
11773 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11775 if (!validate_arg (dst, POINTER_TYPE)
11776 || !validate_arg (src, POINTER_TYPE))
11777 return NULL_TREE;
11778 else
11780 const char *p = c_getstr (src);
11782 /* If the string length is zero, return the dst parameter. */
11783 if (p && *p == '\0')
11784 return dst;
11786 if (optimize_insn_for_speed_p ())
11788 /* See if we can store by pieces into (dst + strlen(dst)). */
11789 tree newdst, call;
11790 tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11791 tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
11793 if (!strlen_fn || !strcpy_fn)
11794 return NULL_TREE;
11796 /* If we don't have a movstr we don't want to emit an strcpy
11797 call. We have to do that if the length of the source string
11798 isn't computable (in that case we can use memcpy probably
11799 later expanding to a sequence of mov instructions). If we
11800 have movstr instructions we can emit strcpy calls. */
11801 if (!HAVE_movstr)
11803 tree len = c_strlen (src, 1);
11804 if (! len || TREE_SIDE_EFFECTS (len))
11805 return NULL_TREE;
11808 /* Stabilize the argument list. */
11809 dst = builtin_save_expr (dst);
11811 /* Create strlen (dst). */
11812 newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11813 /* Create (dst p+ strlen (dst)). */
11815 newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
11816 newdst = builtin_save_expr (newdst);
11818 call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11819 return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11821 return NULL_TREE;
11825 /* Simplify a call to the strncat builtin. DST, SRC, and LEN are the
11826 arguments to the call.
11828 Return NULL_TREE if no simplification was possible, otherwise return the
11829 simplified form of the call as a tree.
11831 The simplified form may be a constant or other expression which
11832 computes the same value, but in a more efficient manner (including
11833 calls to other builtin functions).
11835 The call may contain arguments which need to be evaluated, but
11836 which are not useful to determine the result of the call. In
11837 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11838 COMPOUND_EXPR will be an argument which must be evaluated.
11839 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11840 COMPOUND_EXPR in the chain will contain the tree for the simplified
11841 form of the builtin function call. */
11843 static tree
11844 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11846 if (!validate_arg (dst, POINTER_TYPE)
11847 || !validate_arg (src, POINTER_TYPE)
11848 || !validate_arg (len, INTEGER_TYPE))
11849 return NULL_TREE;
11850 else
11852 const char *p = c_getstr (src);
11854 /* If the requested length is zero, or the src parameter string
11855 length is zero, return the dst parameter. */
11856 if (integer_zerop (len) || (p && *p == '\0'))
11857 return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11859 /* If the requested len is greater than or equal to the string
11860 length, call strcat. */
11861 if (TREE_CODE (len) == INTEGER_CST && p
11862 && compare_tree_int (len, strlen (p)) >= 0)
11864 tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
11866 /* If the replacement _DECL isn't initialized, don't do the
11867 transformation. */
11868 if (!fn)
11869 return NULL_TREE;
11871 return build_call_expr_loc (loc, fn, 2, dst, src);
11873 return NULL_TREE;
11877 /* Simplify a call to the strspn builtin. S1 and S2 are the arguments
11878 to the call.
11880 Return NULL_TREE if no simplification was possible, otherwise return the
11881 simplified form of the call as a tree.
11883 The simplified form may be a constant or other expression which
11884 computes the same value, but in a more efficient manner (including
11885 calls to other builtin functions).
11887 The call may contain arguments which need to be evaluated, but
11888 which are not useful to determine the result of the call. In
11889 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11890 COMPOUND_EXPR will be an argument which must be evaluated.
11891 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11892 COMPOUND_EXPR in the chain will contain the tree for the simplified
11893 form of the builtin function call. */
11895 static tree
11896 fold_builtin_strspn (location_t loc, tree s1, tree s2)
11898 if (!validate_arg (s1, POINTER_TYPE)
11899 || !validate_arg (s2, POINTER_TYPE))
11900 return NULL_TREE;
11901 else
11903 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11905 /* If both arguments are constants, evaluate at compile-time. */
11906 if (p1 && p2)
11908 const size_t r = strspn (p1, p2);
11909 return size_int (r);
11912 /* If either argument is "", return NULL_TREE. */
11913 if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11914 /* Evaluate and ignore both arguments in case either one has
11915 side-effects. */
11916 return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11917 s1, s2);
11918 return NULL_TREE;
11922 /* Simplify a call to the strcspn builtin. S1 and S2 are the arguments
11923 to the call.
11925 Return NULL_TREE if no simplification was possible, otherwise return the
11926 simplified form of the call as a tree.
11928 The simplified form may be a constant or other expression which
11929 computes the same value, but in a more efficient manner (including
11930 calls to other builtin functions).
11932 The call may contain arguments which need to be evaluated, but
11933 which are not useful to determine the result of the call. In
11934 this case we return a chain of COMPOUND_EXPRs. The LHS of each
11935 COMPOUND_EXPR will be an argument which must be evaluated.
11936 COMPOUND_EXPRs are chained through their RHS. The RHS of the last
11937 COMPOUND_EXPR in the chain will contain the tree for the simplified
11938 form of the builtin function call. */
11940 static tree
11941 fold_builtin_strcspn (location_t loc, tree s1, tree s2)
11943 if (!validate_arg (s1, POINTER_TYPE)
11944 || !validate_arg (s2, POINTER_TYPE))
11945 return NULL_TREE;
11946 else
11948 const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11950 /* If both arguments are constants, evaluate at compile-time. */
11951 if (p1 && p2)
11953 const size_t r = strcspn (p1, p2);
11954 return size_int (r);
11957 /* If the first argument is "", return NULL_TREE. */
11958 if (p1 && *p1 == '\0')
11960 /* Evaluate and ignore argument s2 in case it has
11961 side-effects. */
11962 return omit_one_operand_loc (loc, size_type_node,
11963 size_zero_node, s2);
11966 /* If the second argument is "", return __builtin_strlen(s1). */
11967 if (p2 && *p2 == '\0')
11969 tree fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11971 /* If the replacement _DECL isn't initialized, don't do the
11972 transformation. */
11973 if (!fn)
11974 return NULL_TREE;
11976 return build_call_expr_loc (loc, fn, 1, s1);
11978 return NULL_TREE;
11982 /* Fold a call to the fputs builtin. ARG0 and ARG1 are the arguments
11983 to the call. IGNORE is true if the value returned
11984 by the builtin will be ignored. UNLOCKED is true is true if this
11985 actually a call to fputs_unlocked. If LEN in non-NULL, it represents
11986 the known length of the string. Return NULL_TREE if no simplification
11987 was possible. */
11989 tree
11990 fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11991 bool ignore, bool unlocked, tree len)
11993 /* If we're using an unlocked function, assume the other unlocked
11994 functions exist explicitly. */
11995 tree const fn_fputc = (unlocked
11996 ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
11997 : builtin_decl_implicit (BUILT_IN_FPUTC));
11998 tree const fn_fwrite = (unlocked
11999 ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
12000 : builtin_decl_implicit (BUILT_IN_FWRITE));
12002 /* If the return value is used, don't do the transformation. */
12003 if (!ignore)
12004 return NULL_TREE;
12006 /* Verify the arguments in the original call. */
12007 if (!validate_arg (arg0, POINTER_TYPE)
12008 || !validate_arg (arg1, POINTER_TYPE))
12009 return NULL_TREE;
12011 if (! len)
12012 len = c_strlen (arg0, 0);
12014 /* Get the length of the string passed to fputs. If the length
12015 can't be determined, punt. */
12016 if (!len
12017 || TREE_CODE (len) != INTEGER_CST)
12018 return NULL_TREE;
12020 switch (compare_tree_int (len, 1))
12022 case -1: /* length is 0, delete the call entirely . */
12023 return omit_one_operand_loc (loc, integer_type_node,
12024 integer_zero_node, arg1);;
12026 case 0: /* length is 1, call fputc. */
12028 const char *p = c_getstr (arg0);
12030 if (p != NULL)
12032 if (fn_fputc)
12033 return build_call_expr_loc (loc, fn_fputc, 2,
12034 build_int_cst
12035 (integer_type_node, p[0]), arg1);
12036 else
12037 return NULL_TREE;
12040 /* FALLTHROUGH */
12041 case 1: /* length is greater than 1, call fwrite. */
12043 /* If optimizing for size keep fputs. */
12044 if (optimize_function_for_size_p (cfun))
12045 return NULL_TREE;
12046 /* New argument list transforming fputs(string, stream) to
12047 fwrite(string, 1, len, stream). */
12048 if (fn_fwrite)
12049 return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12050 size_one_node, len, arg1);
12051 else
12052 return NULL_TREE;
12054 default:
12055 gcc_unreachable ();
12057 return NULL_TREE;
12060 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
12061 produced. False otherwise. This is done so that we don't output the error
12062 or warning twice or three times. */
12064 bool
12065 fold_builtin_next_arg (tree exp, bool va_start_p)
12067 tree fntype = TREE_TYPE (current_function_decl);
12068 int nargs = call_expr_nargs (exp);
12069 tree arg;
12070 /* There is good chance the current input_location points inside the
12071 definition of the va_start macro (perhaps on the token for
12072 builtin) in a system header, so warnings will not be emitted.
12073 Use the location in real source code. */
12074 source_location current_location =
12075 linemap_unwind_to_first_non_reserved_loc (line_table, input_location,
12076 NULL);
12078 if (!stdarg_p (fntype))
12080 error ("%<va_start%> used in function with fixed args");
12081 return true;
12084 if (va_start_p)
12086 if (va_start_p && (nargs != 2))
12088 error ("wrong number of arguments to function %<va_start%>");
12089 return true;
12091 arg = CALL_EXPR_ARG (exp, 1);
12093 /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12094 when we checked the arguments and if needed issued a warning. */
12095 else
12097 if (nargs == 0)
12099 /* Evidently an out of date version of <stdarg.h>; can't validate
12100 va_start's second argument, but can still work as intended. */
12101 warning_at (current_location,
12102 OPT_Wvarargs,
12103 "%<__builtin_next_arg%> called without an argument");
12104 return true;
12106 else if (nargs > 1)
12108 error ("wrong number of arguments to function %<__builtin_next_arg%>");
12109 return true;
12111 arg = CALL_EXPR_ARG (exp, 0);
12114 if (TREE_CODE (arg) == SSA_NAME)
12115 arg = SSA_NAME_VAR (arg);
12117 /* We destructively modify the call to be __builtin_va_start (ap, 0)
12118 or __builtin_next_arg (0) the first time we see it, after checking
12119 the arguments and if needed issuing a warning. */
12120 if (!integer_zerop (arg))
12122 tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
12124 /* Strip off all nops for the sake of the comparison. This
12125 is not quite the same as STRIP_NOPS. It does more.
12126 We must also strip off INDIRECT_EXPR for C++ reference
12127 parameters. */
12128 while (CONVERT_EXPR_P (arg)
12129 || TREE_CODE (arg) == INDIRECT_REF)
12130 arg = TREE_OPERAND (arg, 0);
12131 if (arg != last_parm)
12133 /* FIXME: Sometimes with the tree optimizers we can get the
12134 not the last argument even though the user used the last
12135 argument. We just warn and set the arg to be the last
12136 argument so that we will get wrong-code because of
12137 it. */
12138 warning_at (current_location,
12139 OPT_Wvarargs,
12140 "second parameter of %<va_start%> not last named argument");
12143 /* Undefined by C99 7.15.1.4p4 (va_start):
12144 "If the parameter parmN is declared with the register storage
12145 class, with a function or array type, or with a type that is
12146 not compatible with the type that results after application of
12147 the default argument promotions, the behavior is undefined."
12149 else if (DECL_REGISTER (arg))
12151 warning_at (current_location,
12152 OPT_Wvarargs,
12153 "undefined behaviour when second parameter of "
12154 "%<va_start%> is declared with %<register%> storage");
12157 /* We want to verify the second parameter just once before the tree
12158 optimizers are run and then avoid keeping it in the tree,
12159 as otherwise we could warn even for correct code like:
12160 void foo (int i, ...)
12161 { va_list ap; i++; va_start (ap, i); va_end (ap); } */
12162 if (va_start_p)
12163 CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12164 else
12165 CALL_EXPR_ARG (exp, 0) = integer_zero_node;
12167 return false;
12171 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12172 ORIG may be null if this is a 2-argument call. We don't attempt to
12173 simplify calls with more than 3 arguments.
12175 Return NULL_TREE if no simplification was possible, otherwise return the
12176 simplified form of the call as a tree. If IGNORED is true, it means that
12177 the caller does not use the returned value of the function. */
12179 static tree
12180 fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12181 tree orig, int ignored)
12183 tree call, retval;
12184 const char *fmt_str = NULL;
12186 /* Verify the required arguments in the original call. We deal with two
12187 types of sprintf() calls: 'sprintf (str, fmt)' and
12188 'sprintf (dest, "%s", orig)'. */
12189 if (!validate_arg (dest, POINTER_TYPE)
12190 || !validate_arg (fmt, POINTER_TYPE))
12191 return NULL_TREE;
12192 if (orig && !validate_arg (orig, POINTER_TYPE))
12193 return NULL_TREE;
12195 /* Check whether the format is a literal string constant. */
12196 fmt_str = c_getstr (fmt);
12197 if (fmt_str == NULL)
12198 return NULL_TREE;
12200 call = NULL_TREE;
12201 retval = NULL_TREE;
12203 if (!init_target_chars ())
12204 return NULL_TREE;
12206 /* If the format doesn't contain % args or %%, use strcpy. */
12207 if (strchr (fmt_str, target_percent) == NULL)
12209 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12211 if (!fn)
12212 return NULL_TREE;
12214 /* Don't optimize sprintf (buf, "abc", ptr++). */
12215 if (orig)
12216 return NULL_TREE;
12218 /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12219 'format' is known to contain no % formats. */
12220 call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12221 if (!ignored)
12222 retval = build_int_cst (integer_type_node, strlen (fmt_str));
12225 /* If the format is "%s", use strcpy if the result isn't used. */
12226 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12228 tree fn;
12229 fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12231 if (!fn)
12232 return NULL_TREE;
12234 /* Don't crash on sprintf (str1, "%s"). */
12235 if (!orig)
12236 return NULL_TREE;
12238 /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2). */
12239 if (!ignored)
12241 retval = c_strlen (orig, 1);
12242 if (!retval || TREE_CODE (retval) != INTEGER_CST)
12243 return NULL_TREE;
12245 call = build_call_expr_loc (loc, fn, 2, dest, orig);
12248 if (call && retval)
12250 retval = fold_convert_loc
12251 (loc, TREE_TYPE (TREE_TYPE (builtin_decl_implicit (BUILT_IN_SPRINTF))),
12252 retval);
12253 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12255 else
12256 return call;
12259 /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
12260 FMT, and ORIG. ORIG may be null if this is a 3-argument call. We don't
12261 attempt to simplify calls with more than 4 arguments.
12263 Return NULL_TREE if no simplification was possible, otherwise return the
12264 simplified form of the call as a tree. If IGNORED is true, it means that
12265 the caller does not use the returned value of the function. */
12267 static tree
12268 fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
12269 tree orig, int ignored)
12271 tree call, retval;
12272 const char *fmt_str = NULL;
12273 unsigned HOST_WIDE_INT destlen;
12275 /* Verify the required arguments in the original call. We deal with two
12276 types of snprintf() calls: 'snprintf (str, cst, fmt)' and
12277 'snprintf (dest, cst, "%s", orig)'. */
12278 if (!validate_arg (dest, POINTER_TYPE)
12279 || !validate_arg (destsize, INTEGER_TYPE)
12280 || !validate_arg (fmt, POINTER_TYPE))
12281 return NULL_TREE;
12282 if (orig && !validate_arg (orig, POINTER_TYPE))
12283 return NULL_TREE;
12285 if (!host_integerp (destsize, 1))
12286 return NULL_TREE;
12288 /* Check whether the format is a literal string constant. */
12289 fmt_str = c_getstr (fmt);
12290 if (fmt_str == NULL)
12291 return NULL_TREE;
12293 call = NULL_TREE;
12294 retval = NULL_TREE;
12296 if (!init_target_chars ())
12297 return NULL_TREE;
12299 destlen = tree_low_cst (destsize, 1);
12301 /* If the format doesn't contain % args or %%, use strcpy. */
12302 if (strchr (fmt_str, target_percent) == NULL)
12304 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12305 size_t len = strlen (fmt_str);
12307 /* Don't optimize snprintf (buf, 4, "abc", ptr++). */
12308 if (orig)
12309 return NULL_TREE;
12311 /* We could expand this as
12312 memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
12313 or to
12314 memcpy (str, fmt_with_nul_at_cstm1, cst);
12315 but in the former case that might increase code size
12316 and in the latter case grow .rodata section too much.
12317 So punt for now. */
12318 if (len >= destlen)
12319 return NULL_TREE;
12321 if (!fn)
12322 return NULL_TREE;
12324 /* Convert snprintf (str, cst, fmt) into strcpy (str, fmt) when
12325 'format' is known to contain no % formats and
12326 strlen (fmt) < cst. */
12327 call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12329 if (!ignored)
12330 retval = build_int_cst (integer_type_node, strlen (fmt_str));
12333 /* If the format is "%s", use strcpy if the result isn't used. */
12334 else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12336 tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12337 unsigned HOST_WIDE_INT origlen;
12339 /* Don't crash on snprintf (str1, cst, "%s"). */
12340 if (!orig)
12341 return NULL_TREE;
12343 retval = c_strlen (orig, 1);
12344 if (!retval || !host_integerp (retval, 1))
12345 return NULL_TREE;
12347 origlen = tree_low_cst (retval, 1);
12348 /* We could expand this as
12349 memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
12350 or to
12351 memcpy (str1, str2_with_nul_at_cstm1, cst);
12352 but in the former case that might increase code size
12353 and in the latter case grow .rodata section too much.
12354 So punt for now. */
12355 if (origlen >= destlen)
12356 return NULL_TREE;
12358 /* Convert snprintf (str1, cst, "%s", str2) into
12359 strcpy (str1, str2) if strlen (str2) < cst. */
12360 if (!fn)
12361 return NULL_TREE;
12363 call = build_call_expr_loc (loc, fn, 2, dest, orig);
12365 if (ignored)
12366 retval = NULL_TREE;
12369 if (call && retval)
12371 tree fn = builtin_decl_explicit (BUILT_IN_SNPRINTF);
12372 retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
12373 return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12375 else
12376 return call;
12379 /* Expand a call EXP to __builtin_object_size. */
12382 expand_builtin_object_size (tree exp)
12384 tree ost;
12385 int object_size_type;
12386 tree fndecl = get_callee_fndecl (exp);
12388 if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
12390 error ("%Kfirst argument of %D must be a pointer, second integer constant",
12391 exp, fndecl);
12392 expand_builtin_trap ();
12393 return const0_rtx;
12396 ost = CALL_EXPR_ARG (exp, 1);
12397 STRIP_NOPS (ost);
12399 if (TREE_CODE (ost) != INTEGER_CST
12400 || tree_int_cst_sgn (ost) < 0
12401 || compare_tree_int (ost, 3) > 0)
12403 error ("%Klast argument of %D is not integer constant between 0 and 3",
12404 exp, fndecl);
12405 expand_builtin_trap ();
12406 return const0_rtx;
12409 object_size_type = tree_low_cst (ost, 0);
12411 return object_size_type < 2 ? constm1_rtx : const0_rtx;
12414 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12415 FCODE is the BUILT_IN_* to use.
12416 Return NULL_RTX if we failed; the caller should emit a normal call,
12417 otherwise try to get the result in TARGET, if convenient (and in
12418 mode MODE if that's convenient). */
12420 static rtx
12421 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12422 enum built_in_function fcode)
12424 tree dest, src, len, size;
12426 if (!validate_arglist (exp,
12427 POINTER_TYPE,
12428 fcode == BUILT_IN_MEMSET_CHK
12429 ? INTEGER_TYPE : POINTER_TYPE,
12430 INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
12431 return NULL_RTX;
12433 dest = CALL_EXPR_ARG (exp, 0);
12434 src = CALL_EXPR_ARG (exp, 1);
12435 len = CALL_EXPR_ARG (exp, 2);
12436 size = CALL_EXPR_ARG (exp, 3);
12438 if (! host_integerp (size, 1))
12439 return NULL_RTX;
12441 if (host_integerp (len, 1) || integer_all_onesp (size))
12443 tree fn;
12445 if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12447 warning_at (tree_nonartificial_location (exp),
12448 0, "%Kcall to %D will always overflow destination buffer",
12449 exp, get_callee_fndecl (exp));
12450 return NULL_RTX;
12453 fn = NULL_TREE;
12454 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12455 mem{cpy,pcpy,move,set} is available. */
12456 switch (fcode)
12458 case BUILT_IN_MEMCPY_CHK:
12459 fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12460 break;
12461 case BUILT_IN_MEMPCPY_CHK:
12462 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12463 break;
12464 case BUILT_IN_MEMMOVE_CHK:
12465 fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12466 break;
12467 case BUILT_IN_MEMSET_CHK:
12468 fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12469 break;
12470 default:
12471 break;
12474 if (! fn)
12475 return NULL_RTX;
12477 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len);
12478 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12479 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12480 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12482 else if (fcode == BUILT_IN_MEMSET_CHK)
12483 return NULL_RTX;
12484 else
12486 unsigned int dest_align = get_pointer_alignment (dest);
12488 /* If DEST is not a pointer type, call the normal function. */
12489 if (dest_align == 0)
12490 return NULL_RTX;
12492 /* If SRC and DEST are the same (and not volatile), do nothing. */
12493 if (operand_equal_p (src, dest, 0))
12495 tree expr;
12497 if (fcode != BUILT_IN_MEMPCPY_CHK)
12499 /* Evaluate and ignore LEN in case it has side-effects. */
12500 expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12501 return expand_expr (dest, target, mode, EXPAND_NORMAL);
12504 expr = fold_build_pointer_plus (dest, len);
12505 return expand_expr (expr, target, mode, EXPAND_NORMAL);
12508 /* __memmove_chk special case. */
12509 if (fcode == BUILT_IN_MEMMOVE_CHK)
12511 unsigned int src_align = get_pointer_alignment (src);
12513 if (src_align == 0)
12514 return NULL_RTX;
12516 /* If src is categorized for a readonly section we can use
12517 normal __memcpy_chk. */
12518 if (readonly_data_expr (src))
12520 tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12521 if (!fn)
12522 return NULL_RTX;
12523 fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
12524 dest, src, len, size);
12525 gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12526 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12527 return expand_expr (fn, target, mode, EXPAND_NORMAL);
12530 return NULL_RTX;
12534 /* Emit warning if a buffer overflow is detected at compile time. */
12536 static void
12537 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12539 int is_strlen = 0;
12540 tree len, size;
12541 location_t loc = tree_nonartificial_location (exp);
12543 switch (fcode)
12545 case BUILT_IN_STRCPY_CHK:
12546 case BUILT_IN_STPCPY_CHK:
12547 /* For __strcat_chk the warning will be emitted only if overflowing
12548 by at least strlen (dest) + 1 bytes. */
12549 case BUILT_IN_STRCAT_CHK:
12550 len = CALL_EXPR_ARG (exp, 1);
12551 size = CALL_EXPR_ARG (exp, 2);
12552 is_strlen = 1;
12553 break;
12554 case BUILT_IN_STRNCAT_CHK:
12555 case BUILT_IN_STRNCPY_CHK:
12556 case BUILT_IN_STPNCPY_CHK:
12557 len = CALL_EXPR_ARG (exp, 2);
12558 size = CALL_EXPR_ARG (exp, 3);
12559 break;
12560 case BUILT_IN_SNPRINTF_CHK:
12561 case BUILT_IN_VSNPRINTF_CHK:
12562 len = CALL_EXPR_ARG (exp, 1);
12563 size = CALL_EXPR_ARG (exp, 3);
12564 break;
12565 default:
12566 gcc_unreachable ();
12569 if (!len || !size)
12570 return;
12572 if (! host_integerp (size, 1) || integer_all_onesp (size))
12573 return;
12575 if (is_strlen)
12577 len = c_strlen (len, 1);
12578 if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12579 return;
12581 else if (fcode == BUILT_IN_STRNCAT_CHK)
12583 tree src = CALL_EXPR_ARG (exp, 1);
12584 if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12585 return;
12586 src = c_strlen (src, 1);
12587 if (! src || ! host_integerp (src, 1))
12589 warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12590 exp, get_callee_fndecl (exp));
12591 return;
12593 else if (tree_int_cst_lt (src, size))
12594 return;
12596 else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12597 return;
12599 warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12600 exp, get_callee_fndecl (exp));
12603 /* Emit warning if a buffer overflow is detected at compile time
12604 in __sprintf_chk/__vsprintf_chk calls. */
12606 static void
12607 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12609 tree size, len, fmt;
12610 const char *fmt_str;
12611 int nargs = call_expr_nargs (exp);
12613 /* Verify the required arguments in the original call. */
12615 if (nargs < 4)
12616 return;
12617 size = CALL_EXPR_ARG (exp, 2);
12618 fmt = CALL_EXPR_ARG (exp, 3);
12620 if (! host_integerp (size, 1) || integer_all_onesp (size))
12621 return;
12623 /* Check whether the format is a literal string constant. */
12624 fmt_str = c_getstr (fmt);
12625 if (fmt_str == NULL)
12626 return;
12628 if (!init_target_chars ())
12629 return;
12631 /* If the format doesn't contain % args or %%, we know its size. */
12632 if (strchr (fmt_str, target_percent) == 0)
12633 len = build_int_cstu (size_type_node, strlen (fmt_str));
12634 /* If the format is "%s" and first ... argument is a string literal,
12635 we know it too. */
12636 else if (fcode == BUILT_IN_SPRINTF_CHK
12637 && strcmp (fmt_str, target_percent_s) == 0)
12639 tree arg;
12641 if (nargs < 5)
12642 return;
12643 arg = CALL_EXPR_ARG (exp, 4);
12644 if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12645 return;
12647 len = c_strlen (arg, 1);
12648 if (!len || ! host_integerp (len, 1))
12649 return;
12651 else
12652 return;
12654 if (! tree_int_cst_lt (len, size))
12655 warning_at (tree_nonartificial_location (exp),
12656 0, "%Kcall to %D will always overflow destination buffer",
12657 exp, get_callee_fndecl (exp));
12660 /* Emit warning if a free is called with address of a variable. */
12662 static void
12663 maybe_emit_free_warning (tree exp)
12665 tree arg = CALL_EXPR_ARG (exp, 0);
12667 STRIP_NOPS (arg);
12668 if (TREE_CODE (arg) != ADDR_EXPR)
12669 return;
12671 arg = get_base_address (TREE_OPERAND (arg, 0));
12672 if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF)
12673 return;
12675 if (SSA_VAR_P (arg))
12676 warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12677 "%Kattempt to free a non-heap object %qD", exp, arg);
12678 else
12679 warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12680 "%Kattempt to free a non-heap object", exp);
12683 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12684 if possible. */
12686 tree
12687 fold_builtin_object_size (tree ptr, tree ost)
12689 unsigned HOST_WIDE_INT bytes;
12690 int object_size_type;
12692 if (!validate_arg (ptr, POINTER_TYPE)
12693 || !validate_arg (ost, INTEGER_TYPE))
12694 return NULL_TREE;
12696 STRIP_NOPS (ost);
12698 if (TREE_CODE (ost) != INTEGER_CST
12699 || tree_int_cst_sgn (ost) < 0
12700 || compare_tree_int (ost, 3) > 0)
12701 return NULL_TREE;
12703 object_size_type = tree_low_cst (ost, 0);
12705 /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12706 if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12707 and (size_t) 0 for types 2 and 3. */
12708 if (TREE_SIDE_EFFECTS (ptr))
12709 return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12711 if (TREE_CODE (ptr) == ADDR_EXPR)
12713 bytes = compute_builtin_object_size (ptr, object_size_type);
12714 if (double_int_fits_to_tree_p (size_type_node,
12715 uhwi_to_double_int (bytes)))
12716 return build_int_cstu (size_type_node, bytes);
12718 else if (TREE_CODE (ptr) == SSA_NAME)
12720 /* If object size is not known yet, delay folding until
12721 later. Maybe subsequent passes will help determining
12722 it. */
12723 bytes = compute_builtin_object_size (ptr, object_size_type);
12724 if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
12725 && double_int_fits_to_tree_p (size_type_node,
12726 uhwi_to_double_int (bytes)))
12727 return build_int_cstu (size_type_node, bytes);
12730 return NULL_TREE;
12733 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12734 DEST, SRC, LEN, and SIZE are the arguments to the call.
12735 IGNORE is true, if return value can be ignored. FCODE is the BUILT_IN_*
12736 code of the builtin. If MAXLEN is not NULL, it is maximum length
12737 passed as third argument. */
12739 tree
12740 fold_builtin_memory_chk (location_t loc, tree fndecl,
12741 tree dest, tree src, tree len, tree size,
12742 tree maxlen, bool ignore,
12743 enum built_in_function fcode)
12745 tree fn;
12747 if (!validate_arg (dest, POINTER_TYPE)
12748 || !validate_arg (src,
12749 (fcode == BUILT_IN_MEMSET_CHK
12750 ? INTEGER_TYPE : POINTER_TYPE))
12751 || !validate_arg (len, INTEGER_TYPE)
12752 || !validate_arg (size, INTEGER_TYPE))
12753 return NULL_TREE;
12755 /* If SRC and DEST are the same (and not volatile), return DEST
12756 (resp. DEST+LEN for __mempcpy_chk). */
12757 if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12759 if (fcode != BUILT_IN_MEMPCPY_CHK)
12760 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12761 dest, len);
12762 else
12764 tree temp = fold_build_pointer_plus_loc (loc, dest, len);
12765 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12769 if (! host_integerp (size, 1))
12770 return NULL_TREE;
12772 if (! integer_all_onesp (size))
12774 if (! host_integerp (len, 1))
12776 /* If LEN is not constant, try MAXLEN too.
12777 For MAXLEN only allow optimizing into non-_ocs function
12778 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12779 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12781 if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12783 /* (void) __mempcpy_chk () can be optimized into
12784 (void) __memcpy_chk (). */
12785 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12786 if (!fn)
12787 return NULL_TREE;
12789 return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12791 return NULL_TREE;
12794 else
12795 maxlen = len;
12797 if (tree_int_cst_lt (size, maxlen))
12798 return NULL_TREE;
12801 fn = NULL_TREE;
12802 /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12803 mem{cpy,pcpy,move,set} is available. */
12804 switch (fcode)
12806 case BUILT_IN_MEMCPY_CHK:
12807 fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12808 break;
12809 case BUILT_IN_MEMPCPY_CHK:
12810 fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12811 break;
12812 case BUILT_IN_MEMMOVE_CHK:
12813 fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12814 break;
12815 case BUILT_IN_MEMSET_CHK:
12816 fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12817 break;
12818 default:
12819 break;
12822 if (!fn)
12823 return NULL_TREE;
12825 return build_call_expr_loc (loc, fn, 3, dest, src, len);
12828 /* Fold a call to the __st[rp]cpy_chk builtin.
12829 DEST, SRC, and SIZE are the arguments to the call.
12830 IGNORE is true if return value can be ignored. FCODE is the BUILT_IN_*
12831 code of the builtin. If MAXLEN is not NULL, it is maximum length of
12832 strings passed as second argument. */
12834 tree
12835 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12836 tree src, tree size,
12837 tree maxlen, bool ignore,
12838 enum built_in_function fcode)
12840 tree len, fn;
12842 if (!validate_arg (dest, POINTER_TYPE)
12843 || !validate_arg (src, POINTER_TYPE)
12844 || !validate_arg (size, INTEGER_TYPE))
12845 return NULL_TREE;
12847 /* If SRC and DEST are the same (and not volatile), return DEST. */
12848 if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12849 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12851 if (! host_integerp (size, 1))
12852 return NULL_TREE;
12854 if (! integer_all_onesp (size))
12856 len = c_strlen (src, 1);
12857 if (! len || ! host_integerp (len, 1))
12859 /* If LEN is not constant, try MAXLEN too.
12860 For MAXLEN only allow optimizing into non-_ocs function
12861 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12862 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12864 if (fcode == BUILT_IN_STPCPY_CHK)
12866 if (! ignore)
12867 return NULL_TREE;
12869 /* If return value of __stpcpy_chk is ignored,
12870 optimize into __strcpy_chk. */
12871 fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
12872 if (!fn)
12873 return NULL_TREE;
12875 return build_call_expr_loc (loc, fn, 3, dest, src, size);
12878 if (! len || TREE_SIDE_EFFECTS (len))
12879 return NULL_TREE;
12881 /* If c_strlen returned something, but not a constant,
12882 transform __strcpy_chk into __memcpy_chk. */
12883 fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12884 if (!fn)
12885 return NULL_TREE;
12887 len = fold_convert_loc (loc, size_type_node, len);
12888 len = size_binop_loc (loc, PLUS_EXPR, len,
12889 build_int_cst (size_type_node, 1));
12890 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12891 build_call_expr_loc (loc, fn, 4,
12892 dest, src, len, size));
12895 else
12896 maxlen = len;
12898 if (! tree_int_cst_lt (maxlen, size))
12899 return NULL_TREE;
12902 /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available. */
12903 fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
12904 ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
12905 if (!fn)
12906 return NULL_TREE;
12908 return build_call_expr_loc (loc, fn, 2, dest, src);
12911 /* Fold a call to the __st{r,p}ncpy_chk builtin. DEST, SRC, LEN, and SIZE
12912 are the arguments to the call. If MAXLEN is not NULL, it is maximum
12913 length passed as third argument. IGNORE is true if return value can be
12914 ignored. FCODE is the BUILT_IN_* code of the builtin. */
12916 tree
12917 fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
12918 tree len, tree size, tree maxlen, bool ignore,
12919 enum built_in_function fcode)
12921 tree fn;
12923 if (!validate_arg (dest, POINTER_TYPE)
12924 || !validate_arg (src, POINTER_TYPE)
12925 || !validate_arg (len, INTEGER_TYPE)
12926 || !validate_arg (size, INTEGER_TYPE))
12927 return NULL_TREE;
12929 if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
12931 /* If return value of __stpncpy_chk is ignored,
12932 optimize into __strncpy_chk. */
12933 fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
12934 if (fn)
12935 return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12938 if (! host_integerp (size, 1))
12939 return NULL_TREE;
12941 if (! integer_all_onesp (size))
12943 if (! host_integerp (len, 1))
12945 /* If LEN is not constant, try MAXLEN too.
12946 For MAXLEN only allow optimizing into non-_ocs function
12947 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
12948 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12949 return NULL_TREE;
12951 else
12952 maxlen = len;
12954 if (tree_int_cst_lt (size, maxlen))
12955 return NULL_TREE;
12958 /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available. */
12959 fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
12960 ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
12961 if (!fn)
12962 return NULL_TREE;
12964 return build_call_expr_loc (loc, fn, 3, dest, src, len);
12967 /* Fold a call to the __strcat_chk builtin FNDECL. DEST, SRC, and SIZE
12968 are the arguments to the call. */
12970 static tree
12971 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12972 tree src, tree size)
12974 tree fn;
12975 const char *p;
12977 if (!validate_arg (dest, POINTER_TYPE)
12978 || !validate_arg (src, POINTER_TYPE)
12979 || !validate_arg (size, INTEGER_TYPE))
12980 return NULL_TREE;
12982 p = c_getstr (src);
12983 /* If the SRC parameter is "", return DEST. */
12984 if (p && *p == '\0')
12985 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12987 if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12988 return NULL_TREE;
12990 /* If __builtin_strcat_chk is used, assume strcat is available. */
12991 fn = builtin_decl_explicit (BUILT_IN_STRCAT);
12992 if (!fn)
12993 return NULL_TREE;
12995 return build_call_expr_loc (loc, fn, 2, dest, src);
12998 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12999 LEN, and SIZE. */
13001 static tree
13002 fold_builtin_strncat_chk (location_t loc, tree fndecl,
13003 tree dest, tree src, tree len, tree size)
13005 tree fn;
13006 const char *p;
13008 if (!validate_arg (dest, POINTER_TYPE)
13009 || !validate_arg (src, POINTER_TYPE)
13010 || !validate_arg (size, INTEGER_TYPE)
13011 || !validate_arg (size, INTEGER_TYPE))
13012 return NULL_TREE;
13014 p = c_getstr (src);
13015 /* If the SRC parameter is "" or if LEN is 0, return DEST. */
13016 if (p && *p == '\0')
13017 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
13018 else if (integer_zerop (len))
13019 return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
13021 if (! host_integerp (size, 1))
13022 return NULL_TREE;
13024 if (! integer_all_onesp (size))
13026 tree src_len = c_strlen (src, 1);
13027 if (src_len
13028 && host_integerp (src_len, 1)
13029 && host_integerp (len, 1)
13030 && ! tree_int_cst_lt (len, src_len))
13032 /* If LEN >= strlen (SRC), optimize into __strcat_chk. */
13033 fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
13034 if (!fn)
13035 return NULL_TREE;
13037 return build_call_expr_loc (loc, fn, 3, dest, src, size);
13039 return NULL_TREE;
13042 /* If __builtin_strncat_chk is used, assume strncat is available. */
13043 fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
13044 if (!fn)
13045 return NULL_TREE;
13047 return build_call_expr_loc (loc, fn, 3, dest, src, len);
13050 /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
13051 Return NULL_TREE if a normal call should be emitted rather than
13052 expanding the function inline. FCODE is either BUILT_IN_SPRINTF_CHK
13053 or BUILT_IN_VSPRINTF_CHK. */
13055 static tree
13056 fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
13057 enum built_in_function fcode)
13059 tree dest, size, len, fn, fmt, flag;
13060 const char *fmt_str;
13062 /* Verify the required arguments in the original call. */
13063 if (nargs < 4)
13064 return NULL_TREE;
13065 dest = args[0];
13066 if (!validate_arg (dest, POINTER_TYPE))
13067 return NULL_TREE;
13068 flag = args[1];
13069 if (!validate_arg (flag, INTEGER_TYPE))
13070 return NULL_TREE;
13071 size = args[2];
13072 if (!validate_arg (size, INTEGER_TYPE))
13073 return NULL_TREE;
13074 fmt = args[3];
13075 if (!validate_arg (fmt, POINTER_TYPE))
13076 return NULL_TREE;
13078 if (! host_integerp (size, 1))
13079 return NULL_TREE;
13081 len = NULL_TREE;
13083 if (!init_target_chars ())
13084 return NULL_TREE;
13086 /* Check whether the format is a literal string constant. */
13087 fmt_str = c_getstr (fmt);
13088 if (fmt_str != NULL)
13090 /* If the format doesn't contain % args or %%, we know the size. */
13091 if (strchr (fmt_str, target_percent) == 0)
13093 if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13094 len = build_int_cstu (size_type_node, strlen (fmt_str));
13096 /* If the format is "%s" and first ... argument is a string literal,
13097 we know the size too. */
13098 else if (fcode == BUILT_IN_SPRINTF_CHK
13099 && strcmp (fmt_str, target_percent_s) == 0)
13101 tree arg;
13103 if (nargs == 5)
13105 arg = args[4];
13106 if (validate_arg (arg, POINTER_TYPE))
13108 len = c_strlen (arg, 1);
13109 if (! len || ! host_integerp (len, 1))
13110 len = NULL_TREE;
13116 if (! integer_all_onesp (size))
13118 if (! len || ! tree_int_cst_lt (len, size))
13119 return NULL_TREE;
13122 /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13123 or if format doesn't contain % chars or is "%s". */
13124 if (! integer_zerop (flag))
13126 if (fmt_str == NULL)
13127 return NULL_TREE;
13128 if (strchr (fmt_str, target_percent) != NULL
13129 && strcmp (fmt_str, target_percent_s))
13130 return NULL_TREE;
13133 /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available. */
13134 fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
13135 ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
13136 if (!fn)
13137 return NULL_TREE;
13139 return rewrite_call_expr_array (loc, nargs, args, 4, fn, 2, dest, fmt);
13142 /* Fold a call EXP to __{,v}sprintf_chk. Return NULL_TREE if
13143 a normal call should be emitted rather than expanding the function
13144 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
13146 static tree
13147 fold_builtin_sprintf_chk (location_t loc, tree exp,
13148 enum built_in_function fcode)
13150 return fold_builtin_sprintf_chk_1 (loc, call_expr_nargs (exp),
13151 CALL_EXPR_ARGP (exp), fcode);
13154 /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS. Return
13155 NULL_TREE if a normal call should be emitted rather than expanding
13156 the function inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13157 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13158 passed as second argument. */
13160 static tree
13161 fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
13162 tree maxlen, enum built_in_function fcode)
13164 tree dest, size, len, fn, fmt, flag;
13165 const char *fmt_str;
13167 /* Verify the required arguments in the original call. */
13168 if (nargs < 5)
13169 return NULL_TREE;
13170 dest = args[0];
13171 if (!validate_arg (dest, POINTER_TYPE))
13172 return NULL_TREE;
13173 len = args[1];
13174 if (!validate_arg (len, INTEGER_TYPE))
13175 return NULL_TREE;
13176 flag = args[2];
13177 if (!validate_arg (flag, INTEGER_TYPE))
13178 return NULL_TREE;
13179 size = args[3];
13180 if (!validate_arg (size, INTEGER_TYPE))
13181 return NULL_TREE;
13182 fmt = args[4];
13183 if (!validate_arg (fmt, POINTER_TYPE))
13184 return NULL_TREE;
13186 if (! host_integerp (size, 1))
13187 return NULL_TREE;
13189 if (! integer_all_onesp (size))
13191 if (! host_integerp (len, 1))
13193 /* If LEN is not constant, try MAXLEN too.
13194 For MAXLEN only allow optimizing into non-_ocs function
13195 if SIZE is >= MAXLEN, never convert to __ocs_fail (). */
13196 if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13197 return NULL_TREE;
13199 else
13200 maxlen = len;
13202 if (tree_int_cst_lt (size, maxlen))
13203 return NULL_TREE;
13206 if (!init_target_chars ())
13207 return NULL_TREE;
13209 /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13210 or if format doesn't contain % chars or is "%s". */
13211 if (! integer_zerop (flag))
13213 fmt_str = c_getstr (fmt);
13214 if (fmt_str == NULL)
13215 return NULL_TREE;
13216 if (strchr (fmt_str, target_percent) != NULL
13217 && strcmp (fmt_str, target_percent_s))
13218 return NULL_TREE;
13221 /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13222 available. */
13223 fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
13224 ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
13225 if (!fn)
13226 return NULL_TREE;
13228 return rewrite_call_expr_array (loc, nargs, args, 5, fn, 3, dest, len, fmt);
13231 /* Fold a call EXP to {,v}snprintf. Return NULL_TREE if
13232 a normal call should be emitted rather than expanding the function
13233 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
13234 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
13235 passed as second argument. */
13237 tree
13238 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
13239 enum built_in_function fcode)
13241 return fold_builtin_snprintf_chk_1 (loc, call_expr_nargs (exp),
13242 CALL_EXPR_ARGP (exp), maxlen, fcode);
13245 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
13246 FMT and ARG are the arguments to the call; we don't fold cases with
13247 more than 2 arguments, and ARG may be null if this is a 1-argument case.
13249 Return NULL_TREE if no simplification was possible, otherwise return the
13250 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13251 code of the function to be simplified. */
13253 static tree
13254 fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13255 tree arg, bool ignore,
13256 enum built_in_function fcode)
13258 tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
13259 const char *fmt_str = NULL;
13261 /* If the return value is used, don't do the transformation. */
13262 if (! ignore)
13263 return NULL_TREE;
13265 /* Verify the required arguments in the original call. */
13266 if (!validate_arg (fmt, POINTER_TYPE))
13267 return NULL_TREE;
13269 /* Check whether the format is a literal string constant. */
13270 fmt_str = c_getstr (fmt);
13271 if (fmt_str == NULL)
13272 return NULL_TREE;
13274 if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13276 /* If we're using an unlocked function, assume the other
13277 unlocked functions exist explicitly. */
13278 fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
13279 fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
13281 else
13283 fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
13284 fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
13287 if (!init_target_chars ())
13288 return NULL_TREE;
13290 if (strcmp (fmt_str, target_percent_s) == 0
13291 || strchr (fmt_str, target_percent) == NULL)
13293 const char *str;
13295 if (strcmp (fmt_str, target_percent_s) == 0)
13297 if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13298 return NULL_TREE;
13300 if (!arg || !validate_arg (arg, POINTER_TYPE))
13301 return NULL_TREE;
13303 str = c_getstr (arg);
13304 if (str == NULL)
13305 return NULL_TREE;
13307 else
13309 /* The format specifier doesn't contain any '%' characters. */
13310 if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
13311 && arg)
13312 return NULL_TREE;
13313 str = fmt_str;
13316 /* If the string was "", printf does nothing. */
13317 if (str[0] == '\0')
13318 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13320 /* If the string has length of 1, call putchar. */
13321 if (str[1] == '\0')
13323 /* Given printf("c"), (where c is any one character,)
13324 convert "c"[0] to an int and pass that to the replacement
13325 function. */
13326 newarg = build_int_cst (integer_type_node, str[0]);
13327 if (fn_putchar)
13328 call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
13330 else
13332 /* If the string was "string\n", call puts("string"). */
13333 size_t len = strlen (str);
13334 if ((unsigned char)str[len - 1] == target_newline
13335 && (size_t) (int) len == len
13336 && (int) len > 0)
13338 char *newstr;
13339 tree offset_node, string_cst;
13341 /* Create a NUL-terminated string that's one char shorter
13342 than the original, stripping off the trailing '\n'. */
13343 newarg = build_string_literal (len, str);
13344 string_cst = string_constant (newarg, &offset_node);
13345 gcc_checking_assert (string_cst
13346 && (TREE_STRING_LENGTH (string_cst)
13347 == (int) len)
13348 && integer_zerop (offset_node)
13349 && (unsigned char)
13350 TREE_STRING_POINTER (string_cst)[len - 1]
13351 == target_newline);
13352 /* build_string_literal creates a new STRING_CST,
13353 modify it in place to avoid double copying. */
13354 newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst));
13355 newstr[len - 1] = '\0';
13356 if (fn_puts)
13357 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
13359 else
13360 /* We'd like to arrange to call fputs(string,stdout) here,
13361 but we need stdout and don't have a way to get it yet. */
13362 return NULL_TREE;
13366 /* The other optimizations can be done only on the non-va_list variants. */
13367 else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13368 return NULL_TREE;
13370 /* If the format specifier was "%s\n", call __builtin_puts(arg). */
13371 else if (strcmp (fmt_str, target_percent_s_newline) == 0)
13373 if (!arg || !validate_arg (arg, POINTER_TYPE))
13374 return NULL_TREE;
13375 if (fn_puts)
13376 call = build_call_expr_loc (loc, fn_puts, 1, arg);
13379 /* If the format specifier was "%c", call __builtin_putchar(arg). */
13380 else if (strcmp (fmt_str, target_percent_c) == 0)
13382 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13383 return NULL_TREE;
13384 if (fn_putchar)
13385 call = build_call_expr_loc (loc, fn_putchar, 1, arg);
13388 if (!call)
13389 return NULL_TREE;
13391 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13394 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
13395 FP, FMT, and ARG are the arguments to the call. We don't fold calls with
13396 more than 3 arguments, and ARG may be null in the 2-argument case.
13398 Return NULL_TREE if no simplification was possible, otherwise return the
13399 simplified form of the call as a tree. FCODE is the BUILT_IN_*
13400 code of the function to be simplified. */
13402 static tree
13403 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13404 tree fmt, tree arg, bool ignore,
13405 enum built_in_function fcode)
13407 tree fn_fputc, fn_fputs, call = NULL_TREE;
13408 const char *fmt_str = NULL;
13410 /* If the return value is used, don't do the transformation. */
13411 if (! ignore)
13412 return NULL_TREE;
13414 /* Verify the required arguments in the original call. */
13415 if (!validate_arg (fp, POINTER_TYPE))
13416 return NULL_TREE;
13417 if (!validate_arg (fmt, POINTER_TYPE))
13418 return NULL_TREE;
13420 /* Check whether the format is a literal string constant. */
13421 fmt_str = c_getstr (fmt);
13422 if (fmt_str == NULL)
13423 return NULL_TREE;
13425 if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13427 /* If we're using an unlocked function, assume the other
13428 unlocked functions exist explicitly. */
13429 fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
13430 fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
13432 else
13434 fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
13435 fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
13438 if (!init_target_chars ())
13439 return NULL_TREE;
13441 /* If the format doesn't contain % args or %%, use strcpy. */
13442 if (strchr (fmt_str, target_percent) == NULL)
13444 if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
13445 && arg)
13446 return NULL_TREE;
13448 /* If the format specifier was "", fprintf does nothing. */
13449 if (fmt_str[0] == '\0')
13451 /* If FP has side-effects, just wait until gimplification is
13452 done. */
13453 if (TREE_SIDE_EFFECTS (fp))
13454 return NULL_TREE;
13456 return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13459 /* When "string" doesn't contain %, replace all cases of
13460 fprintf (fp, string) with fputs (string, fp). The fputs
13461 builtin will take care of special cases like length == 1. */
13462 if (fn_fputs)
13463 call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
13466 /* The other optimizations can be done only on the non-va_list variants. */
13467 else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
13468 return NULL_TREE;
13470 /* If the format specifier was "%s", call __builtin_fputs (arg, fp). */
13471 else if (strcmp (fmt_str, target_percent_s) == 0)
13473 if (!arg || !validate_arg (arg, POINTER_TYPE))
13474 return NULL_TREE;
13475 if (fn_fputs)
13476 call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
13479 /* If the format specifier was "%c", call __builtin_fputc (arg, fp). */
13480 else if (strcmp (fmt_str, target_percent_c) == 0)
13482 if (!arg || !validate_arg (arg, INTEGER_TYPE))
13483 return NULL_TREE;
13484 if (fn_fputc)
13485 call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
13488 if (!call)
13489 return NULL_TREE;
13490 return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13493 /* Initialize format string characters in the target charset. */
13495 static bool
13496 init_target_chars (void)
13498 static bool init;
13499 if (!init)
13501 target_newline = lang_hooks.to_target_charset ('\n');
13502 target_percent = lang_hooks.to_target_charset ('%');
13503 target_c = lang_hooks.to_target_charset ('c');
13504 target_s = lang_hooks.to_target_charset ('s');
13505 if (target_newline == 0 || target_percent == 0 || target_c == 0
13506 || target_s == 0)
13507 return false;
13509 target_percent_c[0] = target_percent;
13510 target_percent_c[1] = target_c;
13511 target_percent_c[2] = '\0';
13513 target_percent_s[0] = target_percent;
13514 target_percent_s[1] = target_s;
13515 target_percent_s[2] = '\0';
13517 target_percent_s_newline[0] = target_percent;
13518 target_percent_s_newline[1] = target_s;
13519 target_percent_s_newline[2] = target_newline;
13520 target_percent_s_newline[3] = '\0';
13522 init = true;
13524 return true;
13527 /* Helper function for do_mpfr_arg*(). Ensure M is a normal number
13528 and no overflow/underflow occurred. INEXACT is true if M was not
13529 exactly calculated. TYPE is the tree type for the result. This
13530 function assumes that you cleared the MPFR flags and then
13531 calculated M to see if anything subsequently set a flag prior to
13532 entering this function. Return NULL_TREE if any checks fail. */
13534 static tree
13535 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13537 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13538 overflow/underflow occurred. If -frounding-math, proceed iff the
13539 result of calling FUNC was exact. */
13540 if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13541 && (!flag_rounding_math || !inexact))
13543 REAL_VALUE_TYPE rr;
13545 real_from_mpfr (&rr, m, type, GMP_RNDN);
13546 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13547 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13548 but the mpft_t is not, then we underflowed in the
13549 conversion. */
13550 if (real_isfinite (&rr)
13551 && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13553 REAL_VALUE_TYPE rmode;
13555 real_convert (&rmode, TYPE_MODE (type), &rr);
13556 /* Proceed iff the specified mode can hold the value. */
13557 if (real_identical (&rmode, &rr))
13558 return build_real (type, rmode);
13561 return NULL_TREE;
13564 /* Helper function for do_mpc_arg*(). Ensure M is a normal complex
13565 number and no overflow/underflow occurred. INEXACT is true if M
13566 was not exactly calculated. TYPE is the tree type for the result.
13567 This function assumes that you cleared the MPFR flags and then
13568 calculated M to see if anything subsequently set a flag prior to
13569 entering this function. Return NULL_TREE if any checks fail, if
13570 FORCE_CONVERT is true, then bypass the checks. */
13572 static tree
13573 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13575 /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13576 overflow/underflow occurred. If -frounding-math, proceed iff the
13577 result of calling FUNC was exact. */
13578 if (force_convert
13579 || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13580 && !mpfr_overflow_p () && !mpfr_underflow_p ()
13581 && (!flag_rounding_math || !inexact)))
13583 REAL_VALUE_TYPE re, im;
13585 real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN);
13586 real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN);
13587 /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13588 check for overflow/underflow. If the REAL_VALUE_TYPE is zero
13589 but the mpft_t is not, then we underflowed in the
13590 conversion. */
13591 if (force_convert
13592 || (real_isfinite (&re) && real_isfinite (&im)
13593 && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13594 && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13596 REAL_VALUE_TYPE re_mode, im_mode;
13598 real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13599 real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13600 /* Proceed iff the specified mode can hold the value. */
13601 if (force_convert
13602 || (real_identical (&re_mode, &re)
13603 && real_identical (&im_mode, &im)))
13604 return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13605 build_real (TREE_TYPE (type), im_mode));
13608 return NULL_TREE;
13611 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13612 FUNC on it and return the resulting value as a tree with type TYPE.
13613 If MIN and/or MAX are not NULL, then the supplied ARG must be
13614 within those bounds. If INCLUSIVE is true, then MIN/MAX are
13615 acceptable values, otherwise they are not. The mpfr precision is
13616 set to the precision of TYPE. We assume that function FUNC returns
13617 zero if the result could be calculated exactly within the requested
13618 precision. */
13620 static tree
13621 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13622 const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13623 bool inclusive)
13625 tree result = NULL_TREE;
13627 STRIP_NOPS (arg);
13629 /* To proceed, MPFR must exactly represent the target floating point
13630 format, which only happens when the target base equals two. */
13631 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13632 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13634 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13636 if (real_isfinite (ra)
13637 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13638 && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13640 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13641 const int prec = fmt->p;
13642 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13643 int inexact;
13644 mpfr_t m;
13646 mpfr_init2 (m, prec);
13647 mpfr_from_real (m, ra, GMP_RNDN);
13648 mpfr_clear_flags ();
13649 inexact = func (m, m, rnd);
13650 result = do_mpfr_ckconv (m, type, inexact);
13651 mpfr_clear (m);
13655 return result;
13658 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13659 FUNC on it and return the resulting value as a tree with type TYPE.
13660 The mpfr precision is set to the precision of TYPE. We assume that
13661 function FUNC returns zero if the result could be calculated
13662 exactly within the requested precision. */
13664 static tree
13665 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13666 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13668 tree result = NULL_TREE;
13670 STRIP_NOPS (arg1);
13671 STRIP_NOPS (arg2);
13673 /* To proceed, MPFR must exactly represent the target floating point
13674 format, which only happens when the target base equals two. */
13675 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13676 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13677 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13679 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13680 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13682 if (real_isfinite (ra1) && real_isfinite (ra2))
13684 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13685 const int prec = fmt->p;
13686 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13687 int inexact;
13688 mpfr_t m1, m2;
13690 mpfr_inits2 (prec, m1, m2, NULL);
13691 mpfr_from_real (m1, ra1, GMP_RNDN);
13692 mpfr_from_real (m2, ra2, GMP_RNDN);
13693 mpfr_clear_flags ();
13694 inexact = func (m1, m1, m2, rnd);
13695 result = do_mpfr_ckconv (m1, type, inexact);
13696 mpfr_clears (m1, m2, NULL);
13700 return result;
13703 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13704 FUNC on it and return the resulting value as a tree with type TYPE.
13705 The mpfr precision is set to the precision of TYPE. We assume that
13706 function FUNC returns zero if the result could be calculated
13707 exactly within the requested precision. */
13709 static tree
13710 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13711 int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13713 tree result = NULL_TREE;
13715 STRIP_NOPS (arg1);
13716 STRIP_NOPS (arg2);
13717 STRIP_NOPS (arg3);
13719 /* To proceed, MPFR must exactly represent the target floating point
13720 format, which only happens when the target base equals two. */
13721 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13722 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13723 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13724 && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13726 const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13727 const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13728 const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13730 if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13732 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13733 const int prec = fmt->p;
13734 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13735 int inexact;
13736 mpfr_t m1, m2, m3;
13738 mpfr_inits2 (prec, m1, m2, m3, NULL);
13739 mpfr_from_real (m1, ra1, GMP_RNDN);
13740 mpfr_from_real (m2, ra2, GMP_RNDN);
13741 mpfr_from_real (m3, ra3, GMP_RNDN);
13742 mpfr_clear_flags ();
13743 inexact = func (m1, m1, m2, m3, rnd);
13744 result = do_mpfr_ckconv (m1, type, inexact);
13745 mpfr_clears (m1, m2, m3, NULL);
13749 return result;
13752 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13753 the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13754 If ARG_SINP and ARG_COSP are NULL then the result is returned
13755 as a complex value.
13756 The type is taken from the type of ARG and is used for setting the
13757 precision of the calculation and results. */
13759 static tree
13760 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13762 tree const type = TREE_TYPE (arg);
13763 tree result = NULL_TREE;
13765 STRIP_NOPS (arg);
13767 /* To proceed, MPFR must exactly represent the target floating point
13768 format, which only happens when the target base equals two. */
13769 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13770 && TREE_CODE (arg) == REAL_CST
13771 && !TREE_OVERFLOW (arg))
13773 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13775 if (real_isfinite (ra))
13777 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13778 const int prec = fmt->p;
13779 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13780 tree result_s, result_c;
13781 int inexact;
13782 mpfr_t m, ms, mc;
13784 mpfr_inits2 (prec, m, ms, mc, NULL);
13785 mpfr_from_real (m, ra, GMP_RNDN);
13786 mpfr_clear_flags ();
13787 inexact = mpfr_sin_cos (ms, mc, m, rnd);
13788 result_s = do_mpfr_ckconv (ms, type, inexact);
13789 result_c = do_mpfr_ckconv (mc, type, inexact);
13790 mpfr_clears (m, ms, mc, NULL);
13791 if (result_s && result_c)
13793 /* If we are to return in a complex value do so. */
13794 if (!arg_sinp && !arg_cosp)
13795 return build_complex (build_complex_type (type),
13796 result_c, result_s);
13798 /* Dereference the sin/cos pointer arguments. */
13799 arg_sinp = build_fold_indirect_ref (arg_sinp);
13800 arg_cosp = build_fold_indirect_ref (arg_cosp);
13801 /* Proceed if valid pointer type were passed in. */
13802 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13803 && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13805 /* Set the values. */
13806 result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13807 result_s);
13808 TREE_SIDE_EFFECTS (result_s) = 1;
13809 result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13810 result_c);
13811 TREE_SIDE_EFFECTS (result_c) = 1;
13812 /* Combine the assignments into a compound expr. */
13813 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13814 result_s, result_c));
13819 return result;
13822 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13823 two-argument mpfr order N Bessel function FUNC on them and return
13824 the resulting value as a tree with type TYPE. The mpfr precision
13825 is set to the precision of TYPE. We assume that function FUNC
13826 returns zero if the result could be calculated exactly within the
13827 requested precision. */
13828 static tree
13829 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13830 int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13831 const REAL_VALUE_TYPE *min, bool inclusive)
13833 tree result = NULL_TREE;
13835 STRIP_NOPS (arg1);
13836 STRIP_NOPS (arg2);
13838 /* To proceed, MPFR must exactly represent the target floating point
13839 format, which only happens when the target base equals two. */
13840 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13841 && host_integerp (arg1, 0)
13842 && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13844 const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13845 const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13847 if (n == (long)n
13848 && real_isfinite (ra)
13849 && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13851 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13852 const int prec = fmt->p;
13853 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13854 int inexact;
13855 mpfr_t m;
13857 mpfr_init2 (m, prec);
13858 mpfr_from_real (m, ra, GMP_RNDN);
13859 mpfr_clear_flags ();
13860 inexact = func (m, n, m, rnd);
13861 result = do_mpfr_ckconv (m, type, inexact);
13862 mpfr_clear (m);
13866 return result;
13869 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13870 the pointer *(ARG_QUO) and return the result. The type is taken
13871 from the type of ARG0 and is used for setting the precision of the
13872 calculation and results. */
13874 static tree
13875 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13877 tree const type = TREE_TYPE (arg0);
13878 tree result = NULL_TREE;
13880 STRIP_NOPS (arg0);
13881 STRIP_NOPS (arg1);
13883 /* To proceed, MPFR must exactly represent the target floating point
13884 format, which only happens when the target base equals two. */
13885 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13886 && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13887 && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13889 const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13890 const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13892 if (real_isfinite (ra0) && real_isfinite (ra1))
13894 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13895 const int prec = fmt->p;
13896 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13897 tree result_rem;
13898 long integer_quo;
13899 mpfr_t m0, m1;
13901 mpfr_inits2 (prec, m0, m1, NULL);
13902 mpfr_from_real (m0, ra0, GMP_RNDN);
13903 mpfr_from_real (m1, ra1, GMP_RNDN);
13904 mpfr_clear_flags ();
13905 mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13906 /* Remquo is independent of the rounding mode, so pass
13907 inexact=0 to do_mpfr_ckconv(). */
13908 result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13909 mpfr_clears (m0, m1, NULL);
13910 if (result_rem)
13912 /* MPFR calculates quo in the host's long so it may
13913 return more bits in quo than the target int can hold
13914 if sizeof(host long) > sizeof(target int). This can
13915 happen even for native compilers in LP64 mode. In
13916 these cases, modulo the quo value with the largest
13917 number that the target int can hold while leaving one
13918 bit for the sign. */
13919 if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13920 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13922 /* Dereference the quo pointer argument. */
13923 arg_quo = build_fold_indirect_ref (arg_quo);
13924 /* Proceed iff a valid pointer type was passed in. */
13925 if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13927 /* Set the value. */
13928 tree result_quo
13929 = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo,
13930 build_int_cst (TREE_TYPE (arg_quo),
13931 integer_quo));
13932 TREE_SIDE_EFFECTS (result_quo) = 1;
13933 /* Combine the quo assignment with the rem. */
13934 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13935 result_quo, result_rem));
13940 return result;
13943 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13944 resulting value as a tree with type TYPE. The mpfr precision is
13945 set to the precision of TYPE. We assume that this mpfr function
13946 returns zero if the result could be calculated exactly within the
13947 requested precision. In addition, the integer pointer represented
13948 by ARG_SG will be dereferenced and set to the appropriate signgam
13949 (-1,1) value. */
13951 static tree
13952 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13954 tree result = NULL_TREE;
13956 STRIP_NOPS (arg);
13958 /* To proceed, MPFR must exactly represent the target floating point
13959 format, which only happens when the target base equals two. Also
13960 verify ARG is a constant and that ARG_SG is an int pointer. */
13961 if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13962 && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13963 && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13964 && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13966 const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13968 /* In addition to NaN and Inf, the argument cannot be zero or a
13969 negative integer. */
13970 if (real_isfinite (ra)
13971 && ra->cl != rvc_zero
13972 && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13974 const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13975 const int prec = fmt->p;
13976 const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13977 int inexact, sg;
13978 mpfr_t m;
13979 tree result_lg;
13981 mpfr_init2 (m, prec);
13982 mpfr_from_real (m, ra, GMP_RNDN);
13983 mpfr_clear_flags ();
13984 inexact = mpfr_lgamma (m, &sg, m, rnd);
13985 result_lg = do_mpfr_ckconv (m, type, inexact);
13986 mpfr_clear (m);
13987 if (result_lg)
13989 tree result_sg;
13991 /* Dereference the arg_sg pointer argument. */
13992 arg_sg = build_fold_indirect_ref (arg_sg);
13993 /* Assign the signgam value into *arg_sg. */
13994 result_sg = fold_build2 (MODIFY_EXPR,
13995 TREE_TYPE (arg_sg), arg_sg,
13996 build_int_cst (TREE_TYPE (arg_sg), sg));
13997 TREE_SIDE_EFFECTS (result_sg) = 1;
13998 /* Combine the signgam assignment with the lgamma result. */
13999 result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
14000 result_sg, result_lg));
14005 return result;
14008 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc
14009 function FUNC on it and return the resulting value as a tree with
14010 type TYPE. The mpfr precision is set to the precision of TYPE. We
14011 assume that function FUNC returns zero if the result could be
14012 calculated exactly within the requested precision. */
14014 static tree
14015 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
14017 tree result = NULL_TREE;
14019 STRIP_NOPS (arg);
14021 /* To proceed, MPFR must exactly represent the target floating point
14022 format, which only happens when the target base equals two. */
14023 if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
14024 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
14025 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
14027 const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
14028 const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
14030 if (real_isfinite (re) && real_isfinite (im))
14032 const struct real_format *const fmt =
14033 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14034 const int prec = fmt->p;
14035 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14036 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14037 int inexact;
14038 mpc_t m;
14040 mpc_init2 (m, prec);
14041 mpfr_from_real (mpc_realref(m), re, rnd);
14042 mpfr_from_real (mpc_imagref(m), im, rnd);
14043 mpfr_clear_flags ();
14044 inexact = func (m, m, crnd);
14045 result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
14046 mpc_clear (m);
14050 return result;
14053 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
14054 mpc function FUNC on it and return the resulting value as a tree
14055 with type TYPE. The mpfr precision is set to the precision of
14056 TYPE. We assume that function FUNC returns zero if the result
14057 could be calculated exactly within the requested precision. If
14058 DO_NONFINITE is true, then fold expressions containing Inf or NaN
14059 in the arguments and/or results. */
14061 tree
14062 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
14063 int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
14065 tree result = NULL_TREE;
14067 STRIP_NOPS (arg0);
14068 STRIP_NOPS (arg1);
14070 /* To proceed, MPFR must exactly represent the target floating point
14071 format, which only happens when the target base equals two. */
14072 if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
14073 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
14074 && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
14075 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
14076 && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
14078 const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
14079 const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
14080 const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
14081 const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
14083 if (do_nonfinite
14084 || (real_isfinite (re0) && real_isfinite (im0)
14085 && real_isfinite (re1) && real_isfinite (im1)))
14087 const struct real_format *const fmt =
14088 REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14089 const int prec = fmt->p;
14090 const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14091 const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14092 int inexact;
14093 mpc_t m0, m1;
14095 mpc_init2 (m0, prec);
14096 mpc_init2 (m1, prec);
14097 mpfr_from_real (mpc_realref(m0), re0, rnd);
14098 mpfr_from_real (mpc_imagref(m0), im0, rnd);
14099 mpfr_from_real (mpc_realref(m1), re1, rnd);
14100 mpfr_from_real (mpc_imagref(m1), im1, rnd);
14101 mpfr_clear_flags ();
14102 inexact = func (m0, m0, m1, crnd);
14103 result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
14104 mpc_clear (m0);
14105 mpc_clear (m1);
14109 return result;
14112 /* Fold a call STMT to __{,v}sprintf_chk. Return NULL_TREE if
14113 a normal call should be emitted rather than expanding the function
14114 inline. FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK. */
14116 static tree
14117 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
14119 int nargs = gimple_call_num_args (stmt);
14121 return fold_builtin_sprintf_chk_1 (gimple_location (stmt), nargs,
14122 (nargs > 0
14123 ? gimple_call_arg_ptr (stmt, 0)
14124 : &error_mark_node), fcode);
14127 /* Fold a call STMT to {,v}snprintf. Return NULL_TREE if
14128 a normal call should be emitted rather than expanding the function
14129 inline. FCODE is either BUILT_IN_SNPRINTF_CHK or
14130 BUILT_IN_VSNPRINTF_CHK. If MAXLEN is not NULL, it is maximum length
14131 passed as second argument. */
14133 tree
14134 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14135 enum built_in_function fcode)
14137 int nargs = gimple_call_num_args (stmt);
14139 return fold_builtin_snprintf_chk_1 (gimple_location (stmt), nargs,
14140 (nargs > 0
14141 ? gimple_call_arg_ptr (stmt, 0)
14142 : &error_mark_node), maxlen, fcode);
14145 /* Builtins with folding operations that operate on "..." arguments
14146 need special handling; we need to store the arguments in a convenient
14147 data structure before attempting any folding. Fortunately there are
14148 only a few builtins that fall into this category. FNDECL is the
14149 function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14150 result of the function call is ignored. */
14152 static tree
14153 gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14154 bool ignore ATTRIBUTE_UNUSED)
14156 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14157 tree ret = NULL_TREE;
14159 switch (fcode)
14161 case BUILT_IN_SPRINTF_CHK:
14162 case BUILT_IN_VSPRINTF_CHK:
14163 ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14164 break;
14166 case BUILT_IN_SNPRINTF_CHK:
14167 case BUILT_IN_VSNPRINTF_CHK:
14168 ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14170 default:
14171 break;
14173 if (ret)
14175 ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14176 TREE_NO_WARNING (ret) = 1;
14177 return ret;
14179 return NULL_TREE;
14182 /* A wrapper function for builtin folding that prevents warnings for
14183 "statement without effect" and the like, caused by removing the
14184 call node earlier than the warning is generated. */
14186 tree
14187 fold_call_stmt (gimple stmt, bool ignore)
14189 tree ret = NULL_TREE;
14190 tree fndecl = gimple_call_fndecl (stmt);
14191 location_t loc = gimple_location (stmt);
14192 if (fndecl
14193 && TREE_CODE (fndecl) == FUNCTION_DECL
14194 && DECL_BUILT_IN (fndecl)
14195 && !gimple_call_va_arg_pack_p (stmt))
14197 int nargs = gimple_call_num_args (stmt);
14198 tree *args = (nargs > 0
14199 ? gimple_call_arg_ptr (stmt, 0)
14200 : &error_mark_node);
14202 if (avoid_folding_inline_builtin (fndecl))
14203 return NULL_TREE;
14204 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14206 return targetm.fold_builtin (fndecl, nargs, args, ignore);
14208 else
14210 if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14211 ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
14212 if (!ret)
14213 ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14214 if (ret)
14216 /* Propagate location information from original call to
14217 expansion of builtin. Otherwise things like
14218 maybe_emit_chk_warning, that operate on the expansion
14219 of a builtin, will use the wrong location information. */
14220 if (gimple_has_location (stmt))
14222 tree realret = ret;
14223 if (TREE_CODE (ret) == NOP_EXPR)
14224 realret = TREE_OPERAND (ret, 0);
14225 if (CAN_HAVE_LOCATION_P (realret)
14226 && !EXPR_HAS_LOCATION (realret))
14227 SET_EXPR_LOCATION (realret, loc);
14228 return realret;
14230 return ret;
14234 return NULL_TREE;
14237 /* Look up the function in builtin_decl that corresponds to DECL
14238 and set ASMSPEC as its user assembler name. DECL must be a
14239 function decl that declares a builtin. */
14241 void
14242 set_builtin_user_assembler_name (tree decl, const char *asmspec)
14244 tree builtin;
14245 gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
14246 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
14247 && asmspec != 0);
14249 builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
14250 set_user_assembler_name (builtin, asmspec);
14251 switch (DECL_FUNCTION_CODE (decl))
14253 case BUILT_IN_MEMCPY:
14254 init_block_move_fn (asmspec);
14255 memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
14256 break;
14257 case BUILT_IN_MEMSET:
14258 init_block_clear_fn (asmspec);
14259 memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
14260 break;
14261 case BUILT_IN_MEMMOVE:
14262 memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
14263 break;
14264 case BUILT_IN_MEMCMP:
14265 memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
14266 break;
14267 case BUILT_IN_ABORT:
14268 abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
14269 break;
14270 case BUILT_IN_FFS:
14271 if (INT_TYPE_SIZE < BITS_PER_WORD)
14273 set_user_assembler_libfunc ("ffs", asmspec);
14274 set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
14275 MODE_INT, 0), "ffs");
14277 break;
14278 default:
14279 break;
14283 /* Return true if DECL is a builtin that expands to a constant or similarly
14284 simple code. */
14285 bool
14286 is_simple_builtin (tree decl)
14288 if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14289 switch (DECL_FUNCTION_CODE (decl))
14291 /* Builtins that expand to constants. */
14292 case BUILT_IN_CONSTANT_P:
14293 case BUILT_IN_EXPECT:
14294 case BUILT_IN_OBJECT_SIZE:
14295 case BUILT_IN_UNREACHABLE:
14296 /* Simple register moves or loads from stack. */
14297 case BUILT_IN_ASSUME_ALIGNED:
14298 case BUILT_IN_RETURN_ADDRESS:
14299 case BUILT_IN_EXTRACT_RETURN_ADDR:
14300 case BUILT_IN_FROB_RETURN_ADDR:
14301 case BUILT_IN_RETURN:
14302 case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
14303 case BUILT_IN_FRAME_ADDRESS:
14304 case BUILT_IN_VA_END:
14305 case BUILT_IN_STACK_SAVE:
14306 case BUILT_IN_STACK_RESTORE:
14307 /* Exception state returns or moves registers around. */
14308 case BUILT_IN_EH_FILTER:
14309 case BUILT_IN_EH_POINTER:
14310 case BUILT_IN_EH_COPY_VALUES:
14311 return true;
14313 default:
14314 return false;
14317 return false;
14320 /* Return true if DECL is a builtin that is not expensive, i.e., they are
14321 most probably expanded inline into reasonably simple code. This is a
14322 superset of is_simple_builtin. */
14323 bool
14324 is_inexpensive_builtin (tree decl)
14326 if (!decl)
14327 return false;
14328 else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
14329 return true;
14330 else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14331 switch (DECL_FUNCTION_CODE (decl))
14333 case BUILT_IN_ABS:
14334 case BUILT_IN_ALLOCA:
14335 case BUILT_IN_ALLOCA_WITH_ALIGN:
14336 case BUILT_IN_BSWAP16:
14337 case BUILT_IN_BSWAP32:
14338 case BUILT_IN_BSWAP64:
14339 case BUILT_IN_CLZ:
14340 case BUILT_IN_CLZIMAX:
14341 case BUILT_IN_CLZL:
14342 case BUILT_IN_CLZLL:
14343 case BUILT_IN_CTZ:
14344 case BUILT_IN_CTZIMAX:
14345 case BUILT_IN_CTZL:
14346 case BUILT_IN_CTZLL:
14347 case BUILT_IN_FFS:
14348 case BUILT_IN_FFSIMAX:
14349 case BUILT_IN_FFSL:
14350 case BUILT_IN_FFSLL:
14351 case BUILT_IN_IMAXABS:
14352 case BUILT_IN_FINITE:
14353 case BUILT_IN_FINITEF:
14354 case BUILT_IN_FINITEL:
14355 case BUILT_IN_FINITED32:
14356 case BUILT_IN_FINITED64:
14357 case BUILT_IN_FINITED128:
14358 case BUILT_IN_FPCLASSIFY:
14359 case BUILT_IN_ISFINITE:
14360 case BUILT_IN_ISINF_SIGN:
14361 case BUILT_IN_ISINF:
14362 case BUILT_IN_ISINFF:
14363 case BUILT_IN_ISINFL:
14364 case BUILT_IN_ISINFD32:
14365 case BUILT_IN_ISINFD64:
14366 case BUILT_IN_ISINFD128:
14367 case BUILT_IN_ISNAN:
14368 case BUILT_IN_ISNANF:
14369 case BUILT_IN_ISNANL:
14370 case BUILT_IN_ISNAND32:
14371 case BUILT_IN_ISNAND64:
14372 case BUILT_IN_ISNAND128:
14373 case BUILT_IN_ISNORMAL:
14374 case BUILT_IN_ISGREATER:
14375 case BUILT_IN_ISGREATEREQUAL:
14376 case BUILT_IN_ISLESS:
14377 case BUILT_IN_ISLESSEQUAL:
14378 case BUILT_IN_ISLESSGREATER:
14379 case BUILT_IN_ISUNORDERED:
14380 case BUILT_IN_VA_ARG_PACK:
14381 case BUILT_IN_VA_ARG_PACK_LEN:
14382 case BUILT_IN_VA_COPY:
14383 case BUILT_IN_TRAP:
14384 case BUILT_IN_SAVEREGS:
14385 case BUILT_IN_POPCOUNTL:
14386 case BUILT_IN_POPCOUNTLL:
14387 case BUILT_IN_POPCOUNTIMAX:
14388 case BUILT_IN_POPCOUNT:
14389 case BUILT_IN_PARITYL:
14390 case BUILT_IN_PARITYLL:
14391 case BUILT_IN_PARITYIMAX:
14392 case BUILT_IN_PARITY:
14393 case BUILT_IN_LABS:
14394 case BUILT_IN_LLABS:
14395 case BUILT_IN_PREFETCH:
14396 return true;
14398 default:
14399 return is_simple_builtin (decl);
14402 return false;