OSDN Git Service

2012-02-10 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
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.
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>.  */
21
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"
53
54
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));
59
60 struct target_builtins default_target_builtins;
61 #if SWITCHABLE_TARGET
62 struct target_builtins *this_target_builtins = &default_target_builtins;
63 #endif
64
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"};
68
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] =
71 {
72 #include "builtins.def"
73 };
74 #undef DEF_BUILTIN
75
76 /* Setup an array of _DECL trees, make sure each element is
77    initialized to NULL_TREE.  */
78 builtin_info_type builtin_info;
79
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);
181
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);
191
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);
206
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);
227
228 /* Return true if NAME starts with __builtin_ or __sync_.  */
229
230 static bool
231 is_builtin_name (const char *name)
232 {
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;
240 }
241
242
243 /* Return true if DECL is a function symbol representing a built-in.  */
244
245 bool
246 is_builtin_fn (tree decl)
247 {
248   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
249 }
250
251
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".  */
255
256 static bool
257 called_as_built_in (tree node)
258 {
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);
264 }
265
266 /* Compute values M and N such that M divides (address of EXP - N) and
267    such that N < M.  Store N in *BITPOSP and return M.
268
269    Note that the address (and thus the alignment) computed here is based
270    on the address to which a symbol resolves, whereas DECL_ALIGN is based
271    on the address at which an object is actually located.  These two
272    addresses are not always the same.  For example, on ARM targets,
273    the address &foo of a Thumb function foo() has the lowest bit set,
274    whereas foo() itself starts on an even address.  */
275
276 unsigned int
277 get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
278 {
279   HOST_WIDE_INT bitsize, bitpos;
280   tree offset;
281   enum machine_mode mode;
282   int unsignedp, volatilep;
283   unsigned int align, inner;
284
285   /* Get the innermost object and the constant (bitpos) and possibly
286      variable (offset) offset of the access.  */
287   exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
288                              &mode, &unsignedp, &volatilep, true);
289
290   /* Extract alignment information from the innermost object and
291      possibly adjust bitpos and offset.  */
292   if (TREE_CODE (exp) == CONST_DECL)
293     exp = DECL_INITIAL (exp);
294   if (DECL_P (exp)
295       && TREE_CODE (exp) != LABEL_DECL)
296     {
297       if (TREE_CODE (exp) == FUNCTION_DECL)
298         {
299           /* Function addresses can encode extra information besides their
300              alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
301              allows the low bit to be used as a virtual bit, we know
302              that the address itself must be 2-byte aligned.  */
303           if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
304             align = 2 * BITS_PER_UNIT;
305           else
306             align = BITS_PER_UNIT;
307         }
308       else
309         align = DECL_ALIGN (exp);
310     }
311   else if (CONSTANT_CLASS_P (exp))
312     {
313       align = TYPE_ALIGN (TREE_TYPE (exp));
314 #ifdef CONSTANT_ALIGNMENT
315       align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
316 #endif
317     }
318   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
319     align = TYPE_ALIGN (TREE_TYPE (exp));
320   else if (TREE_CODE (exp) == INDIRECT_REF)
321     align = TYPE_ALIGN (TREE_TYPE (exp));
322   else if (TREE_CODE (exp) == MEM_REF)
323     {
324       tree addr = TREE_OPERAND (exp, 0);
325       struct ptr_info_def *pi;
326       if (TREE_CODE (addr) == BIT_AND_EXPR
327           && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
328         {
329           align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
330                     & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
331           align *= BITS_PER_UNIT;
332           addr = TREE_OPERAND (addr, 0);
333         }
334       else
335         align = BITS_PER_UNIT;
336       if (TREE_CODE (addr) == SSA_NAME
337           && (pi = SSA_NAME_PTR_INFO (addr)))
338         {
339           bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
340           align = MAX (pi->align * BITS_PER_UNIT, align);
341         }
342       else if (TREE_CODE (addr) == ADDR_EXPR)
343         align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
344       bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
345     }
346   else if (TREE_CODE (exp) == TARGET_MEM_REF)
347     {
348       struct ptr_info_def *pi;
349       tree addr = TMR_BASE (exp);
350       if (TREE_CODE (addr) == BIT_AND_EXPR
351           && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
352         {
353           align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
354                    & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
355           align *= BITS_PER_UNIT;
356           addr = TREE_OPERAND (addr, 0);
357         }
358       else
359         align = BITS_PER_UNIT;
360       if (TREE_CODE (addr) == SSA_NAME
361           && (pi = SSA_NAME_PTR_INFO (addr)))
362         {
363           bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
364           align = MAX (pi->align * BITS_PER_UNIT, align);
365         }
366       else if (TREE_CODE (addr) == ADDR_EXPR)
367         align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
368       if (TMR_OFFSET (exp))
369         bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
370       if (TMR_INDEX (exp) && TMR_STEP (exp))
371         {
372           unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
373           align = MIN (align, (step & -step) * BITS_PER_UNIT);
374         }
375       else if (TMR_INDEX (exp))
376         align = BITS_PER_UNIT;
377       if (TMR_INDEX2 (exp))
378         align = BITS_PER_UNIT;
379     }
380   else
381     align = BITS_PER_UNIT;
382
383   /* If there is a non-constant offset part extract the maximum
384      alignment that can prevail.  */
385   inner = ~0U;
386   while (offset)
387     {
388       tree next_offset;
389
390       if (TREE_CODE (offset) == PLUS_EXPR)
391         {
392           next_offset = TREE_OPERAND (offset, 0);
393           offset = TREE_OPERAND (offset, 1);
394         }
395       else
396         next_offset = NULL;
397       if (host_integerp (offset, 1))
398         {
399           /* Any overflow in calculating offset_bits won't change
400              the alignment.  */
401           unsigned offset_bits
402             = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
403
404           if (offset_bits)
405             inner = MIN (inner, (offset_bits & -offset_bits));
406         }
407       else if (TREE_CODE (offset) == MULT_EXPR
408                && host_integerp (TREE_OPERAND (offset, 1), 1))
409         {
410           /* Any overflow in calculating offset_factor won't change
411              the alignment.  */
412           unsigned offset_factor
413             = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
414                * BITS_PER_UNIT);
415
416           if (offset_factor)
417             inner = MIN (inner, (offset_factor & -offset_factor));
418         }
419       else
420         {
421           inner = MIN (inner, BITS_PER_UNIT);
422           break;
423         }
424       offset = next_offset;
425     }
426
427   /* Alignment is innermost object alignment adjusted by the constant
428      and non-constant offset parts.  */
429   align = MIN (align, inner);
430   bitpos = bitpos & (align - 1);
431
432   *bitposp = bitpos;
433   return align;
434 }
435
436 /* Return the alignment in bits of EXP, an object.  */
437
438 unsigned int
439 get_object_alignment (tree exp)
440 {
441   unsigned HOST_WIDE_INT bitpos = 0;
442   unsigned int align;
443
444   align = get_object_alignment_1 (exp, &bitpos);
445
446   /* align and bitpos now specify known low bits of the pointer.
447      ptr & (align - 1) == bitpos.  */
448
449   if (bitpos != 0)
450     align = (bitpos & -bitpos);
451
452   return align;
453 }
454
455 /* Return the alignment of object EXP, also considering its type when we do
456    not know of explicit misalignment.  Only handle MEM_REF and TARGET_MEM_REF.
457
458    ??? Note that, in the general case, the type of an expression is not kept
459    consistent with misalignment information by the front-end, for example when
460    taking the address of a member of a packed structure.  However, in most of
461    the cases, expressions have the alignment of their type so we optimistically
462    fall back to this alignment when we cannot compute a misalignment.  */
463
464 unsigned int
465 get_object_or_type_alignment (tree exp)
466 {
467   unsigned HOST_WIDE_INT misalign;
468   unsigned int align = get_object_alignment_1 (exp, &misalign);
469
470   gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
471
472   if (misalign != 0)
473     align = (misalign & -misalign);
474   else
475     align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
476
477   return align;
478 }
479
480 /* For a pointer valued expression EXP compute values M and N such that
481    M divides (EXP - N) and such that N < M.  Store N in *BITPOSP and return M.
482
483    If EXP is not a pointer, 0 is returned.  */
484
485 unsigned int
486 get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
487 {
488   STRIP_NOPS (exp);
489
490   if (TREE_CODE (exp) == ADDR_EXPR)
491     return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
492   else if (TREE_CODE (exp) == SSA_NAME
493            && POINTER_TYPE_P (TREE_TYPE (exp)))
494     {
495       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
496       if (!pi)
497         {
498           *bitposp = 0;
499           return BITS_PER_UNIT;
500         }
501       *bitposp = pi->misalign * BITS_PER_UNIT;
502       return pi->align * BITS_PER_UNIT;
503     }
504
505   *bitposp = 0;
506   return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
507 }
508
509 /* Return the alignment in bits of EXP, a pointer valued expression.
510    The alignment returned is, by default, the alignment of the thing that
511    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
512
513    Otherwise, look at the expression to see if we can do better, i.e., if the
514    expression is actually pointing at an object whose alignment is tighter.  */
515
516 unsigned int
517 get_pointer_alignment (tree exp)
518 {
519   unsigned HOST_WIDE_INT bitpos = 0;
520   unsigned int align;
521   
522   align = get_pointer_alignment_1 (exp, &bitpos);
523
524   /* align and bitpos now specify known low bits of the pointer.
525      ptr & (align - 1) == bitpos.  */
526
527   if (bitpos != 0)
528     align = (bitpos & -bitpos);
529
530   return align;
531 }
532
533 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
534    way, because it could contain a zero byte in the middle.
535    TREE_STRING_LENGTH is the size of the character array, not the string.
536
537    ONLY_VALUE should be nonzero if the result is not going to be emitted
538    into the instruction stream and zero if it is going to be expanded.
539    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
540    is returned, otherwise NULL, since
541    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
542    evaluate the side-effects.
543
544    The value returned is of type `ssizetype'.
545
546    Unfortunately, string_constant can't access the values of const char
547    arrays with initializers, so neither can we do so here.  */
548
549 tree
550 c_strlen (tree src, int only_value)
551 {
552   tree offset_node;
553   HOST_WIDE_INT offset;
554   int max;
555   const char *ptr;
556   location_t loc;
557
558   STRIP_NOPS (src);
559   if (TREE_CODE (src) == COND_EXPR
560       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
561     {
562       tree len1, len2;
563
564       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
565       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
566       if (tree_int_cst_equal (len1, len2))
567         return len1;
568     }
569
570   if (TREE_CODE (src) == COMPOUND_EXPR
571       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
572     return c_strlen (TREE_OPERAND (src, 1), only_value);
573
574   loc = EXPR_LOC_OR_HERE (src);
575
576   src = string_constant (src, &offset_node);
577   if (src == 0)
578     return NULL_TREE;
579
580   max = TREE_STRING_LENGTH (src) - 1;
581   ptr = TREE_STRING_POINTER (src);
582
583   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
584     {
585       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
586          compute the offset to the following null if we don't know where to
587          start searching for it.  */
588       int i;
589
590       for (i = 0; i < max; i++)
591         if (ptr[i] == 0)
592           return NULL_TREE;
593
594       /* We don't know the starting offset, but we do know that the string
595          has no internal zero bytes.  We can assume that the offset falls
596          within the bounds of the string; otherwise, the programmer deserves
597          what he gets.  Subtract the offset from the length of the string,
598          and return that.  This would perhaps not be valid if we were dealing
599          with named arrays in addition to literal string constants.  */
600
601       return size_diffop_loc (loc, size_int (max), offset_node);
602     }
603
604   /* We have a known offset into the string.  Start searching there for
605      a null character if we can represent it as a single HOST_WIDE_INT.  */
606   if (offset_node == 0)
607     offset = 0;
608   else if (! host_integerp (offset_node, 0))
609     offset = -1;
610   else
611     offset = tree_low_cst (offset_node, 0);
612
613   /* If the offset is known to be out of bounds, warn, and call strlen at
614      runtime.  */
615   if (offset < 0 || offset > max)
616     {
617      /* Suppress multiple warnings for propagated constant strings.  */
618       if (! TREE_NO_WARNING (src))
619         {
620           warning_at (loc, 0, "offset outside bounds of constant string");
621           TREE_NO_WARNING (src) = 1;
622         }
623       return NULL_TREE;
624     }
625
626   /* Use strlen to search for the first zero byte.  Since any strings
627      constructed with build_string will have nulls appended, we win even
628      if we get handed something like (char[4])"abcd".
629
630      Since OFFSET is our starting index into the string, no further
631      calculation is needed.  */
632   return ssize_int (strlen (ptr + offset));
633 }
634
635 /* Return a char pointer for a C string if it is a string constant
636    or sum of string constant and integer constant.  */
637
638 static const char *
639 c_getstr (tree src)
640 {
641   tree offset_node;
642
643   src = string_constant (src, &offset_node);
644   if (src == 0)
645     return 0;
646
647   if (offset_node == 0)
648     return TREE_STRING_POINTER (src);
649   else if (!host_integerp (offset_node, 1)
650            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
651     return 0;
652
653   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
654 }
655
656 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
657    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
658
659 static rtx
660 c_readstr (const char *str, enum machine_mode mode)
661 {
662   HOST_WIDE_INT c[2];
663   HOST_WIDE_INT ch;
664   unsigned int i, j;
665
666   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
667
668   c[0] = 0;
669   c[1] = 0;
670   ch = 1;
671   for (i = 0; i < GET_MODE_SIZE (mode); i++)
672     {
673       j = i;
674       if (WORDS_BIG_ENDIAN)
675         j = GET_MODE_SIZE (mode) - i - 1;
676       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
677           && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
678         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
679       j *= BITS_PER_UNIT;
680       gcc_assert (j < 2 * HOST_BITS_PER_WIDE_INT);
681
682       if (ch)
683         ch = (unsigned char) str[i];
684       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
685     }
686   return immed_double_const (c[0], c[1], mode);
687 }
688
689 /* Cast a target constant CST to target CHAR and if that value fits into
690    host char type, return zero and put that value into variable pointed to by
691    P.  */
692
693 static int
694 target_char_cast (tree cst, char *p)
695 {
696   unsigned HOST_WIDE_INT val, hostval;
697
698   if (TREE_CODE (cst) != INTEGER_CST
699       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
700     return 1;
701
702   val = TREE_INT_CST_LOW (cst);
703   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
704     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
705
706   hostval = val;
707   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
708     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
709
710   if (val != hostval)
711     return 1;
712
713   *p = hostval;
714   return 0;
715 }
716
717 /* Similar to save_expr, but assumes that arbitrary code is not executed
718    in between the multiple evaluations.  In particular, we assume that a
719    non-addressable local variable will not be modified.  */
720
721 static tree
722 builtin_save_expr (tree exp)
723 {
724   if (TREE_CODE (exp) == SSA_NAME
725       || (TREE_ADDRESSABLE (exp) == 0
726           && (TREE_CODE (exp) == PARM_DECL
727               || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))))
728     return exp;
729
730   return save_expr (exp);
731 }
732
733 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
734    times to get the address of either a higher stack frame, or a return
735    address located within it (depending on FNDECL_CODE).  */
736
737 static rtx
738 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
739 {
740   int i;
741
742 #ifdef INITIAL_FRAME_ADDRESS_RTX
743   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
744 #else
745   rtx tem;
746
747   /* For a zero count with __builtin_return_address, we don't care what
748      frame address we return, because target-specific definitions will
749      override us.  Therefore frame pointer elimination is OK, and using
750      the soft frame pointer is OK.
751
752      For a nonzero count, or a zero count with __builtin_frame_address,
753      we require a stable offset from the current frame pointer to the
754      previous one, so we must use the hard frame pointer, and
755      we must disable frame pointer elimination.  */
756   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
757     tem = frame_pointer_rtx;
758   else
759     {
760       tem = hard_frame_pointer_rtx;
761
762       /* Tell reload not to eliminate the frame pointer.  */
763       crtl->accesses_prior_frames = 1;
764     }
765 #endif
766
767   /* Some machines need special handling before we can access
768      arbitrary frames.  For example, on the SPARC, we must first flush
769      all register windows to the stack.  */
770 #ifdef SETUP_FRAME_ADDRESSES
771   if (count > 0)
772     SETUP_FRAME_ADDRESSES ();
773 #endif
774
775   /* On the SPARC, the return address is not in the frame, it is in a
776      register.  There is no way to access it off of the current frame
777      pointer, but it can be accessed off the previous frame pointer by
778      reading the value from the register window save area.  */
779 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
780   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
781     count--;
782 #endif
783
784   /* Scan back COUNT frames to the specified frame.  */
785   for (i = 0; i < count; i++)
786     {
787       /* Assume the dynamic chain pointer is in the word that the
788          frame address points to, unless otherwise specified.  */
789 #ifdef DYNAMIC_CHAIN_ADDRESS
790       tem = DYNAMIC_CHAIN_ADDRESS (tem);
791 #endif
792       tem = memory_address (Pmode, tem);
793       tem = gen_frame_mem (Pmode, tem);
794       tem = copy_to_reg (tem);
795     }
796
797   /* For __builtin_frame_address, return what we've got.  But, on
798      the SPARC for example, we may have to add a bias.  */
799   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
800 #ifdef FRAME_ADDR_RTX
801     return FRAME_ADDR_RTX (tem);
802 #else
803     return tem;
804 #endif
805
806   /* For __builtin_return_address, get the return address from that frame.  */
807 #ifdef RETURN_ADDR_RTX
808   tem = RETURN_ADDR_RTX (count, tem);
809 #else
810   tem = memory_address (Pmode,
811                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
812   tem = gen_frame_mem (Pmode, tem);
813 #endif
814   return tem;
815 }
816
817 /* Alias set used for setjmp buffer.  */
818 static alias_set_type setjmp_alias_set = -1;
819
820 /* Construct the leading half of a __builtin_setjmp call.  Control will
821    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
822    exception handling code.  */
823
824 void
825 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
826 {
827   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
828   rtx stack_save;
829   rtx mem;
830
831   if (setjmp_alias_set == -1)
832     setjmp_alias_set = new_alias_set ();
833
834   buf_addr = convert_memory_address (Pmode, buf_addr);
835
836   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
837
838   /* We store the frame pointer and the address of receiver_label in
839      the buffer and use the rest of it for the stack save area, which
840      is machine-dependent.  */
841
842   mem = gen_rtx_MEM (Pmode, buf_addr);
843   set_mem_alias_set (mem, setjmp_alias_set);
844   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
845
846   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
847   set_mem_alias_set (mem, setjmp_alias_set);
848
849   emit_move_insn (validize_mem (mem),
850                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
851
852   stack_save = gen_rtx_MEM (sa_mode,
853                             plus_constant (buf_addr,
854                                            2 * GET_MODE_SIZE (Pmode)));
855   set_mem_alias_set (stack_save, setjmp_alias_set);
856   emit_stack_save (SAVE_NONLOCAL, &stack_save);
857
858   /* If there is further processing to do, do it.  */
859 #ifdef HAVE_builtin_setjmp_setup
860   if (HAVE_builtin_setjmp_setup)
861     emit_insn (gen_builtin_setjmp_setup (buf_addr));
862 #endif
863
864   /* We have a nonlocal label.   */
865   cfun->has_nonlocal_label = 1;
866 }
867
868 /* Construct the trailing part of a __builtin_setjmp call.  This is
869    also called directly by the SJLJ exception handling code.  */
870
871 void
872 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
873 {
874   rtx chain;
875
876   /* Clobber the FP when we get here, so we have to make sure it's
877      marked as used by this function.  */
878   emit_use (hard_frame_pointer_rtx);
879
880   /* Mark the static chain as clobbered here so life information
881      doesn't get messed up for it.  */
882   chain = targetm.calls.static_chain (current_function_decl, true);
883   if (chain && REG_P (chain))
884     emit_clobber (chain);
885
886   /* Now put in the code to restore the frame pointer, and argument
887      pointer, if needed.  */
888 #ifdef HAVE_nonlocal_goto
889   if (! HAVE_nonlocal_goto)
890 #endif
891     {
892       emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
893       /* This might change the hard frame pointer in ways that aren't
894          apparent to early optimization passes, so force a clobber.  */
895       emit_clobber (hard_frame_pointer_rtx);
896     }
897
898 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
899   if (fixed_regs[ARG_POINTER_REGNUM])
900     {
901 #ifdef ELIMINABLE_REGS
902       size_t i;
903       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
904
905       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
906         if (elim_regs[i].from == ARG_POINTER_REGNUM
907             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
908           break;
909
910       if (i == ARRAY_SIZE (elim_regs))
911 #endif
912         {
913           /* Now restore our arg pointer from the address at which it
914              was saved in our stack frame.  */
915           emit_move_insn (crtl->args.internal_arg_pointer,
916                           copy_to_reg (get_arg_pointer_save_area ()));
917         }
918     }
919 #endif
920
921 #ifdef HAVE_builtin_setjmp_receiver
922   if (HAVE_builtin_setjmp_receiver)
923     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
924   else
925 #endif
926 #ifdef HAVE_nonlocal_goto_receiver
927     if (HAVE_nonlocal_goto_receiver)
928       emit_insn (gen_nonlocal_goto_receiver ());
929     else
930 #endif
931       { /* Nothing */ }
932
933   /* We must not allow the code we just generated to be reordered by
934      scheduling.  Specifically, the update of the frame pointer must
935      happen immediately, not later.  */
936   emit_insn (gen_blockage ());
937 }
938
939 /* __builtin_longjmp is passed a pointer to an array of five words (not
940    all will be used on all machines).  It operates similarly to the C
941    library function of the same name, but is more efficient.  Much of
942    the code below is copied from the handling of non-local gotos.  */
943
944 static void
945 expand_builtin_longjmp (rtx buf_addr, rtx value)
946 {
947   rtx fp, lab, stack, insn, last;
948   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
949
950   /* DRAP is needed for stack realign if longjmp is expanded to current
951      function  */
952   if (SUPPORTS_STACK_ALIGNMENT)
953     crtl->need_drap = true;
954
955   if (setjmp_alias_set == -1)
956     setjmp_alias_set = new_alias_set ();
957
958   buf_addr = convert_memory_address (Pmode, buf_addr);
959
960   buf_addr = force_reg (Pmode, buf_addr);
961
962   /* We require that the user must pass a second argument of 1, because
963      that is what builtin_setjmp will return.  */
964   gcc_assert (value == const1_rtx);
965
966   last = get_last_insn ();
967 #ifdef HAVE_builtin_longjmp
968   if (HAVE_builtin_longjmp)
969     emit_insn (gen_builtin_longjmp (buf_addr));
970   else
971 #endif
972     {
973       fp = gen_rtx_MEM (Pmode, buf_addr);
974       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
975                                                GET_MODE_SIZE (Pmode)));
976
977       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
978                                                    2 * GET_MODE_SIZE (Pmode)));
979       set_mem_alias_set (fp, setjmp_alias_set);
980       set_mem_alias_set (lab, setjmp_alias_set);
981       set_mem_alias_set (stack, setjmp_alias_set);
982
983       /* Pick up FP, label, and SP from the block and jump.  This code is
984          from expand_goto in stmt.c; see there for detailed comments.  */
985 #ifdef HAVE_nonlocal_goto
986       if (HAVE_nonlocal_goto)
987         /* We have to pass a value to the nonlocal_goto pattern that will
988            get copied into the static_chain pointer, but it does not matter
989            what that value is, because builtin_setjmp does not use it.  */
990         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
991       else
992 #endif
993         {
994           lab = copy_to_reg (lab);
995
996           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
997           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
998
999           emit_move_insn (hard_frame_pointer_rtx, fp);
1000           emit_stack_restore (SAVE_NONLOCAL, stack);
1001
1002           emit_use (hard_frame_pointer_rtx);
1003           emit_use (stack_pointer_rtx);
1004           emit_indirect_jump (lab);
1005         }
1006     }
1007
1008   /* Search backwards and mark the jump insn as a non-local goto.
1009      Note that this precludes the use of __builtin_longjmp to a
1010      __builtin_setjmp target in the same function.  However, we've
1011      already cautioned the user that these functions are for
1012      internal exception handling use only.  */
1013   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1014     {
1015       gcc_assert (insn != last);
1016
1017       if (JUMP_P (insn))
1018         {
1019           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1020           break;
1021         }
1022       else if (CALL_P (insn))
1023         break;
1024     }
1025 }
1026
1027 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
1028    and the address of the save area.  */
1029
1030 static rtx
1031 expand_builtin_nonlocal_goto (tree exp)
1032 {
1033   tree t_label, t_save_area;
1034   rtx r_label, r_save_area, r_fp, r_sp, insn;
1035
1036   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1037     return NULL_RTX;
1038
1039   t_label = CALL_EXPR_ARG (exp, 0);
1040   t_save_area = CALL_EXPR_ARG (exp, 1);
1041
1042   r_label = expand_normal (t_label);
1043   r_label = convert_memory_address (Pmode, r_label);
1044   r_save_area = expand_normal (t_save_area);
1045   r_save_area = convert_memory_address (Pmode, r_save_area);
1046   /* Copy the address of the save location to a register just in case it was
1047      based on the frame pointer.   */
1048   r_save_area = copy_to_reg (r_save_area);
1049   r_fp = gen_rtx_MEM (Pmode, r_save_area);
1050   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
1051                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
1052
1053   crtl->has_nonlocal_goto = 1;
1054
1055 #ifdef HAVE_nonlocal_goto
1056   /* ??? We no longer need to pass the static chain value, afaik.  */
1057   if (HAVE_nonlocal_goto)
1058     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
1059   else
1060 #endif
1061     {
1062       r_label = copy_to_reg (r_label);
1063
1064       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1065       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1066
1067       /* Restore frame pointer for containing function.  */
1068       emit_move_insn (hard_frame_pointer_rtx, r_fp);
1069       emit_stack_restore (SAVE_NONLOCAL, r_sp);
1070
1071       /* USE of hard_frame_pointer_rtx added for consistency;
1072          not clear if really needed.  */
1073       emit_use (hard_frame_pointer_rtx);
1074       emit_use (stack_pointer_rtx);
1075
1076       /* If the architecture is using a GP register, we must
1077          conservatively assume that the target function makes use of it.
1078          The prologue of functions with nonlocal gotos must therefore
1079          initialize the GP register to the appropriate value, and we
1080          must then make sure that this value is live at the point
1081          of the jump.  (Note that this doesn't necessarily apply
1082          to targets with a nonlocal_goto pattern; they are free
1083          to implement it in their own way.  Note also that this is
1084          a no-op if the GP register is a global invariant.)  */
1085       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
1086           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
1087         emit_use (pic_offset_table_rtx);
1088
1089       emit_indirect_jump (r_label);
1090     }
1091
1092   /* Search backwards to the jump insn and mark it as a
1093      non-local goto.  */
1094   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1095     {
1096       if (JUMP_P (insn))
1097         {
1098           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1099           break;
1100         }
1101       else if (CALL_P (insn))
1102         break;
1103     }
1104
1105   return const0_rtx;
1106 }
1107
1108 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
1109    (not all will be used on all machines) that was passed to __builtin_setjmp.
1110    It updates the stack pointer in that block to correspond to the current
1111    stack pointer.  */
1112
1113 static void
1114 expand_builtin_update_setjmp_buf (rtx buf_addr)
1115 {
1116   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1117   rtx stack_save
1118     = gen_rtx_MEM (sa_mode,
1119                    memory_address
1120                    (sa_mode,
1121                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1122
1123   emit_stack_save (SAVE_NONLOCAL, &stack_save);
1124 }
1125
1126 /* Expand a call to __builtin_prefetch.  For a target that does not support
1127    data prefetch, evaluate the memory address argument in case it has side
1128    effects.  */
1129
1130 static void
1131 expand_builtin_prefetch (tree exp)
1132 {
1133   tree arg0, arg1, arg2;
1134   int nargs;
1135   rtx op0, op1, op2;
1136
1137   if (!validate_arglist (exp, POINTER_TYPE, 0))
1138     return;
1139
1140   arg0 = CALL_EXPR_ARG (exp, 0);
1141
1142   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1143      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1144      locality).  */
1145   nargs = call_expr_nargs (exp);
1146   if (nargs > 1)
1147     arg1 = CALL_EXPR_ARG (exp, 1);
1148   else
1149     arg1 = integer_zero_node;
1150   if (nargs > 2)
1151     arg2 = CALL_EXPR_ARG (exp, 2);
1152   else
1153     arg2 = integer_three_node;
1154
1155   /* Argument 0 is an address.  */
1156   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1157
1158   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1159   if (TREE_CODE (arg1) != INTEGER_CST)
1160     {
1161       error ("second argument to %<__builtin_prefetch%> must be a constant");
1162       arg1 = integer_zero_node;
1163     }
1164   op1 = expand_normal (arg1);
1165   /* Argument 1 must be either zero or one.  */
1166   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1167     {
1168       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1169                " using zero");
1170       op1 = const0_rtx;
1171     }
1172
1173   /* Argument 2 (locality) must be a compile-time constant int.  */
1174   if (TREE_CODE (arg2) != INTEGER_CST)
1175     {
1176       error ("third argument to %<__builtin_prefetch%> must be a constant");
1177       arg2 = integer_zero_node;
1178     }
1179   op2 = expand_normal (arg2);
1180   /* Argument 2 must be 0, 1, 2, or 3.  */
1181   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1182     {
1183       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1184       op2 = const0_rtx;
1185     }
1186
1187 #ifdef HAVE_prefetch
1188   if (HAVE_prefetch)
1189     {
1190       struct expand_operand ops[3];
1191
1192       create_address_operand (&ops[0], op0);
1193       create_integer_operand (&ops[1], INTVAL (op1));
1194       create_integer_operand (&ops[2], INTVAL (op2));
1195       if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops))
1196         return;
1197     }
1198 #endif
1199
1200   /* Don't do anything with direct references to volatile memory, but
1201      generate code to handle other side effects.  */
1202   if (!MEM_P (op0) && side_effects_p (op0))
1203     emit_insn (op0);
1204 }
1205
1206 /* Get a MEM rtx for expression EXP which is the address of an operand
1207    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1208    the maximum length of the block of memory that might be accessed or
1209    NULL if unknown.  */
1210
1211 static rtx
1212 get_memory_rtx (tree exp, tree len)
1213 {
1214   tree orig_exp = exp;
1215   rtx addr, mem;
1216   HOST_WIDE_INT off;
1217
1218   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1219      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1220   if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1221     exp = TREE_OPERAND (exp, 0);
1222
1223   addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1224   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1225
1226   /* Get an expression we can use to find the attributes to assign to MEM.
1227      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1228      we can.  First remove any nops.  */
1229   while (CONVERT_EXPR_P (exp)
1230          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1231     exp = TREE_OPERAND (exp, 0);
1232
1233   off = 0;
1234   if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1235       && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1236       && host_integerp (TREE_OPERAND (exp, 1), 0)
1237       && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1238     exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1239   else if (TREE_CODE (exp) == ADDR_EXPR)
1240     exp = TREE_OPERAND (exp, 0);
1241   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1242     exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1243   else
1244     exp = NULL;
1245
1246   /* Honor attributes derived from exp, except for the alias set
1247      (as builtin stringops may alias with anything) and the size
1248      (as stringops may access multiple array elements).  */
1249   if (exp)
1250     {
1251       set_mem_attributes (mem, exp, 0);
1252
1253       if (off)
1254         mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1255
1256       /* Allow the string and memory builtins to overflow from one
1257          field into another, see http://gcc.gnu.org/PR23561.
1258          Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1259          memory accessed by the string or memory builtin will fit
1260          within the field.  */
1261       if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1262         {
1263           tree mem_expr = MEM_EXPR (mem);
1264           HOST_WIDE_INT offset = -1, length = -1;
1265           tree inner = exp;
1266
1267           while (TREE_CODE (inner) == ARRAY_REF
1268                  || CONVERT_EXPR_P (inner)
1269                  || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1270                  || TREE_CODE (inner) == SAVE_EXPR)
1271             inner = TREE_OPERAND (inner, 0);
1272
1273           gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1274
1275           if (MEM_OFFSET_KNOWN_P (mem))
1276             offset = MEM_OFFSET (mem);
1277
1278           if (offset >= 0 && len && host_integerp (len, 0))
1279             length = tree_low_cst (len, 0);
1280
1281           while (TREE_CODE (inner) == COMPONENT_REF)
1282             {
1283               tree field = TREE_OPERAND (inner, 1);
1284               gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1285               gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1286
1287               /* Bitfields are generally not byte-addressable.  */
1288               gcc_assert (!DECL_BIT_FIELD (field)
1289                           || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1290                                % BITS_PER_UNIT) == 0
1291                               && host_integerp (DECL_SIZE (field), 0)
1292                               && (TREE_INT_CST_LOW (DECL_SIZE (field))
1293                                   % BITS_PER_UNIT) == 0));
1294
1295               /* If we can prove that the memory starting at XEXP (mem, 0) and
1296                  ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1297                  can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
1298                  fields without DECL_SIZE_UNIT like flexible array members.  */
1299               if (length >= 0
1300                   && DECL_SIZE_UNIT (field)
1301                   && host_integerp (DECL_SIZE_UNIT (field), 0))
1302                 {
1303                   HOST_WIDE_INT size
1304                     = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
1305                   if (offset <= size
1306                       && length <= size
1307                       && offset + length <= size)
1308                     break;
1309                 }
1310
1311               if (offset >= 0
1312                   && host_integerp (DECL_FIELD_OFFSET (field), 0))
1313                 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
1314                           + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1315                             / BITS_PER_UNIT;
1316               else
1317                 {
1318                   offset = -1;
1319                   length = -1;
1320                 }
1321
1322               mem_expr = TREE_OPERAND (mem_expr, 0);
1323               inner = TREE_OPERAND (inner, 0);
1324             }
1325
1326           if (mem_expr == NULL)
1327             offset = -1;
1328           if (mem_expr != MEM_EXPR (mem))
1329             {
1330               set_mem_expr (mem, mem_expr);
1331               if (offset >= 0)
1332                 set_mem_offset (mem, offset);
1333               else
1334                 clear_mem_offset (mem);
1335             }
1336         }
1337       set_mem_alias_set (mem, 0);
1338       clear_mem_size (mem);
1339     }
1340
1341   return mem;
1342 }
1343 \f
1344 /* Built-in functions to perform an untyped call and return.  */
1345
1346 #define apply_args_mode \
1347   (this_target_builtins->x_apply_args_mode)
1348 #define apply_result_mode \
1349   (this_target_builtins->x_apply_result_mode)
1350
1351 /* Return the size required for the block returned by __builtin_apply_args,
1352    and initialize apply_args_mode.  */
1353
1354 static int
1355 apply_args_size (void)
1356 {
1357   static int size = -1;
1358   int align;
1359   unsigned int regno;
1360   enum machine_mode mode;
1361
1362   /* The values computed by this function never change.  */
1363   if (size < 0)
1364     {
1365       /* The first value is the incoming arg-pointer.  */
1366       size = GET_MODE_SIZE (Pmode);
1367
1368       /* The second value is the structure value address unless this is
1369          passed as an "invisible" first argument.  */
1370       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1371         size += GET_MODE_SIZE (Pmode);
1372
1373       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1374         if (FUNCTION_ARG_REGNO_P (regno))
1375           {
1376             mode = targetm.calls.get_raw_arg_mode (regno);
1377
1378             gcc_assert (mode != VOIDmode);
1379
1380             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1381             if (size % align != 0)
1382               size = CEIL (size, align) * align;
1383             size += GET_MODE_SIZE (mode);
1384             apply_args_mode[regno] = mode;
1385           }
1386         else
1387           {
1388             apply_args_mode[regno] = VOIDmode;
1389           }
1390     }
1391   return size;
1392 }
1393
1394 /* Return the size required for the block returned by __builtin_apply,
1395    and initialize apply_result_mode.  */
1396
1397 static int
1398 apply_result_size (void)
1399 {
1400   static int size = -1;
1401   int align, regno;
1402   enum machine_mode mode;
1403
1404   /* The values computed by this function never change.  */
1405   if (size < 0)
1406     {
1407       size = 0;
1408
1409       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1410         if (targetm.calls.function_value_regno_p (regno))
1411           {
1412             mode = targetm.calls.get_raw_result_mode (regno);
1413
1414             gcc_assert (mode != VOIDmode);
1415
1416             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1417             if (size % align != 0)
1418               size = CEIL (size, align) * align;
1419             size += GET_MODE_SIZE (mode);
1420             apply_result_mode[regno] = mode;
1421           }
1422         else
1423           apply_result_mode[regno] = VOIDmode;
1424
1425       /* Allow targets that use untyped_call and untyped_return to override
1426          the size so that machine-specific information can be stored here.  */
1427 #ifdef APPLY_RESULT_SIZE
1428       size = APPLY_RESULT_SIZE;
1429 #endif
1430     }
1431   return size;
1432 }
1433
1434 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1435 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1436    the result block is used to save the values; otherwise it is used to
1437    restore the values.  */
1438
1439 static rtx
1440 result_vector (int savep, rtx result)
1441 {
1442   int regno, size, align, nelts;
1443   enum machine_mode mode;
1444   rtx reg, mem;
1445   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1446
1447   size = nelts = 0;
1448   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1449     if ((mode = apply_result_mode[regno]) != VOIDmode)
1450       {
1451         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1452         if (size % align != 0)
1453           size = CEIL (size, align) * align;
1454         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1455         mem = adjust_address (result, mode, size);
1456         savevec[nelts++] = (savep
1457                             ? gen_rtx_SET (VOIDmode, mem, reg)
1458                             : gen_rtx_SET (VOIDmode, reg, mem));
1459         size += GET_MODE_SIZE (mode);
1460       }
1461   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1462 }
1463 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1464
1465 /* Save the state required to perform an untyped call with the same
1466    arguments as were passed to the current function.  */
1467
1468 static rtx
1469 expand_builtin_apply_args_1 (void)
1470 {
1471   rtx registers, tem;
1472   int size, align, regno;
1473   enum machine_mode mode;
1474   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1475
1476   /* Create a block where the arg-pointer, structure value address,
1477      and argument registers can be saved.  */
1478   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1479
1480   /* Walk past the arg-pointer and structure value address.  */
1481   size = GET_MODE_SIZE (Pmode);
1482   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1483     size += GET_MODE_SIZE (Pmode);
1484
1485   /* Save each register used in calling a function to the block.  */
1486   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1487     if ((mode = apply_args_mode[regno]) != VOIDmode)
1488       {
1489         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1490         if (size % align != 0)
1491           size = CEIL (size, align) * align;
1492
1493         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1494
1495         emit_move_insn (adjust_address (registers, mode, size), tem);
1496         size += GET_MODE_SIZE (mode);
1497       }
1498
1499   /* Save the arg pointer to the block.  */
1500   tem = copy_to_reg (crtl->args.internal_arg_pointer);
1501 #ifdef STACK_GROWS_DOWNWARD
1502   /* We need the pointer as the caller actually passed them to us, not
1503      as we might have pretended they were passed.  Make sure it's a valid
1504      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1505   tem
1506     = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
1507                      NULL_RTX);
1508 #endif
1509   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1510
1511   size = GET_MODE_SIZE (Pmode);
1512
1513   /* Save the structure value address unless this is passed as an
1514      "invisible" first argument.  */
1515   if (struct_incoming_value)
1516     {
1517       emit_move_insn (adjust_address (registers, Pmode, size),
1518                       copy_to_reg (struct_incoming_value));
1519       size += GET_MODE_SIZE (Pmode);
1520     }
1521
1522   /* Return the address of the block.  */
1523   return copy_addr_to_reg (XEXP (registers, 0));
1524 }
1525
1526 /* __builtin_apply_args returns block of memory allocated on
1527    the stack into which is stored the arg pointer, structure
1528    value address, static chain, and all the registers that might
1529    possibly be used in performing a function call.  The code is
1530    moved to the start of the function so the incoming values are
1531    saved.  */
1532
1533 static rtx
1534 expand_builtin_apply_args (void)
1535 {
1536   /* Don't do __builtin_apply_args more than once in a function.
1537      Save the result of the first call and reuse it.  */
1538   if (apply_args_value != 0)
1539     return apply_args_value;
1540   {
1541     /* When this function is called, it means that registers must be
1542        saved on entry to this function.  So we migrate the
1543        call to the first insn of this function.  */
1544     rtx temp;
1545     rtx seq;
1546
1547     start_sequence ();
1548     temp = expand_builtin_apply_args_1 ();
1549     seq = get_insns ();
1550     end_sequence ();
1551
1552     apply_args_value = temp;
1553
1554     /* Put the insns after the NOTE that starts the function.
1555        If this is inside a start_sequence, make the outer-level insn
1556        chain current, so the code is placed at the start of the
1557        function.  If internal_arg_pointer is a non-virtual pseudo,
1558        it needs to be placed after the function that initializes
1559        that pseudo.  */
1560     push_topmost_sequence ();
1561     if (REG_P (crtl->args.internal_arg_pointer)
1562         && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1563       emit_insn_before (seq, parm_birth_insn);
1564     else
1565       emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1566     pop_topmost_sequence ();
1567     return temp;
1568   }
1569 }
1570
1571 /* Perform an untyped call and save the state required to perform an
1572    untyped return of whatever value was returned by the given function.  */
1573
1574 static rtx
1575 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1576 {
1577   int size, align, regno;
1578   enum machine_mode mode;
1579   rtx incoming_args, result, reg, dest, src, call_insn;
1580   rtx old_stack_level = 0;
1581   rtx call_fusage = 0;
1582   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1583
1584   arguments = convert_memory_address (Pmode, arguments);
1585
1586   /* Create a block where the return registers can be saved.  */
1587   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1588
1589   /* Fetch the arg pointer from the ARGUMENTS block.  */
1590   incoming_args = gen_reg_rtx (Pmode);
1591   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1592 #ifndef STACK_GROWS_DOWNWARD
1593   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1594                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1595 #endif
1596
1597   /* Push a new argument block and copy the arguments.  Do not allow
1598      the (potential) memcpy call below to interfere with our stack
1599      manipulations.  */
1600   do_pending_stack_adjust ();
1601   NO_DEFER_POP;
1602
1603   /* Save the stack with nonlocal if available.  */
1604 #ifdef HAVE_save_stack_nonlocal
1605   if (HAVE_save_stack_nonlocal)
1606     emit_stack_save (SAVE_NONLOCAL, &old_stack_level);
1607   else
1608 #endif
1609     emit_stack_save (SAVE_BLOCK, &old_stack_level);
1610
1611   /* Allocate a block of memory onto the stack and copy the memory
1612      arguments to the outgoing arguments address.  We can pass TRUE
1613      as the 4th argument because we just saved the stack pointer
1614      and will restore it right after the call.  */
1615   allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true);
1616
1617   /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1618      may have already set current_function_calls_alloca to true.
1619      current_function_calls_alloca won't be set if argsize is zero,
1620      so we have to guarantee need_drap is true here.  */
1621   if (SUPPORTS_STACK_ALIGNMENT)
1622     crtl->need_drap = true;
1623
1624   dest = virtual_outgoing_args_rtx;
1625 #ifndef STACK_GROWS_DOWNWARD
1626   if (CONST_INT_P (argsize))
1627     dest = plus_constant (dest, -INTVAL (argsize));
1628   else
1629     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1630 #endif
1631   dest = gen_rtx_MEM (BLKmode, dest);
1632   set_mem_align (dest, PARM_BOUNDARY);
1633   src = gen_rtx_MEM (BLKmode, incoming_args);
1634   set_mem_align (src, PARM_BOUNDARY);
1635   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1636
1637   /* Refer to the argument block.  */
1638   apply_args_size ();
1639   arguments = gen_rtx_MEM (BLKmode, arguments);
1640   set_mem_align (arguments, PARM_BOUNDARY);
1641
1642   /* Walk past the arg-pointer and structure value address.  */
1643   size = GET_MODE_SIZE (Pmode);
1644   if (struct_value)
1645     size += GET_MODE_SIZE (Pmode);
1646
1647   /* Restore each of the registers previously saved.  Make USE insns
1648      for each of these registers for use in making the call.  */
1649   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1650     if ((mode = apply_args_mode[regno]) != VOIDmode)
1651       {
1652         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1653         if (size % align != 0)
1654           size = CEIL (size, align) * align;
1655         reg = gen_rtx_REG (mode, regno);
1656         emit_move_insn (reg, adjust_address (arguments, mode, size));
1657         use_reg (&call_fusage, reg);
1658         size += GET_MODE_SIZE (mode);
1659       }
1660
1661   /* Restore the structure value address unless this is passed as an
1662      "invisible" first argument.  */
1663   size = GET_MODE_SIZE (Pmode);
1664   if (struct_value)
1665     {
1666       rtx value = gen_reg_rtx (Pmode);
1667       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1668       emit_move_insn (struct_value, value);
1669       if (REG_P (struct_value))
1670         use_reg (&call_fusage, struct_value);
1671       size += GET_MODE_SIZE (Pmode);
1672     }
1673
1674   /* All arguments and registers used for the call are set up by now!  */
1675   function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1676
1677   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1678      and we don't want to load it into a register as an optimization,
1679      because prepare_call_address already did it if it should be done.  */
1680   if (GET_CODE (function) != SYMBOL_REF)
1681     function = memory_address (FUNCTION_MODE, function);
1682
1683   /* Generate the actual call instruction and save the return value.  */
1684 #ifdef HAVE_untyped_call
1685   if (HAVE_untyped_call)
1686     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1687                                       result, result_vector (1, result)));
1688   else
1689 #endif
1690 #ifdef HAVE_call_value
1691   if (HAVE_call_value)
1692     {
1693       rtx valreg = 0;
1694
1695       /* Locate the unique return register.  It is not possible to
1696          express a call that sets more than one return register using
1697          call_value; use untyped_call for that.  In fact, untyped_call
1698          only needs to save the return registers in the given block.  */
1699       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1700         if ((mode = apply_result_mode[regno]) != VOIDmode)
1701           {
1702             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1703
1704             valreg = gen_rtx_REG (mode, regno);
1705           }
1706
1707       emit_call_insn (GEN_CALL_VALUE (valreg,
1708                                       gen_rtx_MEM (FUNCTION_MODE, function),
1709                                       const0_rtx, NULL_RTX, const0_rtx));
1710
1711       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1712     }
1713   else
1714 #endif
1715     gcc_unreachable ();
1716
1717   /* Find the CALL insn we just emitted, and attach the register usage
1718      information.  */
1719   call_insn = last_call_insn ();
1720   add_function_usage_to (call_insn, call_fusage);
1721
1722   /* Restore the stack.  */
1723 #ifdef HAVE_save_stack_nonlocal
1724   if (HAVE_save_stack_nonlocal)
1725     emit_stack_restore (SAVE_NONLOCAL, old_stack_level);
1726   else
1727 #endif
1728     emit_stack_restore (SAVE_BLOCK, old_stack_level);
1729   fixup_args_size_notes (call_insn, get_last_insn(), 0);
1730
1731   OK_DEFER_POP;
1732
1733   /* Return the address of the result block.  */
1734   result = copy_addr_to_reg (XEXP (result, 0));
1735   return convert_memory_address (ptr_mode, result);
1736 }
1737
1738 /* Perform an untyped return.  */
1739
1740 static void
1741 expand_builtin_return (rtx result)
1742 {
1743   int size, align, regno;
1744   enum machine_mode mode;
1745   rtx reg;
1746   rtx call_fusage = 0;
1747
1748   result = convert_memory_address (Pmode, result);
1749
1750   apply_result_size ();
1751   result = gen_rtx_MEM (BLKmode, result);
1752
1753 #ifdef HAVE_untyped_return
1754   if (HAVE_untyped_return)
1755     {
1756       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1757       emit_barrier ();
1758       return;
1759     }
1760 #endif
1761
1762   /* Restore the return value and note that each value is used.  */
1763   size = 0;
1764   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1765     if ((mode = apply_result_mode[regno]) != VOIDmode)
1766       {
1767         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1768         if (size % align != 0)
1769           size = CEIL (size, align) * align;
1770         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1771         emit_move_insn (reg, adjust_address (result, mode, size));
1772
1773         push_to_sequence (call_fusage);
1774         emit_use (reg);
1775         call_fusage = get_insns ();
1776         end_sequence ();
1777         size += GET_MODE_SIZE (mode);
1778       }
1779
1780   /* Put the USE insns before the return.  */
1781   emit_insn (call_fusage);
1782
1783   /* Return whatever values was restored by jumping directly to the end
1784      of the function.  */
1785   expand_naked_return ();
1786 }
1787
1788 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1789
1790 static enum type_class
1791 type_to_class (tree type)
1792 {
1793   switch (TREE_CODE (type))
1794     {
1795     case VOID_TYPE:        return void_type_class;
1796     case INTEGER_TYPE:     return integer_type_class;
1797     case ENUMERAL_TYPE:    return enumeral_type_class;
1798     case BOOLEAN_TYPE:     return boolean_type_class;
1799     case POINTER_TYPE:     return pointer_type_class;
1800     case REFERENCE_TYPE:   return reference_type_class;
1801     case OFFSET_TYPE:      return offset_type_class;
1802     case REAL_TYPE:        return real_type_class;
1803     case COMPLEX_TYPE:     return complex_type_class;
1804     case FUNCTION_TYPE:    return function_type_class;
1805     case METHOD_TYPE:      return method_type_class;
1806     case RECORD_TYPE:      return record_type_class;
1807     case UNION_TYPE:
1808     case QUAL_UNION_TYPE:  return union_type_class;
1809     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1810                                    ? string_type_class : array_type_class);
1811     case LANG_TYPE:        return lang_type_class;
1812     default:               return no_type_class;
1813     }
1814 }
1815
1816 /* Expand a call EXP to __builtin_classify_type.  */
1817
1818 static rtx
1819 expand_builtin_classify_type (tree exp)
1820 {
1821   if (call_expr_nargs (exp))
1822     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1823   return GEN_INT (no_type_class);
1824 }
1825
1826 /* This helper macro, meant to be used in mathfn_built_in below,
1827    determines which among a set of three builtin math functions is
1828    appropriate for a given type mode.  The `F' and `L' cases are
1829    automatically generated from the `double' case.  */
1830 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1831   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1832   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1833   fcodel = BUILT_IN_MATHFN##L ; break;
1834 /* Similar to above, but appends _R after any F/L suffix.  */
1835 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1836   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1837   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1838   fcodel = BUILT_IN_MATHFN##L_R ; break;
1839
1840 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1841    if available.  If IMPLICIT is true use the implicit builtin declaration,
1842    otherwise use the explicit declaration.  If we can't do the conversion,
1843    return zero.  */
1844
1845 static tree
1846 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p)
1847 {
1848   enum built_in_function fcode, fcodef, fcodel, fcode2;
1849
1850   switch (fn)
1851     {
1852       CASE_MATHFN (BUILT_IN_ACOS)
1853       CASE_MATHFN (BUILT_IN_ACOSH)
1854       CASE_MATHFN (BUILT_IN_ASIN)
1855       CASE_MATHFN (BUILT_IN_ASINH)
1856       CASE_MATHFN (BUILT_IN_ATAN)
1857       CASE_MATHFN (BUILT_IN_ATAN2)
1858       CASE_MATHFN (BUILT_IN_ATANH)
1859       CASE_MATHFN (BUILT_IN_CBRT)
1860       CASE_MATHFN (BUILT_IN_CEIL)
1861       CASE_MATHFN (BUILT_IN_CEXPI)
1862       CASE_MATHFN (BUILT_IN_COPYSIGN)
1863       CASE_MATHFN (BUILT_IN_COS)
1864       CASE_MATHFN (BUILT_IN_COSH)
1865       CASE_MATHFN (BUILT_IN_DREM)
1866       CASE_MATHFN (BUILT_IN_ERF)
1867       CASE_MATHFN (BUILT_IN_ERFC)
1868       CASE_MATHFN (BUILT_IN_EXP)
1869       CASE_MATHFN (BUILT_IN_EXP10)
1870       CASE_MATHFN (BUILT_IN_EXP2)
1871       CASE_MATHFN (BUILT_IN_EXPM1)
1872       CASE_MATHFN (BUILT_IN_FABS)
1873       CASE_MATHFN (BUILT_IN_FDIM)
1874       CASE_MATHFN (BUILT_IN_FLOOR)
1875       CASE_MATHFN (BUILT_IN_FMA)
1876       CASE_MATHFN (BUILT_IN_FMAX)
1877       CASE_MATHFN (BUILT_IN_FMIN)
1878       CASE_MATHFN (BUILT_IN_FMOD)
1879       CASE_MATHFN (BUILT_IN_FREXP)
1880       CASE_MATHFN (BUILT_IN_GAMMA)
1881       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1882       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1883       CASE_MATHFN (BUILT_IN_HYPOT)
1884       CASE_MATHFN (BUILT_IN_ILOGB)
1885       CASE_MATHFN (BUILT_IN_ICEIL)
1886       CASE_MATHFN (BUILT_IN_IFLOOR)
1887       CASE_MATHFN (BUILT_IN_INF)
1888       CASE_MATHFN (BUILT_IN_IRINT)
1889       CASE_MATHFN (BUILT_IN_IROUND)
1890       CASE_MATHFN (BUILT_IN_ISINF)
1891       CASE_MATHFN (BUILT_IN_J0)
1892       CASE_MATHFN (BUILT_IN_J1)
1893       CASE_MATHFN (BUILT_IN_JN)
1894       CASE_MATHFN (BUILT_IN_LCEIL)
1895       CASE_MATHFN (BUILT_IN_LDEXP)
1896       CASE_MATHFN (BUILT_IN_LFLOOR)
1897       CASE_MATHFN (BUILT_IN_LGAMMA)
1898       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1899       CASE_MATHFN (BUILT_IN_LLCEIL)
1900       CASE_MATHFN (BUILT_IN_LLFLOOR)
1901       CASE_MATHFN (BUILT_IN_LLRINT)
1902       CASE_MATHFN (BUILT_IN_LLROUND)
1903       CASE_MATHFN (BUILT_IN_LOG)
1904       CASE_MATHFN (BUILT_IN_LOG10)
1905       CASE_MATHFN (BUILT_IN_LOG1P)
1906       CASE_MATHFN (BUILT_IN_LOG2)
1907       CASE_MATHFN (BUILT_IN_LOGB)
1908       CASE_MATHFN (BUILT_IN_LRINT)
1909       CASE_MATHFN (BUILT_IN_LROUND)
1910       CASE_MATHFN (BUILT_IN_MODF)
1911       CASE_MATHFN (BUILT_IN_NAN)
1912       CASE_MATHFN (BUILT_IN_NANS)
1913       CASE_MATHFN (BUILT_IN_NEARBYINT)
1914       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1915       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1916       CASE_MATHFN (BUILT_IN_POW)
1917       CASE_MATHFN (BUILT_IN_POWI)
1918       CASE_MATHFN (BUILT_IN_POW10)
1919       CASE_MATHFN (BUILT_IN_REMAINDER)
1920       CASE_MATHFN (BUILT_IN_REMQUO)
1921       CASE_MATHFN (BUILT_IN_RINT)
1922       CASE_MATHFN (BUILT_IN_ROUND)
1923       CASE_MATHFN (BUILT_IN_SCALB)
1924       CASE_MATHFN (BUILT_IN_SCALBLN)
1925       CASE_MATHFN (BUILT_IN_SCALBN)
1926       CASE_MATHFN (BUILT_IN_SIGNBIT)
1927       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1928       CASE_MATHFN (BUILT_IN_SIN)
1929       CASE_MATHFN (BUILT_IN_SINCOS)
1930       CASE_MATHFN (BUILT_IN_SINH)
1931       CASE_MATHFN (BUILT_IN_SQRT)
1932       CASE_MATHFN (BUILT_IN_TAN)
1933       CASE_MATHFN (BUILT_IN_TANH)
1934       CASE_MATHFN (BUILT_IN_TGAMMA)
1935       CASE_MATHFN (BUILT_IN_TRUNC)
1936       CASE_MATHFN (BUILT_IN_Y0)
1937       CASE_MATHFN (BUILT_IN_Y1)
1938       CASE_MATHFN (BUILT_IN_YN)
1939
1940       default:
1941         return NULL_TREE;
1942       }
1943
1944   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1945     fcode2 = fcode;
1946   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1947     fcode2 = fcodef;
1948   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1949     fcode2 = fcodel;
1950   else
1951     return NULL_TREE;
1952
1953   if (implicit_p && !builtin_decl_implicit_p (fcode2))
1954     return NULL_TREE;
1955
1956   return builtin_decl_explicit (fcode2);
1957 }
1958
1959 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1960
1961 tree
1962 mathfn_built_in (tree type, enum built_in_function fn)
1963 {
1964   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1965 }
1966
1967 /* If errno must be maintained, expand the RTL to check if the result,
1968    TARGET, of a built-in function call, EXP, is NaN, and if so set
1969    errno to EDOM.  */
1970
1971 static void
1972 expand_errno_check (tree exp, rtx target)
1973 {
1974   rtx lab = gen_label_rtx ();
1975
1976   /* Test the result; if it is NaN, set errno=EDOM because
1977      the argument was not in the domain.  */
1978   do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1979                            NULL_RTX, NULL_RTX, lab,
1980                            /* The jump is very likely.  */
1981                            REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1));
1982
1983 #ifdef TARGET_EDOM
1984   /* If this built-in doesn't throw an exception, set errno directly.  */
1985   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1986     {
1987 #ifdef GEN_ERRNO_RTX
1988       rtx errno_rtx = GEN_ERRNO_RTX;
1989 #else
1990       rtx errno_rtx
1991           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1992 #endif
1993       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1994       emit_label (lab);
1995       return;
1996     }
1997 #endif
1998
1999   /* Make sure the library call isn't expanded as a tail call.  */
2000   CALL_EXPR_TAILCALL (exp) = 0;
2001
2002   /* We can't set errno=EDOM directly; let the library call do it.
2003      Pop the arguments right away in case the call gets deleted.  */
2004   NO_DEFER_POP;
2005   expand_call (exp, target, 0);
2006   OK_DEFER_POP;
2007   emit_label (lab);
2008 }
2009
2010 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
2011    Return NULL_RTX if a normal call should be emitted rather than expanding
2012    the function in-line.  EXP is the expression that is a call to the builtin
2013    function; if convenient, the result should be placed in TARGET.
2014    SUBTARGET may be used as the target for computing one of EXP's operands.  */
2015
2016 static rtx
2017 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
2018 {
2019   optab builtin_optab;
2020   rtx op0, insns;
2021   tree fndecl = get_callee_fndecl (exp);
2022   enum machine_mode mode;
2023   bool errno_set = false;
2024   tree arg;
2025
2026   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2027     return NULL_RTX;
2028
2029   arg = CALL_EXPR_ARG (exp, 0);
2030
2031   switch (DECL_FUNCTION_CODE (fndecl))
2032     {
2033     CASE_FLT_FN (BUILT_IN_SQRT):
2034       errno_set = ! tree_expr_nonnegative_p (arg);
2035       builtin_optab = sqrt_optab;
2036       break;
2037     CASE_FLT_FN (BUILT_IN_EXP):
2038       errno_set = true; builtin_optab = exp_optab; break;
2039     CASE_FLT_FN (BUILT_IN_EXP10):
2040     CASE_FLT_FN (BUILT_IN_POW10):
2041       errno_set = true; builtin_optab = exp10_optab; break;
2042     CASE_FLT_FN (BUILT_IN_EXP2):
2043       errno_set = true; builtin_optab = exp2_optab; break;
2044     CASE_FLT_FN (BUILT_IN_EXPM1):
2045       errno_set = true; builtin_optab = expm1_optab; break;
2046     CASE_FLT_FN (BUILT_IN_LOGB):
2047       errno_set = true; builtin_optab = logb_optab; break;
2048     CASE_FLT_FN (BUILT_IN_LOG):
2049       errno_set = true; builtin_optab = log_optab; break;
2050     CASE_FLT_FN (BUILT_IN_LOG10):
2051       errno_set = true; builtin_optab = log10_optab; break;
2052     CASE_FLT_FN (BUILT_IN_LOG2):
2053       errno_set = true; builtin_optab = log2_optab; break;
2054     CASE_FLT_FN (BUILT_IN_LOG1P):
2055       errno_set = true; builtin_optab = log1p_optab; break;
2056     CASE_FLT_FN (BUILT_IN_ASIN):
2057       builtin_optab = asin_optab; break;
2058     CASE_FLT_FN (BUILT_IN_ACOS):
2059       builtin_optab = acos_optab; break;
2060     CASE_FLT_FN (BUILT_IN_TAN):
2061       builtin_optab = tan_optab; break;
2062     CASE_FLT_FN (BUILT_IN_ATAN):
2063       builtin_optab = atan_optab; break;
2064     CASE_FLT_FN (BUILT_IN_FLOOR):
2065       builtin_optab = floor_optab; break;
2066     CASE_FLT_FN (BUILT_IN_CEIL):
2067       builtin_optab = ceil_optab; break;
2068     CASE_FLT_FN (BUILT_IN_TRUNC):
2069       builtin_optab = btrunc_optab; break;
2070     CASE_FLT_FN (BUILT_IN_ROUND):
2071       builtin_optab = round_optab; break;
2072     CASE_FLT_FN (BUILT_IN_NEARBYINT):
2073       builtin_optab = nearbyint_optab;
2074       if (flag_trapping_math)
2075         break;
2076       /* Else fallthrough and expand as rint.  */
2077     CASE_FLT_FN (BUILT_IN_RINT):
2078       builtin_optab = rint_optab; break;
2079     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
2080       builtin_optab = significand_optab; break;
2081     default:
2082       gcc_unreachable ();
2083     }
2084
2085   /* Make a suitable register to place result in.  */
2086   mode = TYPE_MODE (TREE_TYPE (exp));
2087
2088   if (! flag_errno_math || ! HONOR_NANS (mode))
2089     errno_set = false;
2090
2091   /* Before working hard, check whether the instruction is available.  */
2092   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
2093       && (!errno_set || !optimize_insn_for_size_p ()))
2094     {
2095       target = gen_reg_rtx (mode);
2096
2097       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2098          need to expand the argument again.  This way, we will not perform
2099          side-effects more the once.  */
2100       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2101
2102       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2103
2104       start_sequence ();
2105
2106       /* Compute into TARGET.
2107          Set TARGET to wherever the result comes back.  */
2108       target = expand_unop (mode, builtin_optab, op0, target, 0);
2109
2110       if (target != 0)
2111         {
2112           if (errno_set)
2113             expand_errno_check (exp, target);
2114
2115           /* Output the entire sequence.  */
2116           insns = get_insns ();
2117           end_sequence ();
2118           emit_insn (insns);
2119           return target;
2120         }
2121
2122       /* If we were unable to expand via the builtin, stop the sequence
2123          (without outputting the insns) and call to the library function
2124          with the stabilized argument list.  */
2125       end_sequence ();
2126     }
2127
2128   return expand_call (exp, target, target == const0_rtx);
2129 }
2130
2131 /* Expand a call to the builtin binary math functions (pow and atan2).
2132    Return NULL_RTX if a normal call should be emitted rather than expanding the
2133    function in-line.  EXP is the expression that is a call to the builtin
2134    function; if convenient, the result should be placed in TARGET.
2135    SUBTARGET may be used as the target for computing one of EXP's
2136    operands.  */
2137
2138 static rtx
2139 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2140 {
2141   optab builtin_optab;
2142   rtx op0, op1, insns;
2143   int op1_type = REAL_TYPE;
2144   tree fndecl = get_callee_fndecl (exp);
2145   tree arg0, arg1;
2146   enum machine_mode mode;
2147   bool errno_set = true;
2148
2149   switch (DECL_FUNCTION_CODE (fndecl))
2150     {
2151     CASE_FLT_FN (BUILT_IN_SCALBN):
2152     CASE_FLT_FN (BUILT_IN_SCALBLN):
2153     CASE_FLT_FN (BUILT_IN_LDEXP):
2154       op1_type = INTEGER_TYPE;
2155     default:
2156       break;
2157     }
2158
2159   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2160     return NULL_RTX;
2161
2162   arg0 = CALL_EXPR_ARG (exp, 0);
2163   arg1 = CALL_EXPR_ARG (exp, 1);
2164
2165   switch (DECL_FUNCTION_CODE (fndecl))
2166     {
2167     CASE_FLT_FN (BUILT_IN_POW):
2168       builtin_optab = pow_optab; break;
2169     CASE_FLT_FN (BUILT_IN_ATAN2):
2170       builtin_optab = atan2_optab; break;
2171     CASE_FLT_FN (BUILT_IN_SCALB):
2172       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2173         return 0;
2174       builtin_optab = scalb_optab; break;
2175     CASE_FLT_FN (BUILT_IN_SCALBN):
2176     CASE_FLT_FN (BUILT_IN_SCALBLN):
2177       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2178         return 0;
2179     /* Fall through... */
2180     CASE_FLT_FN (BUILT_IN_LDEXP):
2181       builtin_optab = ldexp_optab; break;
2182     CASE_FLT_FN (BUILT_IN_FMOD):
2183       builtin_optab = fmod_optab; break;
2184     CASE_FLT_FN (BUILT_IN_REMAINDER):
2185     CASE_FLT_FN (BUILT_IN_DREM):
2186       builtin_optab = remainder_optab; break;
2187     default:
2188       gcc_unreachable ();
2189     }
2190
2191   /* Make a suitable register to place result in.  */
2192   mode = TYPE_MODE (TREE_TYPE (exp));
2193
2194   /* Before working hard, check whether the instruction is available.  */
2195   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2196     return NULL_RTX;
2197
2198   target = gen_reg_rtx (mode);
2199
2200   if (! flag_errno_math || ! HONOR_NANS (mode))
2201     errno_set = false;
2202
2203   if (errno_set && optimize_insn_for_size_p ())
2204     return 0;
2205
2206   /* Always stabilize the argument list.  */
2207   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2208   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2209
2210   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2211   op1 = expand_normal (arg1);
2212
2213   start_sequence ();
2214
2215   /* Compute into TARGET.
2216      Set TARGET to wherever the result comes back.  */
2217   target = expand_binop (mode, builtin_optab, op0, op1,
2218                          target, 0, OPTAB_DIRECT);
2219
2220   /* If we were unable to expand via the builtin, stop the sequence
2221      (without outputting the insns) and call to the library function
2222      with the stabilized argument list.  */
2223   if (target == 0)
2224     {
2225       end_sequence ();
2226       return expand_call (exp, target, target == const0_rtx);
2227     }
2228
2229   if (errno_set)
2230     expand_errno_check (exp, target);
2231
2232   /* Output the entire sequence.  */
2233   insns = get_insns ();
2234   end_sequence ();
2235   emit_insn (insns);
2236
2237   return target;
2238 }
2239
2240 /* Expand a call to the builtin trinary math functions (fma).
2241    Return NULL_RTX if a normal call should be emitted rather than expanding the
2242    function in-line.  EXP is the expression that is a call to the builtin
2243    function; if convenient, the result should be placed in TARGET.
2244    SUBTARGET may be used as the target for computing one of EXP's
2245    operands.  */
2246
2247 static rtx
2248 expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
2249 {
2250   optab builtin_optab;
2251   rtx op0, op1, op2, insns;
2252   tree fndecl = get_callee_fndecl (exp);
2253   tree arg0, arg1, arg2;
2254   enum machine_mode mode;
2255
2256   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2257     return NULL_RTX;
2258
2259   arg0 = CALL_EXPR_ARG (exp, 0);
2260   arg1 = CALL_EXPR_ARG (exp, 1);
2261   arg2 = CALL_EXPR_ARG (exp, 2);
2262
2263   switch (DECL_FUNCTION_CODE (fndecl))
2264     {
2265     CASE_FLT_FN (BUILT_IN_FMA):
2266       builtin_optab = fma_optab; break;
2267     default:
2268       gcc_unreachable ();
2269     }
2270
2271   /* Make a suitable register to place result in.  */
2272   mode = TYPE_MODE (TREE_TYPE (exp));
2273
2274   /* Before working hard, check whether the instruction is available.  */
2275   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2276     return NULL_RTX;
2277
2278   target = gen_reg_rtx (mode);
2279
2280   /* Always stabilize the argument list.  */
2281   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2282   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2283   CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2);
2284
2285   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2286   op1 = expand_normal (arg1);
2287   op2 = expand_normal (arg2);
2288
2289   start_sequence ();
2290
2291   /* Compute into TARGET.
2292      Set TARGET to wherever the result comes back.  */
2293   target = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
2294                               target, 0);
2295
2296   /* If we were unable to expand via the builtin, stop the sequence
2297      (without outputting the insns) and call to the library function
2298      with the stabilized argument list.  */
2299   if (target == 0)
2300     {
2301       end_sequence ();
2302       return expand_call (exp, target, target == const0_rtx);
2303     }
2304
2305   /* Output the entire sequence.  */
2306   insns = get_insns ();
2307   end_sequence ();
2308   emit_insn (insns);
2309
2310   return target;
2311 }
2312
2313 /* Expand a call to the builtin sin and cos math functions.
2314    Return NULL_RTX if a normal call should be emitted rather than expanding the
2315    function in-line.  EXP is the expression that is a call to the builtin
2316    function; if convenient, the result should be placed in TARGET.
2317    SUBTARGET may be used as the target for computing one of EXP's
2318    operands.  */
2319
2320 static rtx
2321 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2322 {
2323   optab builtin_optab;
2324   rtx op0, insns;
2325   tree fndecl = get_callee_fndecl (exp);
2326   enum machine_mode mode;
2327   tree arg;
2328
2329   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2330     return NULL_RTX;
2331
2332   arg = CALL_EXPR_ARG (exp, 0);
2333
2334   switch (DECL_FUNCTION_CODE (fndecl))
2335     {
2336     CASE_FLT_FN (BUILT_IN_SIN):
2337     CASE_FLT_FN (BUILT_IN_COS):
2338       builtin_optab = sincos_optab; break;
2339     default:
2340       gcc_unreachable ();
2341     }
2342
2343   /* Make a suitable register to place result in.  */
2344   mode = TYPE_MODE (TREE_TYPE (exp));
2345
2346   /* Check if sincos insn is available, otherwise fallback
2347      to sin or cos insn.  */
2348   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2349     switch (DECL_FUNCTION_CODE (fndecl))
2350       {
2351       CASE_FLT_FN (BUILT_IN_SIN):
2352         builtin_optab = sin_optab; break;
2353       CASE_FLT_FN (BUILT_IN_COS):
2354         builtin_optab = cos_optab; break;
2355       default:
2356         gcc_unreachable ();
2357       }
2358
2359   /* Before working hard, check whether the instruction is available.  */
2360   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
2361     {
2362       target = gen_reg_rtx (mode);
2363
2364       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2365          need to expand the argument again.  This way, we will not perform
2366          side-effects more the once.  */
2367       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2368
2369       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2370
2371       start_sequence ();
2372
2373       /* Compute into TARGET.
2374          Set TARGET to wherever the result comes back.  */
2375       if (builtin_optab == sincos_optab)
2376         {
2377           int result;
2378
2379           switch (DECL_FUNCTION_CODE (fndecl))
2380             {
2381             CASE_FLT_FN (BUILT_IN_SIN):
2382               result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2383               break;
2384             CASE_FLT_FN (BUILT_IN_COS):
2385               result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2386               break;
2387             default:
2388               gcc_unreachable ();
2389             }
2390           gcc_assert (result);
2391         }
2392       else
2393         {
2394           target = expand_unop (mode, builtin_optab, op0, target, 0);
2395         }
2396
2397       if (target != 0)
2398         {
2399           /* Output the entire sequence.  */
2400           insns = get_insns ();
2401           end_sequence ();
2402           emit_insn (insns);
2403           return target;
2404         }
2405
2406       /* If we were unable to expand via the builtin, stop the sequence
2407          (without outputting the insns) and call to the library function
2408          with the stabilized argument list.  */
2409       end_sequence ();
2410     }
2411
2412   target = expand_call (exp, target, target == const0_rtx);
2413
2414   return target;
2415 }
2416
2417 /* Given an interclass math builtin decl FNDECL and it's argument ARG
2418    return an RTL instruction code that implements the functionality.
2419    If that isn't possible or available return CODE_FOR_nothing.  */
2420
2421 static enum insn_code
2422 interclass_mathfn_icode (tree arg, tree fndecl)
2423 {
2424   bool errno_set = false;
2425   optab builtin_optab = 0;
2426   enum machine_mode mode;
2427
2428   switch (DECL_FUNCTION_CODE (fndecl))
2429     {
2430     CASE_FLT_FN (BUILT_IN_ILOGB):
2431       errno_set = true; builtin_optab = ilogb_optab; break;
2432     CASE_FLT_FN (BUILT_IN_ISINF):
2433       builtin_optab = isinf_optab; break;
2434     case BUILT_IN_ISNORMAL:
2435     case BUILT_IN_ISFINITE:
2436     CASE_FLT_FN (BUILT_IN_FINITE):
2437     case BUILT_IN_FINITED32:
2438     case BUILT_IN_FINITED64:
2439     case BUILT_IN_FINITED128:
2440     case BUILT_IN_ISINFD32:
2441     case BUILT_IN_ISINFD64:
2442     case BUILT_IN_ISINFD128:
2443       /* These builtins have no optabs (yet).  */
2444       break;
2445     default:
2446       gcc_unreachable ();
2447     }
2448
2449   /* There's no easy way to detect the case we need to set EDOM.  */
2450   if (flag_errno_math && errno_set)
2451     return CODE_FOR_nothing;
2452
2453   /* Optab mode depends on the mode of the input argument.  */
2454   mode = TYPE_MODE (TREE_TYPE (arg));
2455
2456   if (builtin_optab)
2457     return optab_handler (builtin_optab, mode);
2458   return CODE_FOR_nothing;
2459 }
2460
2461 /* Expand a call to one of the builtin math functions that operate on
2462    floating point argument and output an integer result (ilogb, isinf,
2463    isnan, etc).
2464    Return 0 if a normal call should be emitted rather than expanding the
2465    function in-line.  EXP is the expression that is a call to the builtin
2466    function; if convenient, the result should be placed in TARGET.  */
2467
2468 static rtx
2469 expand_builtin_interclass_mathfn (tree exp, rtx target)
2470 {
2471   enum insn_code icode = CODE_FOR_nothing;
2472   rtx op0;
2473   tree fndecl = get_callee_fndecl (exp);
2474   enum machine_mode mode;
2475   tree arg;
2476
2477   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2478     return NULL_RTX;
2479
2480   arg = CALL_EXPR_ARG (exp, 0);
2481   icode = interclass_mathfn_icode (arg, fndecl);
2482   mode = TYPE_MODE (TREE_TYPE (arg));
2483
2484   if (icode != CODE_FOR_nothing)
2485     {
2486       struct expand_operand ops[1];
2487       rtx last = get_last_insn ();
2488       tree orig_arg = arg;
2489
2490       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2491          need to expand the argument again.  This way, we will not perform
2492          side-effects more the once.  */
2493       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2494
2495       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2496
2497       if (mode != GET_MODE (op0))
2498         op0 = convert_to_mode (mode, op0, 0);
2499
2500       create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
2501       if (maybe_legitimize_operands (icode, 0, 1, ops)
2502           && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN))
2503         return ops[0].value;
2504
2505       delete_insns_since (last);
2506       CALL_EXPR_ARG (exp, 0) = orig_arg;
2507     }
2508
2509   return NULL_RTX;
2510 }
2511
2512 /* Expand a call to the builtin sincos math function.
2513    Return NULL_RTX if a normal call should be emitted rather than expanding the
2514    function in-line.  EXP is the expression that is a call to the builtin
2515    function.  */
2516
2517 static rtx
2518 expand_builtin_sincos (tree exp)
2519 {
2520   rtx op0, op1, op2, target1, target2;
2521   enum machine_mode mode;
2522   tree arg, sinp, cosp;
2523   int result;
2524   location_t loc = EXPR_LOCATION (exp);
2525   tree alias_type, alias_off;
2526
2527   if (!validate_arglist (exp, REAL_TYPE,
2528                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2529     return NULL_RTX;
2530
2531   arg = CALL_EXPR_ARG (exp, 0);
2532   sinp = CALL_EXPR_ARG (exp, 1);
2533   cosp = CALL_EXPR_ARG (exp, 2);
2534
2535   /* Make a suitable register to place result in.  */
2536   mode = TYPE_MODE (TREE_TYPE (arg));
2537
2538   /* Check if sincos insn is available, otherwise emit the call.  */
2539   if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing)
2540     return NULL_RTX;
2541
2542   target1 = gen_reg_rtx (mode);
2543   target2 = gen_reg_rtx (mode);
2544
2545   op0 = expand_normal (arg);
2546   alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true);
2547   alias_off = build_int_cst (alias_type, 0);
2548   op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2549                                         sinp, alias_off));
2550   op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2551                                         cosp, alias_off));
2552
2553   /* Compute into target1 and target2.
2554      Set TARGET to wherever the result comes back.  */
2555   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2556   gcc_assert (result);
2557
2558   /* Move target1 and target2 to the memory locations indicated
2559      by op1 and op2.  */
2560   emit_move_insn (op1, target1);
2561   emit_move_insn (op2, target2);
2562
2563   return const0_rtx;
2564 }
2565
2566 /* Expand a call to the internal cexpi builtin to the sincos math function.
2567    EXP is the expression that is a call to the builtin function; if convenient,
2568    the result should be placed in TARGET.  */
2569
2570 static rtx
2571 expand_builtin_cexpi (tree exp, rtx target)
2572 {
2573   tree fndecl = get_callee_fndecl (exp);
2574   tree arg, type;
2575   enum machine_mode mode;
2576   rtx op0, op1, op2;
2577   location_t loc = EXPR_LOCATION (exp);
2578
2579   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2580     return NULL_RTX;
2581
2582   arg = CALL_EXPR_ARG (exp, 0);
2583   type = TREE_TYPE (arg);
2584   mode = TYPE_MODE (TREE_TYPE (arg));
2585
2586   /* Try expanding via a sincos optab, fall back to emitting a libcall
2587      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2588      is only generated from sincos, cexp or if we have either of them.  */
2589   if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing)
2590     {
2591       op1 = gen_reg_rtx (mode);
2592       op2 = gen_reg_rtx (mode);
2593
2594       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2595
2596       /* Compute into op1 and op2.  */
2597       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2598     }
2599   else if (TARGET_HAS_SINCOS)
2600     {
2601       tree call, fn = NULL_TREE;
2602       tree top1, top2;
2603       rtx op1a, op2a;
2604
2605       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2606         fn = builtin_decl_explicit (BUILT_IN_SINCOSF);
2607       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2608         fn = builtin_decl_explicit (BUILT_IN_SINCOS);
2609       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2610         fn = builtin_decl_explicit (BUILT_IN_SINCOSL);
2611       else
2612         gcc_unreachable ();
2613
2614       op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2615       op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2616       op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2617       op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2618       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2619       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2620
2621       /* Make sure not to fold the sincos call again.  */
2622       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2623       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2624                                       call, 3, arg, top1, top2));
2625     }
2626   else
2627     {
2628       tree call, fn = NULL_TREE, narg;
2629       tree ctype = build_complex_type (type);
2630
2631       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2632         fn = builtin_decl_explicit (BUILT_IN_CEXPF);
2633       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2634         fn = builtin_decl_explicit (BUILT_IN_CEXP);
2635       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2636         fn = builtin_decl_explicit (BUILT_IN_CEXPL);
2637       else
2638         gcc_unreachable ();
2639
2640       /* If we don't have a decl for cexp create one.  This is the
2641          friendliest fallback if the user calls __builtin_cexpi
2642          without full target C99 function support.  */
2643       if (fn == NULL_TREE)
2644         {
2645           tree fntype;
2646           const char *name = NULL;
2647
2648           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2649             name = "cexpf";
2650           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2651             name = "cexp";
2652           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2653             name = "cexpl";
2654
2655           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2656           fn = build_fn_decl (name, fntype);
2657         }
2658
2659       narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2660                           build_real (type, dconst0), arg);
2661
2662       /* Make sure not to fold the cexp call again.  */
2663       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2664       return expand_expr (build_call_nary (ctype, call, 1, narg),
2665                           target, VOIDmode, EXPAND_NORMAL);
2666     }
2667
2668   /* Now build the proper return type.  */
2669   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2670                               make_tree (TREE_TYPE (arg), op2),
2671                               make_tree (TREE_TYPE (arg), op1)),
2672                       target, VOIDmode, EXPAND_NORMAL);
2673 }
2674
2675 /* Conveniently construct a function call expression.  FNDECL names the
2676    function to be called, N is the number of arguments, and the "..."
2677    parameters are the argument expressions.  Unlike build_call_exr
2678    this doesn't fold the call, hence it will always return a CALL_EXPR.  */
2679
2680 static tree
2681 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2682 {
2683   va_list ap;
2684   tree fntype = TREE_TYPE (fndecl);
2685   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2686
2687   va_start (ap, n);
2688   fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2689   va_end (ap);
2690   SET_EXPR_LOCATION (fn, loc);
2691   return fn;
2692 }
2693
2694 /* Expand a call to one of the builtin rounding functions gcc defines
2695    as an extension (lfloor and lceil).  As these are gcc extensions we
2696    do not need to worry about setting errno to EDOM.
2697    If expanding via optab fails, lower expression to (int)(floor(x)).
2698    EXP is the expression that is a call to the builtin function;
2699    if convenient, the result should be placed in TARGET.  */
2700
2701 static rtx
2702 expand_builtin_int_roundingfn (tree exp, rtx target)
2703 {
2704   convert_optab builtin_optab;
2705   rtx op0, insns, tmp;
2706   tree fndecl = get_callee_fndecl (exp);
2707   enum built_in_function fallback_fn;
2708   tree fallback_fndecl;
2709   enum machine_mode mode;
2710   tree arg;
2711
2712   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2713     gcc_unreachable ();
2714
2715   arg = CALL_EXPR_ARG (exp, 0);
2716
2717   switch (DECL_FUNCTION_CODE (fndecl))
2718     {
2719     CASE_FLT_FN (BUILT_IN_ICEIL):
2720     CASE_FLT_FN (BUILT_IN_LCEIL):
2721     CASE_FLT_FN (BUILT_IN_LLCEIL):
2722       builtin_optab = lceil_optab;
2723       fallback_fn = BUILT_IN_CEIL;
2724       break;
2725
2726     CASE_FLT_FN (BUILT_IN_IFLOOR):
2727     CASE_FLT_FN (BUILT_IN_LFLOOR):
2728     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2729       builtin_optab = lfloor_optab;
2730       fallback_fn = BUILT_IN_FLOOR;
2731       break;
2732
2733     default:
2734       gcc_unreachable ();
2735     }
2736
2737   /* Make a suitable register to place result in.  */
2738   mode = TYPE_MODE (TREE_TYPE (exp));
2739
2740   target = gen_reg_rtx (mode);
2741
2742   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2743      need to expand the argument again.  This way, we will not perform
2744      side-effects more the once.  */
2745   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2746
2747   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2748
2749   start_sequence ();
2750
2751   /* Compute into TARGET.  */
2752   if (expand_sfix_optab (target, op0, builtin_optab))
2753     {
2754       /* Output the entire sequence.  */
2755       insns = get_insns ();
2756       end_sequence ();
2757       emit_insn (insns);
2758       return target;
2759     }
2760
2761   /* If we were unable to expand via the builtin, stop the sequence
2762      (without outputting the insns).  */
2763   end_sequence ();
2764
2765   /* Fall back to floating point rounding optab.  */
2766   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2767
2768   /* For non-C99 targets we may end up without a fallback fndecl here
2769      if the user called __builtin_lfloor directly.  In this case emit
2770      a call to the floor/ceil variants nevertheless.  This should result
2771      in the best user experience for not full C99 targets.  */
2772   if (fallback_fndecl == NULL_TREE)
2773     {
2774       tree fntype;
2775       const char *name = NULL;
2776
2777       switch (DECL_FUNCTION_CODE (fndecl))
2778         {
2779         case BUILT_IN_ICEIL:
2780         case BUILT_IN_LCEIL:
2781         case BUILT_IN_LLCEIL:
2782           name = "ceil";
2783           break;
2784         case BUILT_IN_ICEILF:
2785         case BUILT_IN_LCEILF:
2786         case BUILT_IN_LLCEILF:
2787           name = "ceilf";
2788           break;
2789         case BUILT_IN_ICEILL:
2790         case BUILT_IN_LCEILL:
2791         case BUILT_IN_LLCEILL:
2792           name = "ceill";
2793           break;
2794         case BUILT_IN_IFLOOR:
2795         case BUILT_IN_LFLOOR:
2796         case BUILT_IN_LLFLOOR:
2797           name = "floor";
2798           break;
2799         case BUILT_IN_IFLOORF:
2800         case BUILT_IN_LFLOORF:
2801         case BUILT_IN_LLFLOORF:
2802           name = "floorf";
2803           break;
2804         case BUILT_IN_IFLOORL:
2805         case BUILT_IN_LFLOORL:
2806         case BUILT_IN_LLFLOORL:
2807           name = "floorl";
2808           break;
2809         default:
2810           gcc_unreachable ();
2811         }
2812
2813       fntype = build_function_type_list (TREE_TYPE (arg),
2814                                          TREE_TYPE (arg), NULL_TREE);
2815       fallback_fndecl = build_fn_decl (name, fntype);
2816     }
2817
2818   exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
2819
2820   tmp = expand_normal (exp);
2821
2822   /* Truncate the result of floating point optab to integer
2823      via expand_fix ().  */
2824   target = gen_reg_rtx (mode);
2825   expand_fix (target, tmp, 0);
2826
2827   return target;
2828 }
2829
2830 /* Expand a call to one of the builtin math functions doing integer
2831    conversion (lrint).
2832    Return 0 if a normal call should be emitted rather than expanding the
2833    function in-line.  EXP is the expression that is a call to the builtin
2834    function; if convenient, the result should be placed in TARGET.  */
2835
2836 static rtx
2837 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2838 {
2839   convert_optab builtin_optab;
2840   rtx op0, insns;
2841   tree fndecl = get_callee_fndecl (exp);
2842   tree arg;
2843   enum machine_mode mode;
2844
2845   /* There's no easy way to detect the case we need to set EDOM.  */
2846   if (flag_errno_math)
2847     return NULL_RTX;
2848
2849   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2850      gcc_unreachable ();
2851
2852   arg = CALL_EXPR_ARG (exp, 0);
2853
2854   switch (DECL_FUNCTION_CODE (fndecl))
2855     {
2856     CASE_FLT_FN (BUILT_IN_IRINT):
2857     CASE_FLT_FN (BUILT_IN_LRINT):
2858     CASE_FLT_FN (BUILT_IN_LLRINT):
2859       builtin_optab = lrint_optab; break;
2860
2861     CASE_FLT_FN (BUILT_IN_IROUND):
2862     CASE_FLT_FN (BUILT_IN_LROUND):
2863     CASE_FLT_FN (BUILT_IN_LLROUND):
2864       builtin_optab = lround_optab; break;
2865
2866     default:
2867       gcc_unreachable ();
2868     }
2869
2870   /* Make a suitable register to place result in.  */
2871   mode = TYPE_MODE (TREE_TYPE (exp));
2872
2873   target = gen_reg_rtx (mode);
2874
2875   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2876      need to expand the argument again.  This way, we will not perform
2877      side-effects more the once.  */
2878   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2879
2880   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2881
2882   start_sequence ();
2883
2884   if (expand_sfix_optab (target, op0, builtin_optab))
2885     {
2886       /* Output the entire sequence.  */
2887       insns = get_insns ();
2888       end_sequence ();
2889       emit_insn (insns);
2890       return target;
2891     }
2892
2893   /* If we were unable to expand via the builtin, stop the sequence
2894      (without outputting the insns) and call to the library function
2895      with the stabilized argument list.  */
2896   end_sequence ();
2897
2898   target = expand_call (exp, target, target == const0_rtx);
2899
2900   return target;
2901 }
2902
2903 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
2904    a normal call should be emitted rather than expanding the function
2905    in-line.  EXP is the expression that is a call to the builtin
2906    function; if convenient, the result should be placed in TARGET.  */
2907
2908 static rtx
2909 expand_builtin_powi (tree exp, rtx target)
2910 {
2911   tree arg0, arg1;
2912   rtx op0, op1;
2913   enum machine_mode mode;
2914   enum machine_mode mode2;
2915
2916   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2917     return NULL_RTX;
2918
2919   arg0 = CALL_EXPR_ARG (exp, 0);
2920   arg1 = CALL_EXPR_ARG (exp, 1);
2921   mode = TYPE_MODE (TREE_TYPE (exp));
2922
2923   /* Emit a libcall to libgcc.  */
2924
2925   /* Mode of the 2nd argument must match that of an int.  */
2926   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2927
2928   if (target == NULL_RTX)
2929     target = gen_reg_rtx (mode);
2930
2931   op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL);
2932   if (GET_MODE (op0) != mode)
2933     op0 = convert_to_mode (mode, op0, 0);
2934   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
2935   if (GET_MODE (op1) != mode2)
2936     op1 = convert_to_mode (mode2, op1, 0);
2937
2938   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2939                                     target, LCT_CONST, mode, 2,
2940                                     op0, mode, op1, mode2);
2941
2942   return target;
2943 }
2944
2945 /* Expand expression EXP which is a call to the strlen builtin.  Return
2946    NULL_RTX if we failed the caller should emit a normal call, otherwise
2947    try to get the result in TARGET, if convenient.  */
2948
2949 static rtx
2950 expand_builtin_strlen (tree exp, rtx target,
2951                        enum machine_mode target_mode)
2952 {
2953   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2954     return NULL_RTX;
2955   else
2956     {
2957       struct expand_operand ops[4];
2958       rtx pat;
2959       tree len;
2960       tree src = CALL_EXPR_ARG (exp, 0);
2961       rtx src_reg, before_strlen;
2962       enum machine_mode insn_mode = target_mode;
2963       enum insn_code icode = CODE_FOR_nothing;
2964       unsigned int align;
2965
2966       /* If the length can be computed at compile-time, return it.  */
2967       len = c_strlen (src, 0);
2968       if (len)
2969         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2970
2971       /* If the length can be computed at compile-time and is constant
2972          integer, but there are side-effects in src, evaluate
2973          src for side-effects, then return len.
2974          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2975          can be optimized into: i++; x = 3;  */
2976       len = c_strlen (src, 1);
2977       if (len && TREE_CODE (len) == INTEGER_CST)
2978         {
2979           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2980           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2981         }
2982
2983       align = get_pointer_alignment (src) / BITS_PER_UNIT;
2984
2985       /* If SRC is not a pointer type, don't do this operation inline.  */
2986       if (align == 0)
2987         return NULL_RTX;
2988
2989       /* Bail out if we can't compute strlen in the right mode.  */
2990       while (insn_mode != VOIDmode)
2991         {
2992           icode = optab_handler (strlen_optab, insn_mode);
2993           if (icode != CODE_FOR_nothing)
2994             break;
2995
2996           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2997         }
2998       if (insn_mode == VOIDmode)
2999         return NULL_RTX;
3000
3001       /* Make a place to hold the source address.  We will not expand
3002          the actual source until we are sure that the expansion will
3003          not fail -- there are trees that cannot be expanded twice.  */
3004       src_reg = gen_reg_rtx (Pmode);
3005
3006       /* Mark the beginning of the strlen sequence so we can emit the
3007          source operand later.  */
3008       before_strlen = get_last_insn ();
3009
3010       create_output_operand (&ops[0], target, insn_mode);
3011       create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg));
3012       create_integer_operand (&ops[2], 0);
3013       create_integer_operand (&ops[3], align);
3014       if (!maybe_expand_insn (icode, 4, ops))
3015         return NULL_RTX;
3016
3017       /* Now that we are assured of success, expand the source.  */
3018       start_sequence ();
3019       pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL);
3020       if (pat != src_reg)
3021         {
3022 #ifdef POINTERS_EXTEND_UNSIGNED
3023           if (GET_MODE (pat) != Pmode)
3024             pat = convert_to_mode (Pmode, pat,
3025                                    POINTERS_EXTEND_UNSIGNED);
3026 #endif
3027           emit_move_insn (src_reg, pat);
3028         }
3029       pat = get_insns ();
3030       end_sequence ();
3031
3032       if (before_strlen)
3033         emit_insn_after (pat, before_strlen);
3034       else
3035         emit_insn_before (pat, get_insns ());
3036
3037       /* Return the value in the proper mode for this function.  */
3038       if (GET_MODE (ops[0].value) == target_mode)
3039         target = ops[0].value;
3040       else if (target != 0)
3041         convert_move (target, ops[0].value, 0);
3042       else
3043         target = convert_to_mode (target_mode, ops[0].value, 0);
3044
3045       return target;
3046     }
3047 }
3048
3049 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3050    bytes from constant string DATA + OFFSET and return it as target
3051    constant.  */
3052
3053 static rtx
3054 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3055                          enum machine_mode mode)
3056 {
3057   const char *str = (const char *) data;
3058
3059   gcc_assert (offset >= 0
3060               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3061                   <= strlen (str) + 1));
3062
3063   return c_readstr (str + offset, mode);
3064 }
3065
3066 /* Expand a call EXP to the memcpy builtin.
3067    Return NULL_RTX if we failed, the caller should emit a normal call,
3068    otherwise try to get the result in TARGET, if convenient (and in
3069    mode MODE if that's convenient).  */
3070
3071 static rtx
3072 expand_builtin_memcpy (tree exp, rtx target)
3073 {
3074   if (!validate_arglist (exp,
3075                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3076     return NULL_RTX;
3077   else
3078     {
3079       tree dest = CALL_EXPR_ARG (exp, 0);
3080       tree src = CALL_EXPR_ARG (exp, 1);
3081       tree len = CALL_EXPR_ARG (exp, 2);
3082       const char *src_str;
3083       unsigned int src_align = get_pointer_alignment (src);
3084       unsigned int dest_align = get_pointer_alignment (dest);
3085       rtx dest_mem, src_mem, dest_addr, len_rtx;
3086       HOST_WIDE_INT expected_size = -1;
3087       unsigned int expected_align = 0;
3088
3089       /* If DEST is not a pointer type, call the normal function.  */
3090       if (dest_align == 0)
3091         return NULL_RTX;
3092
3093       /* If either SRC is not a pointer type, don't do this
3094          operation in-line.  */
3095       if (src_align == 0)
3096         return NULL_RTX;
3097
3098       if (currently_expanding_gimple_stmt)
3099         stringop_block_profile (currently_expanding_gimple_stmt,
3100                                 &expected_align, &expected_size);
3101
3102       if (expected_align < dest_align)
3103         expected_align = dest_align;
3104       dest_mem = get_memory_rtx (dest, len);
3105       set_mem_align (dest_mem, dest_align);
3106       len_rtx = expand_normal (len);
3107       src_str = c_getstr (src);
3108
3109       /* If SRC is a string constant and block move would be done
3110          by pieces, we can avoid loading the string from memory
3111          and only stored the computed constants.  */
3112       if (src_str
3113           && CONST_INT_P (len_rtx)
3114           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3115           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3116                                   CONST_CAST (char *, src_str),
3117                                   dest_align, false))
3118         {
3119           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3120                                       builtin_memcpy_read_str,
3121                                       CONST_CAST (char *, src_str),
3122                                       dest_align, false, 0);
3123           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3124           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3125           return dest_mem;
3126         }
3127
3128       src_mem = get_memory_rtx (src, len);
3129       set_mem_align (src_mem, src_align);
3130
3131       /* Copy word part most expediently.  */
3132       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3133                                          CALL_EXPR_TAILCALL (exp)
3134                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3135                                          expected_align, expected_size);
3136
3137       if (dest_addr == 0)
3138         {
3139           dest_addr = force_operand (XEXP (dest_mem, 0), target);
3140           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3141         }
3142       return dest_addr;
3143     }
3144 }
3145
3146 /* Expand a call EXP to the mempcpy builtin.
3147    Return NULL_RTX if we failed; the caller should emit a normal call,
3148    otherwise try to get the result in TARGET, if convenient (and in
3149    mode MODE if that's convenient).  If ENDP is 0 return the
3150    destination pointer, if ENDP is 1 return the end pointer ala
3151    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3152    stpcpy.  */
3153
3154 static rtx
3155 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3156 {
3157   if (!validate_arglist (exp,
3158                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3159     return NULL_RTX;
3160   else
3161     {
3162       tree dest = CALL_EXPR_ARG (exp, 0);
3163       tree src = CALL_EXPR_ARG (exp, 1);
3164       tree len = CALL_EXPR_ARG (exp, 2);
3165       return expand_builtin_mempcpy_args (dest, src, len,
3166                                           target, mode, /*endp=*/ 1);
3167     }
3168 }
3169
3170 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3171    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3172    so that this can also be called without constructing an actual CALL_EXPR.
3173    The other arguments and return value are the same as for
3174    expand_builtin_mempcpy.  */
3175
3176 static rtx
3177 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3178                              rtx target, enum machine_mode mode, int endp)
3179 {
3180     /* If return value is ignored, transform mempcpy into memcpy.  */
3181   if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
3182     {
3183       tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3184       tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
3185                                            dest, src, len);
3186       return expand_expr (result, target, mode, EXPAND_NORMAL);
3187     }
3188   else
3189     {
3190       const char *src_str;
3191       unsigned int src_align = get_pointer_alignment (src);
3192       unsigned int dest_align = get_pointer_alignment (dest);
3193       rtx dest_mem, src_mem, len_rtx;
3194
3195       /* If either SRC or DEST is not a pointer type, don't do this
3196          operation in-line.  */
3197       if (dest_align == 0 || src_align == 0)
3198         return NULL_RTX;
3199
3200       /* If LEN is not constant, call the normal function.  */
3201       if (! host_integerp (len, 1))
3202         return NULL_RTX;
3203
3204       len_rtx = expand_normal (len);
3205       src_str = c_getstr (src);
3206
3207       /* If SRC is a string constant and block move would be done
3208          by pieces, we can avoid loading the string from memory
3209          and only stored the computed constants.  */
3210       if (src_str
3211           && CONST_INT_P (len_rtx)
3212           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3213           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3214                                   CONST_CAST (char *, src_str),
3215                                   dest_align, false))
3216         {
3217           dest_mem = get_memory_rtx (dest, len);
3218           set_mem_align (dest_mem, dest_align);
3219           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3220                                       builtin_memcpy_read_str,
3221                                       CONST_CAST (char *, src_str),
3222                                       dest_align, false, 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;
3226         }
3227
3228       if (CONST_INT_P (len_rtx)
3229           && can_move_by_pieces (INTVAL (len_rtx),
3230                                  MIN (dest_align, src_align)))
3231         {
3232           dest_mem = get_memory_rtx (dest, len);
3233           set_mem_align (dest_mem, dest_align);
3234           src_mem = get_memory_rtx (src, len);
3235           set_mem_align (src_mem, src_align);
3236           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3237                                      MIN (dest_align, src_align), endp);
3238           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3239           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3240           return dest_mem;
3241         }
3242
3243       return NULL_RTX;
3244     }
3245 }
3246
3247 #ifndef HAVE_movstr
3248 # define HAVE_movstr 0
3249 # define CODE_FOR_movstr CODE_FOR_nothing
3250 #endif
3251
3252 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3253    we failed, the caller should emit a normal call, otherwise try to
3254    get the result in TARGET, if convenient.  If ENDP is 0 return the
3255    destination pointer, if ENDP is 1 return the end pointer ala
3256    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3257    stpcpy.  */
3258
3259 static rtx
3260 expand_movstr (tree dest, tree src, rtx target, int endp)
3261 {
3262   struct expand_operand ops[3];
3263   rtx dest_mem;
3264   rtx src_mem;
3265
3266   if (!HAVE_movstr)
3267     return NULL_RTX;
3268
3269   dest_mem = get_memory_rtx (dest, NULL);
3270   src_mem = get_memory_rtx (src, NULL);
3271   if (!endp)
3272     {
3273       target = force_reg (Pmode, XEXP (dest_mem, 0));
3274       dest_mem = replace_equiv_address (dest_mem, target);
3275     }
3276
3277   create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
3278   create_fixed_operand (&ops[1], dest_mem);
3279   create_fixed_operand (&ops[2], src_mem);
3280   expand_insn (CODE_FOR_movstr, 3, ops);
3281
3282   if (endp && target != const0_rtx)
3283     {
3284       target = ops[0].value;
3285       /* movstr is supposed to set end to the address of the NUL
3286          terminator.  If the caller requested a mempcpy-like return value,
3287          adjust it.  */
3288       if (endp == 1)
3289         {
3290           rtx tem = plus_constant (gen_lowpart (GET_MODE (target), target), 1);
3291           emit_move_insn (target, force_operand (tem, NULL_RTX));
3292         }
3293     }
3294   return target;
3295 }
3296
3297 /* Expand expression EXP, which is a call to the strcpy builtin.  Return
3298    NULL_RTX if we failed the caller should emit a normal call, otherwise
3299    try to get the result in TARGET, if convenient (and in mode MODE if that's
3300    convenient).  */
3301
3302 static rtx
3303 expand_builtin_strcpy (tree exp, rtx target)
3304 {
3305   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3306    {
3307      tree dest = CALL_EXPR_ARG (exp, 0);
3308      tree src = CALL_EXPR_ARG (exp, 1);
3309      return expand_builtin_strcpy_args (dest, src, target);
3310    }
3311    return NULL_RTX;
3312 }
3313
3314 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3315    arguments to the builtin_strcpy call DEST and SRC are broken out
3316    so that this can also be called without constructing an actual CALL_EXPR.
3317    The other arguments and return value are the same as for
3318    expand_builtin_strcpy.  */
3319
3320 static rtx
3321 expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3322 {
3323   return expand_movstr (dest, src, target, /*endp=*/0);
3324 }
3325
3326 /* Expand a call EXP to the stpcpy builtin.
3327    Return NULL_RTX if we failed the caller should emit a normal call,
3328    otherwise try to get the result in TARGET, if convenient (and in
3329    mode MODE if that's convenient).  */
3330
3331 static rtx
3332 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3333 {
3334   tree dst, src;
3335   location_t loc = EXPR_LOCATION (exp);
3336
3337   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3338     return NULL_RTX;
3339
3340   dst = CALL_EXPR_ARG (exp, 0);
3341   src = CALL_EXPR_ARG (exp, 1);
3342
3343   /* If return value is ignored, transform stpcpy into strcpy.  */
3344   if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY))
3345     {
3346       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3347       tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
3348       return expand_expr (result, target, mode, EXPAND_NORMAL);
3349     }
3350   else
3351     {
3352       tree len, lenp1;
3353       rtx ret;
3354
3355       /* Ensure we get an actual string whose length can be evaluated at
3356          compile-time, not an expression containing a string.  This is
3357          because the latter will potentially produce pessimized code
3358          when used to produce the return value.  */
3359       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3360         return expand_movstr (dst, src, target, /*endp=*/2);
3361
3362       lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3363       ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3364                                          target, mode, /*endp=*/2);
3365
3366       if (ret)
3367         return ret;
3368
3369       if (TREE_CODE (len) == INTEGER_CST)
3370         {
3371           rtx len_rtx = expand_normal (len);
3372
3373           if (CONST_INT_P (len_rtx))
3374             {
3375               ret = expand_builtin_strcpy_args (dst, src, target);
3376
3377               if (ret)
3378                 {
3379                   if (! target)
3380                     {
3381                       if (mode != VOIDmode)
3382                         target = gen_reg_rtx (mode);
3383                       else
3384                         target = gen_reg_rtx (GET_MODE (ret));
3385                     }
3386                   if (GET_MODE (target) != GET_MODE (ret))
3387                     ret = gen_lowpart (GET_MODE (target), ret);
3388
3389                   ret = plus_constant (ret, INTVAL (len_rtx));
3390                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3391                   gcc_assert (ret);
3392
3393                   return target;
3394                 }
3395             }
3396         }
3397
3398       return expand_movstr (dst, src, target, /*endp=*/2);
3399     }
3400 }
3401
3402 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3403    bytes from constant string DATA + OFFSET and return it as target
3404    constant.  */
3405
3406 rtx
3407 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3408                           enum machine_mode mode)
3409 {
3410   const char *str = (const char *) data;
3411
3412   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3413     return const0_rtx;
3414
3415   return c_readstr (str + offset, mode);
3416 }
3417
3418 /* Expand expression EXP, which is a call to the strncpy builtin.  Return
3419    NULL_RTX if we failed the caller should emit a normal call.  */
3420
3421 static rtx
3422 expand_builtin_strncpy (tree exp, rtx target)
3423 {
3424   location_t loc = EXPR_LOCATION (exp);
3425
3426   if (validate_arglist (exp,
3427                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3428     {
3429       tree dest = CALL_EXPR_ARG (exp, 0);
3430       tree src = CALL_EXPR_ARG (exp, 1);
3431       tree len = CALL_EXPR_ARG (exp, 2);
3432       tree slen = c_strlen (src, 1);
3433
3434       /* We must be passed a constant len and src parameter.  */
3435       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3436         return NULL_RTX;
3437
3438       slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3439
3440       /* We're required to pad with trailing zeros if the requested
3441          len is greater than strlen(s2)+1.  In that case try to
3442          use store_by_pieces, if it fails, punt.  */
3443       if (tree_int_cst_lt (slen, len))
3444         {
3445           unsigned int dest_align = get_pointer_alignment (dest);
3446           const char *p = c_getstr (src);
3447           rtx dest_mem;
3448
3449           if (!p || dest_align == 0 || !host_integerp (len, 1)
3450               || !can_store_by_pieces (tree_low_cst (len, 1),
3451                                        builtin_strncpy_read_str,
3452                                        CONST_CAST (char *, p),
3453                                        dest_align, false))
3454             return NULL_RTX;
3455
3456           dest_mem = get_memory_rtx (dest, len);
3457           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3458                            builtin_strncpy_read_str,
3459                            CONST_CAST (char *, p), dest_align, false, 0);
3460           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3461           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3462           return dest_mem;
3463         }
3464     }
3465   return NULL_RTX;
3466 }
3467
3468 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3469    bytes from constant string DATA + OFFSET and return it as target
3470    constant.  */
3471
3472 rtx
3473 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3474                          enum machine_mode mode)
3475 {
3476   const char *c = (const char *) data;
3477   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3478
3479   memset (p, *c, GET_MODE_SIZE (mode));
3480
3481   return c_readstr (p, mode);
3482 }
3483
3484 /* Callback routine for store_by_pieces.  Return the RTL of a register
3485    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3486    char value given in the RTL register data.  For example, if mode is
3487    4 bytes wide, return the RTL for 0x01010101*data.  */
3488
3489 static rtx
3490 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3491                         enum machine_mode mode)
3492 {
3493   rtx target, coeff;
3494   size_t size;
3495   char *p;
3496
3497   size = GET_MODE_SIZE (mode);
3498   if (size == 1)
3499     return (rtx) data;
3500
3501   p = XALLOCAVEC (char, size);
3502   memset (p, 1, size);
3503   coeff = c_readstr (p, mode);
3504
3505   target = convert_to_mode (mode, (rtx) data, 1);
3506   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3507   return force_reg (mode, target);
3508 }
3509
3510 /* Expand expression EXP, which is a call to the memset builtin.  Return
3511    NULL_RTX if we failed the caller should emit a normal call, otherwise
3512    try to get the result in TARGET, if convenient (and in mode MODE if that's
3513    convenient).  */
3514
3515 static rtx
3516 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3517 {
3518   if (!validate_arglist (exp,
3519                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3520     return NULL_RTX;
3521   else
3522     {
3523       tree dest = CALL_EXPR_ARG (exp, 0);
3524       tree val = CALL_EXPR_ARG (exp, 1);
3525       tree len = CALL_EXPR_ARG (exp, 2);
3526       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3527     }
3528 }
3529
3530 /* Helper function to do the actual work for expand_builtin_memset.  The
3531    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3532    so that this can also be called without constructing an actual CALL_EXPR.
3533    The other arguments and return value are the same as for
3534    expand_builtin_memset.  */
3535
3536 static rtx
3537 expand_builtin_memset_args (tree dest, tree val, tree len,
3538                             rtx target, enum machine_mode mode, tree orig_exp)
3539 {
3540   tree fndecl, fn;
3541   enum built_in_function fcode;
3542   enum machine_mode val_mode;
3543   char c;
3544   unsigned int dest_align;
3545   rtx dest_mem, dest_addr, len_rtx;
3546   HOST_WIDE_INT expected_size = -1;
3547   unsigned int expected_align = 0;
3548
3549   dest_align = get_pointer_alignment (dest);
3550
3551   /* If DEST is not a pointer type, don't do this operation in-line.  */
3552   if (dest_align == 0)
3553     return NULL_RTX;
3554
3555   if (currently_expanding_gimple_stmt)
3556     stringop_block_profile (currently_expanding_gimple_stmt,
3557                             &expected_align, &expected_size);
3558
3559   if (expected_align < dest_align)
3560     expected_align = dest_align;
3561
3562   /* If the LEN parameter is zero, return DEST.  */
3563   if (integer_zerop (len))
3564     {
3565       /* Evaluate and ignore VAL in case it has side-effects.  */
3566       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3567       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3568     }
3569
3570   /* Stabilize the arguments in case we fail.  */
3571   dest = builtin_save_expr (dest);
3572   val = builtin_save_expr (val);
3573   len = builtin_save_expr (len);
3574
3575   len_rtx = expand_normal (len);
3576   dest_mem = get_memory_rtx (dest, len);
3577   val_mode = TYPE_MODE (unsigned_char_type_node);
3578
3579   if (TREE_CODE (val) != INTEGER_CST)
3580     {
3581       rtx val_rtx;
3582
3583       val_rtx = expand_normal (val);
3584       val_rtx = convert_to_mode (val_mode, val_rtx, 0);
3585
3586       /* Assume that we can memset by pieces if we can store
3587        * the coefficients by pieces (in the required modes).
3588        * We can't pass builtin_memset_gen_str as that emits RTL.  */
3589       c = 1;
3590       if (host_integerp (len, 1)
3591           && can_store_by_pieces (tree_low_cst (len, 1),
3592                                   builtin_memset_read_str, &c, dest_align,
3593                                   true))
3594         {
3595           val_rtx = force_reg (val_mode, val_rtx);
3596           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3597                            builtin_memset_gen_str, val_rtx, dest_align,
3598                            true, 0);
3599         }
3600       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3601                                         dest_align, expected_align,
3602                                         expected_size))
3603         goto do_libcall;
3604
3605       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3606       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3607       return dest_mem;
3608     }
3609
3610   if (target_char_cast (val, &c))
3611     goto do_libcall;
3612
3613   if (c)
3614     {
3615       if (host_integerp (len, 1)
3616           && can_store_by_pieces (tree_low_cst (len, 1),
3617                                   builtin_memset_read_str, &c, dest_align,
3618                                   true))
3619         store_by_pieces (dest_mem, tree_low_cst (len, 1),
3620                          builtin_memset_read_str, &c, dest_align, true, 0);
3621       else if (!set_storage_via_setmem (dest_mem, len_rtx,
3622                                         gen_int_mode (c, val_mode),
3623                                         dest_align, expected_align,
3624                                         expected_size))
3625         goto do_libcall;
3626
3627       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3628       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3629       return dest_mem;
3630     }
3631
3632   set_mem_align (dest_mem, dest_align);
3633   dest_addr = clear_storage_hints (dest_mem, len_rtx,
3634                                    CALL_EXPR_TAILCALL (orig_exp)
3635                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3636                                    expected_align, expected_size);
3637
3638   if (dest_addr == 0)
3639     {
3640       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3641       dest_addr = convert_memory_address (ptr_mode, dest_addr);
3642     }
3643
3644   return dest_addr;
3645
3646  do_libcall:
3647   fndecl = get_callee_fndecl (orig_exp);
3648   fcode = DECL_FUNCTION_CODE (fndecl);
3649   if (fcode == BUILT_IN_MEMSET)
3650     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
3651                                 dest, val, len);
3652   else if (fcode == BUILT_IN_BZERO)
3653     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2,
3654                                 dest, len);
3655   else
3656     gcc_unreachable ();
3657   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3658   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3659   return expand_call (fn, target, target == const0_rtx);
3660 }
3661
3662 /* Expand expression EXP, which is a call to the bzero builtin.  Return
3663    NULL_RTX if we failed the caller should emit a normal call.  */
3664
3665 static rtx
3666 expand_builtin_bzero (tree exp)
3667 {
3668   tree dest, size;
3669   location_t loc = EXPR_LOCATION (exp);
3670
3671   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3672     return NULL_RTX;
3673
3674   dest = CALL_EXPR_ARG (exp, 0);
3675   size = CALL_EXPR_ARG (exp, 1);
3676
3677   /* New argument list transforming bzero(ptr x, int y) to
3678      memset(ptr x, int 0, size_t y).   This is done this way
3679      so that if it isn't expanded inline, we fallback to
3680      calling bzero instead of memset.  */
3681
3682   return expand_builtin_memset_args (dest, integer_zero_node,
3683                                      fold_convert_loc (loc,
3684                                                        size_type_node, size),
3685                                      const0_rtx, VOIDmode, exp);
3686 }
3687
3688 /* Expand expression EXP, which is a call to the memcmp built-in function.
3689    Return NULL_RTX if we failed and the caller should emit a normal call,
3690    otherwise try to get the result in TARGET, if convenient (and in mode
3691    MODE, if that's convenient).  */
3692
3693 static rtx
3694 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3695                        ATTRIBUTE_UNUSED enum machine_mode mode)
3696 {
3697   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3698
3699   if (!validate_arglist (exp,
3700                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3701     return NULL_RTX;
3702
3703   /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
3704      implementing memcmp because it will stop if it encounters two
3705      zero bytes.  */
3706 #if defined HAVE_cmpmemsi
3707   {
3708     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3709     rtx result;
3710     rtx insn;
3711     tree arg1 = CALL_EXPR_ARG (exp, 0);
3712     tree arg2 = CALL_EXPR_ARG (exp, 1);
3713     tree len = CALL_EXPR_ARG (exp, 2);
3714
3715     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3716     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3717     enum machine_mode insn_mode;
3718
3719     if (HAVE_cmpmemsi)
3720       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3721     else
3722       return NULL_RTX;
3723
3724     /* If we don't have POINTER_TYPE, call the function.  */
3725     if (arg1_align == 0 || arg2_align == 0)
3726       return NULL_RTX;
3727
3728     /* Make a place to write the result of the instruction.  */
3729     result = target;
3730     if (! (result != 0
3731            && REG_P (result) && GET_MODE (result) == insn_mode
3732            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3733       result = gen_reg_rtx (insn_mode);
3734
3735     arg1_rtx = get_memory_rtx (arg1, len);
3736     arg2_rtx = get_memory_rtx (arg2, len);
3737     arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3738
3739     /* Set MEM_SIZE as appropriate.  */
3740     if (CONST_INT_P (arg3_rtx))
3741       {
3742         set_mem_size (arg1_rtx, INTVAL (arg3_rtx));
3743         set_mem_size (arg2_rtx, INTVAL (arg3_rtx));
3744       }
3745
3746     if (HAVE_cmpmemsi)
3747       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3748                            GEN_INT (MIN (arg1_align, arg2_align)));
3749     else
3750       gcc_unreachable ();
3751
3752     if (insn)
3753       emit_insn (insn);
3754     else
3755       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3756                                TYPE_MODE (integer_type_node), 3,
3757                                XEXP (arg1_rtx, 0), Pmode,
3758                                XEXP (arg2_rtx, 0), Pmode,
3759                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3760                                                 TYPE_UNSIGNED (sizetype)),
3761                                TYPE_MODE (sizetype));
3762
3763     /* Return the value in the proper mode for this function.  */
3764     mode = TYPE_MODE (TREE_TYPE (exp));
3765     if (GET_MODE (result) == mode)
3766       return result;
3767     else if (target != 0)
3768       {
3769         convert_move (target, result, 0);
3770         return target;
3771       }
3772     else
3773       return convert_to_mode (mode, result, 0);
3774   }
3775 #endif /* HAVE_cmpmemsi.  */
3776
3777   return NULL_RTX;
3778 }
3779
3780 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
3781    if we failed the caller should emit a normal call, otherwise try to get
3782    the result in TARGET, if convenient.  */
3783
3784 static rtx
3785 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3786 {
3787   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3788     return NULL_RTX;
3789
3790 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3791   if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing
3792       || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing)
3793     {
3794       rtx arg1_rtx, arg2_rtx;
3795       rtx result, insn = NULL_RTX;
3796       tree fndecl, fn;
3797       tree arg1 = CALL_EXPR_ARG (exp, 0);
3798       tree arg2 = CALL_EXPR_ARG (exp, 1);
3799
3800       unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3801       unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3802
3803       /* If we don't have POINTER_TYPE, call the function.  */
3804       if (arg1_align == 0 || arg2_align == 0)
3805         return NULL_RTX;
3806
3807       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3808       arg1 = builtin_save_expr (arg1);
3809       arg2 = builtin_save_expr (arg2);
3810
3811       arg1_rtx = get_memory_rtx (arg1, NULL);
3812       arg2_rtx = get_memory_rtx (arg2, NULL);
3813
3814 #ifdef HAVE_cmpstrsi
3815       /* Try to call cmpstrsi.  */
3816       if (HAVE_cmpstrsi)
3817         {
3818           enum machine_mode insn_mode
3819             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3820
3821           /* Make a place to write the result of the instruction.  */
3822           result = target;
3823           if (! (result != 0
3824                  && REG_P (result) && GET_MODE (result) == insn_mode
3825                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3826             result = gen_reg_rtx (insn_mode);
3827
3828           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3829                                GEN_INT (MIN (arg1_align, arg2_align)));
3830         }
3831 #endif
3832 #ifdef HAVE_cmpstrnsi
3833       /* Try to determine at least one length and call cmpstrnsi.  */
3834       if (!insn && HAVE_cmpstrnsi)
3835         {
3836           tree len;
3837           rtx arg3_rtx;
3838
3839           enum machine_mode insn_mode
3840             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3841           tree len1 = c_strlen (arg1, 1);
3842           tree len2 = c_strlen (arg2, 1);
3843
3844           if (len1)
3845             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3846           if (len2)
3847             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3848
3849           /* If we don't have a constant length for the first, use the length
3850              of the second, if we know it.  We don't require a constant for
3851              this case; some cost analysis could be done if both are available
3852              but neither is constant.  For now, assume they're equally cheap,
3853              unless one has side effects.  If both strings have constant lengths,
3854              use the smaller.  */
3855
3856           if (!len1)
3857             len = len2;
3858           else if (!len2)
3859             len = len1;
3860           else if (TREE_SIDE_EFFECTS (len1))
3861             len = len2;
3862           else if (TREE_SIDE_EFFECTS (len2))
3863             len = len1;
3864           else if (TREE_CODE (len1) != INTEGER_CST)
3865             len = len2;
3866           else if (TREE_CODE (len2) != INTEGER_CST)
3867             len = len1;
3868           else if (tree_int_cst_lt (len1, len2))
3869             len = len1;
3870           else
3871             len = len2;
3872
3873           /* If both arguments have side effects, we cannot optimize.  */
3874           if (!len || TREE_SIDE_EFFECTS (len))
3875             goto do_libcall;
3876
3877           arg3_rtx = expand_normal (len);
3878
3879           /* Make a place to write the result of the instruction.  */
3880           result = target;
3881           if (! (result != 0
3882                  && REG_P (result) && GET_MODE (result) == insn_mode
3883                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3884             result = gen_reg_rtx (insn_mode);
3885
3886           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3887                                 GEN_INT (MIN (arg1_align, arg2_align)));
3888         }
3889 #endif
3890
3891       if (insn)
3892         {
3893           enum machine_mode mode;
3894           emit_insn (insn);
3895
3896           /* Return the value in the proper mode for this function.  */
3897           mode = TYPE_MODE (TREE_TYPE (exp));
3898           if (GET_MODE (result) == mode)
3899             return result;
3900           if (target == 0)
3901             return convert_to_mode (mode, result, 0);
3902           convert_move (target, result, 0);
3903           return target;
3904         }
3905
3906       /* Expand the library call ourselves using a stabilized argument
3907          list to avoid re-evaluating the function's arguments twice.  */
3908 #ifdef HAVE_cmpstrnsi
3909     do_libcall:
3910 #endif
3911       fndecl = get_callee_fndecl (exp);
3912       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
3913       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3914       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3915       return expand_call (fn, target, target == const0_rtx);
3916     }
3917 #endif
3918   return NULL_RTX;
3919 }
3920
3921 /* Expand expression EXP, which is a call to the strncmp builtin. Return
3922    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
3923    the result in TARGET, if convenient.  */
3924
3925 static rtx
3926 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3927                         ATTRIBUTE_UNUSED enum machine_mode mode)
3928 {
3929   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3930
3931   if (!validate_arglist (exp,
3932                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3933     return NULL_RTX;
3934
3935   /* If c_strlen can determine an expression for one of the string
3936      lengths, and it doesn't have side effects, then emit cmpstrnsi
3937      using length MIN(strlen(string)+1, arg3).  */
3938 #ifdef HAVE_cmpstrnsi
3939   if (HAVE_cmpstrnsi)
3940   {
3941     tree len, len1, len2;
3942     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3943     rtx result, insn;
3944     tree fndecl, fn;
3945     tree arg1 = CALL_EXPR_ARG (exp, 0);
3946     tree arg2 = CALL_EXPR_ARG (exp, 1);
3947     tree arg3 = CALL_EXPR_ARG (exp, 2);
3948
3949     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3950     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3951     enum machine_mode insn_mode
3952       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3953
3954     len1 = c_strlen (arg1, 1);
3955     len2 = c_strlen (arg2, 1);
3956
3957     if (len1)
3958       len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
3959     if (len2)
3960       len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
3961
3962     /* If we don't have a constant length for the first, use the length
3963        of the second, if we know it.  We don't require a constant for
3964        this case; some cost analysis could be done if both are available
3965        but neither is constant.  For now, assume they're equally cheap,
3966        unless one has side effects.  If both strings have constant lengths,
3967        use the smaller.  */
3968
3969     if (!len1)
3970       len = len2;
3971     else if (!len2)
3972       len = len1;
3973     else if (TREE_SIDE_EFFECTS (len1))
3974       len = len2;
3975     else if (TREE_SIDE_EFFECTS (len2))
3976       len = len1;
3977     else if (TREE_CODE (len1) != INTEGER_CST)
3978       len = len2;
3979     else if (TREE_CODE (len2) != INTEGER_CST)
3980       len = len1;
3981     else if (tree_int_cst_lt (len1, len2))
3982       len = len1;
3983     else
3984       len = len2;
3985
3986     /* If both arguments have side effects, we cannot optimize.  */
3987     if (!len || TREE_SIDE_EFFECTS (len))
3988       return NULL_RTX;
3989
3990     /* The actual new length parameter is MIN(len,arg3).  */
3991     len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
3992                        fold_convert_loc (loc, TREE_TYPE (len), arg3));
3993
3994     /* If we don't have POINTER_TYPE, call the function.  */
3995     if (arg1_align == 0 || arg2_align == 0)
3996       return NULL_RTX;
3997
3998     /* Make a place to write the result of the instruction.  */
3999     result = target;
4000     if (! (result != 0
4001            && REG_P (result) && GET_MODE (result) == insn_mode
4002            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4003       result = gen_reg_rtx (insn_mode);
4004
4005     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
4006     arg1 = builtin_save_expr (arg1);
4007     arg2 = builtin_save_expr (arg2);
4008     len = builtin_save_expr (len);
4009
4010     arg1_rtx = get_memory_rtx (arg1, len);
4011     arg2_rtx = get_memory_rtx (arg2, len);
4012     arg3_rtx = expand_normal (len);
4013     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4014                           GEN_INT (MIN (arg1_align, arg2_align)));
4015     if (insn)
4016       {
4017         emit_insn (insn);
4018
4019         /* Return the value in the proper mode for this function.  */
4020         mode = TYPE_MODE (TREE_TYPE (exp));
4021         if (GET_MODE (result) == mode)
4022           return result;
4023         if (target == 0)
4024           return convert_to_mode (mode, result, 0);
4025         convert_move (target, result, 0);
4026         return target;
4027       }
4028
4029     /* Expand the library call ourselves using a stabilized argument
4030        list to avoid re-evaluating the function's arguments twice.  */
4031     fndecl = get_callee_fndecl (exp);
4032     fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
4033                                 arg1, arg2, len);
4034     gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4035     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4036     return expand_call (fn, target, target == const0_rtx);
4037   }
4038 #endif
4039   return NULL_RTX;
4040 }
4041
4042 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4043    if that's convenient.  */
4044
4045 rtx
4046 expand_builtin_saveregs (void)
4047 {
4048   rtx val, seq;
4049
4050   /* Don't do __builtin_saveregs more than once in a function.
4051      Save the result of the first call and reuse it.  */
4052   if (saveregs_value != 0)
4053     return saveregs_value;
4054
4055   /* When this function is called, it means that registers must be
4056      saved on entry to this function.  So we migrate the call to the
4057      first insn of this function.  */
4058
4059   start_sequence ();
4060
4061   /* Do whatever the machine needs done in this case.  */
4062   val = targetm.calls.expand_builtin_saveregs ();
4063
4064   seq = get_insns ();
4065   end_sequence ();
4066
4067   saveregs_value = val;
4068
4069   /* Put the insns after the NOTE that starts the function.  If this
4070      is inside a start_sequence, make the outer-level insn chain current, so
4071      the code is placed at the start of the function.  */
4072   push_topmost_sequence ();
4073   emit_insn_after (seq, entry_of_function ());
4074   pop_topmost_sequence ();
4075
4076   return val;
4077 }
4078
4079 /* Expand a call to __builtin_next_arg.  */
4080
4081 static rtx
4082 expand_builtin_next_arg (void)
4083 {
4084   /* Checking arguments is already done in fold_builtin_next_arg
4085      that must be called before this function.  */
4086   return expand_binop (ptr_mode, add_optab,
4087                        crtl->args.internal_arg_pointer,
4088                        crtl->args.arg_offset_rtx,
4089                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4090 }
4091
4092 /* Make it easier for the backends by protecting the valist argument
4093    from multiple evaluations.  */
4094
4095 static tree
4096 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4097 {
4098   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4099
4100   /* The current way of determining the type of valist is completely
4101      bogus.  We should have the information on the va builtin instead.  */
4102   if (!vatype)
4103     vatype = targetm.fn_abi_va_list (cfun->decl);
4104
4105   if (TREE_CODE (vatype) == ARRAY_TYPE)
4106     {
4107       if (TREE_SIDE_EFFECTS (valist))
4108         valist = save_expr (valist);
4109
4110       /* For this case, the backends will be expecting a pointer to
4111          vatype, but it's possible we've actually been given an array
4112          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4113          So fix it.  */
4114       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4115         {
4116           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4117           valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4118         }
4119     }
4120   else
4121     {
4122       tree pt = build_pointer_type (vatype);
4123
4124       if (! needs_lvalue)
4125         {
4126           if (! TREE_SIDE_EFFECTS (valist))
4127             return valist;
4128
4129           valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4130           TREE_SIDE_EFFECTS (valist) = 1;
4131         }
4132
4133       if (TREE_SIDE_EFFECTS (valist))
4134         valist = save_expr (valist);
4135       valist = fold_build2_loc (loc, MEM_REF,
4136                                 vatype, valist, build_int_cst (pt, 0));
4137     }
4138
4139   return valist;
4140 }
4141
4142 /* The "standard" definition of va_list is void*.  */
4143
4144 tree
4145 std_build_builtin_va_list (void)
4146 {
4147   return ptr_type_node;
4148 }
4149
4150 /* The "standard" abi va_list is va_list_type_node.  */
4151
4152 tree
4153 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4154 {
4155   return va_list_type_node;
4156 }
4157
4158 /* The "standard" type of va_list is va_list_type_node.  */
4159
4160 tree
4161 std_canonical_va_list_type (tree type)
4162 {
4163   tree wtype, htype;
4164
4165   if (INDIRECT_REF_P (type))
4166     type = TREE_TYPE (type);
4167   else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4168     type = TREE_TYPE (type);
4169   wtype = va_list_type_node;
4170   htype = type;
4171   /* Treat structure va_list types.  */
4172   if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4173     htype = TREE_TYPE (htype);
4174   else if (TREE_CODE (wtype) == ARRAY_TYPE)
4175     {
4176       /* If va_list is an array type, the argument may have decayed
4177          to a pointer type, e.g. by being passed to another function.
4178          In that case, unwrap both types so that we can compare the
4179          underlying records.  */
4180       if (TREE_CODE (htype) == ARRAY_TYPE
4181           || POINTER_TYPE_P (htype))
4182         {
4183           wtype = TREE_TYPE (wtype);
4184           htype = TREE_TYPE (htype);
4185         }
4186     }
4187   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4188     return va_list_type_node;
4189
4190   return NULL_TREE;
4191 }
4192
4193 /* The "standard" implementation of va_start: just assign `nextarg' to
4194    the variable.  */
4195
4196 void
4197 std_expand_builtin_va_start (tree valist, rtx nextarg)
4198 {
4199   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4200   convert_move (va_r, nextarg, 0);
4201 }
4202
4203 /* Expand EXP, a call to __builtin_va_start.  */
4204
4205 static rtx
4206 expand_builtin_va_start (tree exp)
4207 {
4208   rtx nextarg;
4209   tree valist;
4210   location_t loc = EXPR_LOCATION (exp);
4211
4212   if (call_expr_nargs (exp) < 2)
4213     {
4214       error_at (loc, "too few arguments to function %<va_start%>");
4215       return const0_rtx;
4216     }
4217
4218   if (fold_builtin_next_arg (exp, true))
4219     return const0_rtx;
4220
4221   nextarg = expand_builtin_next_arg ();
4222   valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4223
4224   if (targetm.expand_builtin_va_start)
4225     targetm.expand_builtin_va_start (valist, nextarg);
4226   else
4227     std_expand_builtin_va_start (valist, nextarg);
4228
4229   return const0_rtx;
4230 }
4231
4232 /* The "standard" implementation of va_arg: read the value from the
4233    current (padded) address and increment by the (padded) size.  */
4234
4235 tree
4236 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4237                           gimple_seq *post_p)
4238 {
4239   tree addr, t, type_size, rounded_size, valist_tmp;
4240   unsigned HOST_WIDE_INT align, boundary;
4241   bool indirect;
4242
4243 #ifdef ARGS_GROW_DOWNWARD
4244   /* All of the alignment and movement below is for args-grow-up machines.
4245      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4246      implement their own specialized gimplify_va_arg_expr routines.  */
4247   gcc_unreachable ();
4248 #endif
4249
4250   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4251   if (indirect)
4252     type = build_pointer_type (type);
4253
4254   align = PARM_BOUNDARY / BITS_PER_UNIT;
4255   boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
4256
4257   /* When we align parameter on stack for caller, if the parameter
4258      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4259      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4260      here with caller.  */
4261   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4262     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4263
4264   boundary /= BITS_PER_UNIT;
4265
4266   /* Hoist the valist value into a temporary for the moment.  */
4267   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4268
4269   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4270      requires greater alignment, we must perform dynamic alignment.  */
4271   if (boundary > align
4272       && !integer_zerop (TYPE_SIZE (type)))
4273     {
4274       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4275                   fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
4276       gimplify_and_add (t, pre_p);
4277
4278       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4279                   fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
4280                                valist_tmp,
4281                                build_int_cst (TREE_TYPE (valist), -boundary)));
4282       gimplify_and_add (t, pre_p);
4283     }
4284   else
4285     boundary = align;
4286
4287   /* If the actual alignment is less than the alignment of the type,
4288      adjust the type accordingly so that we don't assume strict alignment
4289      when dereferencing the pointer.  */
4290   boundary *= BITS_PER_UNIT;
4291   if (boundary < TYPE_ALIGN (type))
4292     {
4293       type = build_variant_type_copy (type);
4294       TYPE_ALIGN (type) = boundary;
4295     }
4296
4297   /* Compute the rounded size of the type.  */
4298   type_size = size_in_bytes (type);
4299   rounded_size = round_up (type_size, align);
4300
4301   /* Reduce rounded_size so it's sharable with the postqueue.  */
4302   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4303
4304   /* Get AP.  */
4305   addr = valist_tmp;
4306   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4307     {
4308       /* Small args are padded downward.  */
4309       t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4310                        rounded_size, size_int (align));
4311       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4312                        size_binop (MINUS_EXPR, rounded_size, type_size));
4313       addr = fold_build_pointer_plus (addr, t);
4314     }
4315
4316   /* Compute new value for AP.  */
4317   t = fold_build_pointer_plus (valist_tmp, rounded_size);
4318   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4319   gimplify_and_add (t, pre_p);
4320
4321   addr = fold_convert (build_pointer_type (type), addr);
4322
4323   if (indirect)
4324     addr = build_va_arg_indirect_ref (addr);
4325
4326   return build_va_arg_indirect_ref (addr);
4327 }
4328
4329 /* Build an indirect-ref expression over the given TREE, which represents a
4330    piece of a va_arg() expansion.  */
4331 tree
4332 build_va_arg_indirect_ref (tree addr)
4333 {
4334   addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
4335
4336   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4337     mf_mark (addr);
4338
4339   return addr;
4340 }
4341
4342 /* Return a dummy expression of type TYPE in order to keep going after an
4343    error.  */
4344
4345 static tree
4346 dummy_object (tree type)
4347 {
4348   tree t = build_int_cst (build_pointer_type (type), 0);
4349   return build2 (MEM_REF, type, t, t);
4350 }
4351
4352 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4353    builtin function, but a very special sort of operator.  */
4354
4355 enum gimplify_status
4356 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4357 {
4358   tree promoted_type, have_va_type;
4359   tree valist = TREE_OPERAND (*expr_p, 0);
4360   tree type = TREE_TYPE (*expr_p);
4361   tree t;
4362   location_t loc = EXPR_LOCATION (*expr_p);
4363
4364   /* Verify that valist is of the proper type.  */
4365   have_va_type = TREE_TYPE (valist);
4366   if (have_va_type == error_mark_node)
4367     return GS_ERROR;
4368   have_va_type = targetm.canonical_va_list_type (have_va_type);
4369
4370   if (have_va_type == NULL_TREE)
4371     {
4372       error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4373       return GS_ERROR;
4374     }
4375
4376   /* Generate a diagnostic for requesting data of a type that cannot
4377      be passed through `...' due to type promotion at the call site.  */
4378   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4379            != type)
4380     {
4381       static bool gave_help;
4382       bool warned;
4383
4384       /* Unfortunately, this is merely undefined, rather than a constraint
4385          violation, so we cannot make this an error.  If this call is never
4386          executed, the program is still strictly conforming.  */
4387       warned = warning_at (loc, 0,
4388                            "%qT is promoted to %qT when passed through %<...%>",
4389                            type, promoted_type);
4390       if (!gave_help && warned)
4391         {
4392           gave_help = true;
4393           inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4394                   promoted_type, type);
4395         }
4396
4397       /* We can, however, treat "undefined" any way we please.
4398          Call abort to encourage the user to fix the program.  */
4399       if (warned)
4400         inform (loc, "if this code is reached, the program will abort");
4401       /* Before the abort, allow the evaluation of the va_list
4402          expression to exit or longjmp.  */
4403       gimplify_and_add (valist, pre_p);
4404       t = build_call_expr_loc (loc,
4405                                builtin_decl_implicit (BUILT_IN_TRAP), 0);
4406       gimplify_and_add (t, pre_p);
4407
4408       /* This is dead code, but go ahead and finish so that the
4409          mode of the result comes out right.  */
4410       *expr_p = dummy_object (type);
4411       return GS_ALL_DONE;
4412     }
4413   else
4414     {
4415       /* Make it easier for the backends by protecting the valist argument
4416          from multiple evaluations.  */
4417       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4418         {
4419           /* For this case, the backends will be expecting a pointer to
4420              TREE_TYPE (abi), but it's possible we've
4421              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4422              So fix it.  */
4423           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4424             {
4425               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4426               valist = fold_convert_loc (loc, p1,
4427                                          build_fold_addr_expr_loc (loc, valist));
4428             }
4429
4430           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4431         }
4432       else
4433         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4434
4435       if (!targetm.gimplify_va_arg_expr)
4436         /* FIXME: Once most targets are converted we should merely
4437            assert this is non-null.  */
4438         return GS_ALL_DONE;
4439
4440       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4441       return GS_OK;
4442     }
4443 }
4444
4445 /* Expand EXP, a call to __builtin_va_end.  */
4446
4447 static rtx
4448 expand_builtin_va_end (tree exp)
4449 {
4450   tree valist = CALL_EXPR_ARG (exp, 0);
4451
4452   /* Evaluate for side effects, if needed.  I hate macros that don't
4453      do that.  */
4454   if (TREE_SIDE_EFFECTS (valist))
4455     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4456
4457   return const0_rtx;
4458 }
4459
4460 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
4461    builtin rather than just as an assignment in stdarg.h because of the
4462    nastiness of array-type va_list types.  */
4463
4464 static rtx
4465 expand_builtin_va_copy (tree exp)
4466 {
4467   tree dst, src, t;
4468   location_t loc = EXPR_LOCATION (exp);
4469
4470   dst = CALL_EXPR_ARG (exp, 0);
4471   src = CALL_EXPR_ARG (exp, 1);
4472
4473   dst = stabilize_va_list_loc (loc, dst, 1);
4474   src = stabilize_va_list_loc (loc, src, 0);
4475
4476   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4477
4478   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4479     {
4480       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4481       TREE_SIDE_EFFECTS (t) = 1;
4482       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4483     }
4484   else
4485     {
4486       rtx dstb, srcb, size;
4487
4488       /* Evaluate to pointers.  */
4489       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4490       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4491       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4492                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
4493
4494       dstb = convert_memory_address (Pmode, dstb);
4495       srcb = convert_memory_address (Pmode, srcb);
4496
4497       /* "Dereference" to BLKmode memories.  */
4498       dstb = gen_rtx_MEM (BLKmode, dstb);
4499       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4500       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4501       srcb = gen_rtx_MEM (BLKmode, srcb);
4502       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4503       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4504
4505       /* Copy.  */
4506       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4507     }
4508
4509   return const0_rtx;
4510 }
4511
4512 /* Expand a call to one of the builtin functions __builtin_frame_address or
4513    __builtin_return_address.  */
4514
4515 static rtx
4516 expand_builtin_frame_address (tree fndecl, tree exp)
4517 {
4518   /* The argument must be a nonnegative integer constant.
4519      It counts the number of frames to scan up the stack.
4520      The value is the return address saved in that frame.  */
4521   if (call_expr_nargs (exp) == 0)
4522     /* Warning about missing arg was already issued.  */
4523     return const0_rtx;
4524   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4525     {
4526       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4527         error ("invalid argument to %<__builtin_frame_address%>");
4528       else
4529         error ("invalid argument to %<__builtin_return_address%>");
4530       return const0_rtx;
4531     }
4532   else
4533     {
4534       rtx tem
4535         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4536                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4537
4538       /* Some ports cannot access arbitrary stack frames.  */
4539       if (tem == NULL)
4540         {
4541           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4542             warning (0, "unsupported argument to %<__builtin_frame_address%>");
4543           else
4544             warning (0, "unsupported argument to %<__builtin_return_address%>");
4545           return const0_rtx;
4546         }
4547
4548       /* For __builtin_frame_address, return what we've got.  */
4549       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4550         return tem;
4551
4552       if (!REG_P (tem)
4553           && ! CONSTANT_P (tem))
4554         tem = copy_to_mode_reg (Pmode, tem);
4555       return tem;
4556     }
4557 }
4558
4559 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if we
4560    failed and the caller should emit a normal call.  CANNOT_ACCUMULATE
4561    is the same as for allocate_dynamic_stack_space.  */
4562
4563 static rtx
4564 expand_builtin_alloca (tree exp, bool cannot_accumulate)
4565 {
4566   rtx op0;
4567   rtx result;
4568   bool valid_arglist;
4569   unsigned int align;
4570   bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
4571                             == BUILT_IN_ALLOCA_WITH_ALIGN);
4572
4573   /* Emit normal call if we use mudflap.  */
4574   if (flag_mudflap)
4575     return NULL_RTX;
4576
4577   valid_arglist
4578     = (alloca_with_align
4579        ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
4580        : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE));
4581
4582   if (!valid_arglist)
4583     return NULL_RTX;
4584
4585   /* Compute the argument.  */
4586   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4587
4588   /* Compute the alignment.  */
4589   align = (alloca_with_align
4590            ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
4591            : BIGGEST_ALIGNMENT);
4592
4593   /* Allocate the desired space.  */
4594   result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate);
4595   result = convert_memory_address (ptr_mode, result);
4596
4597   return result;
4598 }
4599
4600 /* Expand a call to a bswap builtin with argument ARG0.  MODE
4601    is the mode to expand with.  */
4602
4603 static rtx
4604 expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
4605 {
4606   enum machine_mode mode;
4607   tree arg;
4608   rtx op0;
4609
4610   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4611     return NULL_RTX;
4612
4613   arg = CALL_EXPR_ARG (exp, 0);
4614   mode = TYPE_MODE (TREE_TYPE (arg));
4615   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4616
4617   target = expand_unop (mode, bswap_optab, op0, target, 1);
4618
4619   gcc_assert (target);
4620
4621   return convert_to_mode (mode, target, 0);
4622 }
4623
4624 /* Expand a call to a unary builtin in EXP.
4625    Return NULL_RTX if a normal call should be emitted rather than expanding the
4626    function in-line.  If convenient, the result should be placed in TARGET.
4627    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4628
4629 static rtx
4630 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4631                      rtx subtarget, optab op_optab)
4632 {
4633   rtx op0;
4634
4635   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4636     return NULL_RTX;
4637
4638   /* Compute the argument.  */
4639   op0 = expand_expr (CALL_EXPR_ARG (exp, 0),
4640                      (subtarget
4641                       && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))
4642                           == GET_MODE (subtarget))) ? subtarget : NULL_RTX,
4643                      VOIDmode, EXPAND_NORMAL);
4644   /* Compute op, into TARGET if possible.
4645      Set TARGET to wherever the result comes back.  */
4646   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4647                         op_optab, op0, target, op_optab != clrsb_optab);
4648   gcc_assert (target);
4649
4650   return convert_to_mode (target_mode, target, 0);
4651 }
4652
4653 /* Expand a call to __builtin_expect.  We just return our argument
4654    as the builtin_expect semantic should've been already executed by
4655    tree branch prediction pass. */
4656
4657 static rtx
4658 expand_builtin_expect (tree exp, rtx target)
4659 {
4660   tree arg;
4661
4662   if (call_expr_nargs (exp) < 2)
4663     return const0_rtx;
4664   arg = CALL_EXPR_ARG (exp, 0);
4665
4666   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4667   /* When guessing was done, the hints should be already stripped away.  */
4668   gcc_assert (!flag_guess_branch_prob
4669               || optimize == 0 || seen_error ());
4670   return target;
4671 }
4672
4673 /* Expand a call to __builtin_assume_aligned.  We just return our first
4674    argument as the builtin_assume_aligned semantic should've been already
4675    executed by CCP.  */
4676
4677 static rtx
4678 expand_builtin_assume_aligned (tree exp, rtx target)
4679 {
4680   if (call_expr_nargs (exp) < 2)
4681     return const0_rtx;
4682   target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode,
4683                         EXPAND_NORMAL);
4684   gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1))
4685               && (call_expr_nargs (exp) < 3
4686                   || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2))));
4687   return target;
4688 }
4689
4690 void
4691 expand_builtin_trap (void)
4692 {
4693 #ifdef HAVE_trap
4694   if (HAVE_trap)
4695     emit_insn (gen_trap ());
4696   else
4697 #endif
4698     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4699   emit_barrier ();
4700 }
4701
4702 /* Expand a call to __builtin_unreachable.  We do nothing except emit
4703    a barrier saying that control flow will not pass here.
4704
4705    It is the responsibility of the program being compiled to ensure
4706    that control flow does never reach __builtin_unreachable.  */
4707 static void
4708 expand_builtin_unreachable (void)
4709 {
4710   emit_barrier ();
4711 }
4712
4713 /* Expand EXP, a call to fabs, fabsf or fabsl.
4714    Return NULL_RTX if a normal call should be emitted rather than expanding
4715    the function inline.  If convenient, the result should be placed
4716    in TARGET.  SUBTARGET may be used as the target for computing
4717    the operand.  */
4718
4719 static rtx
4720 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4721 {
4722   enum machine_mode mode;
4723   tree arg;
4724   rtx op0;
4725
4726   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4727     return NULL_RTX;
4728
4729   arg = CALL_EXPR_ARG (exp, 0);
4730   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4731   mode = TYPE_MODE (TREE_TYPE (arg));
4732   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4733   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4734 }
4735
4736 /* Expand EXP, a call to copysign, copysignf, or copysignl.
4737    Return NULL is a normal call should be emitted rather than expanding the
4738    function inline.  If convenient, the result should be placed in TARGET.
4739    SUBTARGET may be used as the target for computing the operand.  */
4740
4741 static rtx
4742 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4743 {
4744   rtx op0, op1;
4745   tree arg;
4746
4747   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4748     return NULL_RTX;
4749
4750   arg = CALL_EXPR_ARG (exp, 0);
4751   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4752
4753   arg = CALL_EXPR_ARG (exp, 1);
4754   op1 = expand_normal (arg);
4755
4756   return expand_copysign (op0, op1, target);
4757 }
4758
4759 /* Create a new constant string literal and return a char* pointer to it.
4760    The STRING_CST value is the LEN characters at STR.  */
4761 tree
4762 build_string_literal (int len, const char *str)
4763 {
4764   tree t, elem, index, type;
4765
4766   t = build_string (len, str);
4767   elem = build_type_variant (char_type_node, 1, 0);
4768   index = build_index_type (size_int (len - 1));
4769   type = build_array_type (elem, index);
4770   TREE_TYPE (t) = type;
4771   TREE_CONSTANT (t) = 1;
4772   TREE_READONLY (t) = 1;
4773   TREE_STATIC (t) = 1;
4774
4775   type = build_pointer_type (elem);
4776   t = build1 (ADDR_EXPR, type,
4777               build4 (ARRAY_REF, elem,
4778                       t, integer_zero_node, NULL_TREE, NULL_TREE));
4779   return t;
4780 }
4781
4782 /* Expand a call to __builtin___clear_cache.  */
4783
4784 static rtx
4785 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
4786 {
4787 #ifndef HAVE_clear_cache
4788 #ifdef CLEAR_INSN_CACHE
4789   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4790      does something.  Just do the default expansion to a call to
4791      __clear_cache().  */
4792   return NULL_RTX;
4793 #else
4794   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4795      does nothing.  There is no need to call it.  Do nothing.  */
4796   return const0_rtx;
4797 #endif /* CLEAR_INSN_CACHE */
4798 #else
4799   /* We have a "clear_cache" insn, and it will handle everything.  */
4800   tree begin, end;
4801   rtx begin_rtx, end_rtx;
4802
4803   /* We must not expand to a library call.  If we did, any
4804      fallback library function in libgcc that might contain a call to
4805      __builtin___clear_cache() would recurse infinitely.  */
4806   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4807     {
4808       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
4809       return const0_rtx;
4810     }
4811
4812   if (HAVE_clear_cache)
4813     {
4814       struct expand_operand ops[2];
4815
4816       begin = CALL_EXPR_ARG (exp, 0);
4817       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
4818
4819       end = CALL_EXPR_ARG (exp, 1);
4820       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
4821
4822       create_address_operand (&ops[0], begin_rtx);
4823       create_address_operand (&ops[1], end_rtx);
4824       if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops))
4825         return const0_rtx;
4826     }
4827   return const0_rtx;
4828 #endif /* HAVE_clear_cache */
4829 }
4830
4831 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4832
4833 static rtx
4834 round_trampoline_addr (rtx tramp)
4835 {
4836   rtx temp, addend, mask;
4837
4838   /* If we don't need too much alignment, we'll have been guaranteed
4839      proper alignment by get_trampoline_type.  */
4840   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4841     return tramp;
4842
4843   /* Round address up to desired boundary.  */
4844   temp = gen_reg_rtx (Pmode);
4845   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4846   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4847
4848   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4849                                temp, 0, OPTAB_LIB_WIDEN);
4850   tramp = expand_simple_binop (Pmode, AND, temp, mask,
4851                                temp, 0, OPTAB_LIB_WIDEN);
4852
4853   return tramp;
4854 }
4855
4856 static rtx
4857 expand_builtin_init_trampoline (tree exp, bool onstack)
4858 {
4859   tree t_tramp, t_func, t_chain;
4860   rtx m_tramp, r_tramp, r_chain, tmp;
4861
4862   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4863                          POINTER_TYPE, VOID_TYPE))
4864     return NULL_RTX;
4865
4866   t_tramp = CALL_EXPR_ARG (exp, 0);
4867   t_func = CALL_EXPR_ARG (exp, 1);
4868   t_chain = CALL_EXPR_ARG (exp, 2);
4869
4870   r_tramp = expand_normal (t_tramp);
4871   m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
4872   MEM_NOTRAP_P (m_tramp) = 1;
4873
4874   /* If ONSTACK, the TRAMP argument should be the address of a field
4875      within the local function's FRAME decl.  Either way, let's see if
4876      we can fill in the MEM_ATTRs for this memory.  */
4877   if (TREE_CODE (t_tramp) == ADDR_EXPR)
4878     set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
4879                                      true, 0);
4880
4881   /* Creator of a heap trampoline is responsible for making sure the
4882      address is aligned to at least STACK_BOUNDARY.  Normally malloc
4883      will ensure this anyhow.  */
4884   tmp = round_trampoline_addr (r_tramp);
4885   if (tmp != r_tramp)
4886     {
4887       m_tramp = change_address (m_tramp, BLKmode, tmp);
4888       set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
4889       set_mem_size (m_tramp, TRAMPOLINE_SIZE);
4890     }
4891
4892   /* The FUNC argument should be the address of the nested function.
4893      Extract the actual function decl to pass to the hook.  */
4894   gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
4895   t_func = TREE_OPERAND (t_func, 0);
4896   gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
4897
4898   r_chain = expand_normal (t_chain);
4899
4900   /* Generate insns to initialize the trampoline.  */
4901   targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4902
4903   if (onstack)
4904     {
4905       trampolines_created = 1;
4906
4907       warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines,
4908                   "trampoline generated for nested function %qD", t_func);
4909     }
4910
4911   return const0_rtx;
4912 }
4913
4914 static rtx
4915 expand_builtin_adjust_trampoline (tree exp)
4916 {
4917   rtx tramp;
4918
4919   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4920     return NULL_RTX;
4921
4922   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4923   tramp = round_trampoline_addr (tramp);
4924   if (targetm.calls.trampoline_adjust_address)
4925     tramp = targetm.calls.trampoline_adjust_address (tramp);
4926
4927   return tramp;
4928 }
4929
4930 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
4931    function.  The function first checks whether the back end provides
4932    an insn to implement signbit for the respective mode.  If not, it
4933    checks whether the floating point format of the value is such that
4934    the sign bit can be extracted.  If that is not the case, the
4935    function returns NULL_RTX to indicate that a normal call should be
4936    emitted rather than expanding the function in-line.  EXP is the
4937    expression that is a call to the builtin function; if convenient,
4938    the result should be placed in TARGET.  */
4939 static rtx
4940 expand_builtin_signbit (tree exp, rtx target)
4941 {
4942   const struct real_format *fmt;
4943   enum machine_mode fmode, imode, rmode;
4944   tree arg;
4945   int word, bitpos;
4946   enum insn_code icode;
4947   rtx temp;
4948   location_t loc = EXPR_LOCATION (exp);
4949
4950   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4951     return NULL_RTX;
4952
4953   arg = CALL_EXPR_ARG (exp, 0);
4954   fmode = TYPE_MODE (TREE_TYPE (arg));
4955   rmode = TYPE_MODE (TREE_TYPE (exp));
4956   fmt = REAL_MODE_FORMAT (fmode);
4957
4958   arg = builtin_save_expr (arg);
4959
4960   /* Expand the argument yielding a RTX expression. */
4961   temp = expand_normal (arg);
4962
4963   /* Check if the back end provides an insn that handles signbit for the
4964      argument's mode. */
4965   icode = optab_handler (signbit_optab, fmode);
4966   if (icode != CODE_FOR_nothing)
4967     {
4968       rtx last = get_last_insn ();
4969       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
4970       if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
4971         return target;
4972       delete_insns_since (last);
4973     }
4974
4975   /* For floating point formats without a sign bit, implement signbit
4976      as "ARG < 0.0".  */
4977   bitpos = fmt->signbit_ro;
4978   if (bitpos < 0)
4979   {
4980     /* But we can't do this if the format supports signed zero.  */
4981     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4982       return NULL_RTX;
4983
4984     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
4985                        build_real (TREE_TYPE (arg), dconst0));
4986     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4987   }
4988
4989   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4990     {
4991       imode = int_mode_for_mode (fmode);
4992       if (imode == BLKmode)
4993         return NULL_RTX;
4994       temp = gen_lowpart (imode, temp);
4995     }
4996   else
4997     {
4998       imode = word_mode;
4999       /* Handle targets with different FP word orders.  */
5000       if (FLOAT_WORDS_BIG_ENDIAN)
5001         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5002       else
5003         word = bitpos / BITS_PER_WORD;
5004       temp = operand_subword_force (temp, word, fmode);
5005       bitpos = bitpos % BITS_PER_WORD;
5006     }
5007
5008   /* Force the intermediate word_mode (or narrower) result into a
5009      register.  This avoids attempting to create paradoxical SUBREGs
5010      of floating point modes below.  */
5011   temp = force_reg (imode, temp);
5012
5013   /* If the bitpos is within the "result mode" lowpart, the operation
5014      can be implement with a single bitwise AND.  Otherwise, we need
5015      a right shift and an AND.  */
5016
5017   if (bitpos < GET_MODE_BITSIZE (rmode))
5018     {
5019       double_int mask = double_int_setbit (double_int_zero, bitpos);
5020
5021       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5022         temp = gen_lowpart (rmode, temp);
5023       temp = expand_binop (rmode, and_optab, temp,
5024                            immed_double_int_const (mask, rmode),
5025                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5026     }
5027   else
5028     {
5029       /* Perform a logical right shift to place the signbit in the least
5030          significant bit, then truncate the result to the desired mode
5031          and mask just this bit.  */
5032       temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1);
5033       temp = gen_lowpart (rmode, temp);
5034       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5035                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5036     }
5037
5038   return temp;
5039 }
5040
5041 /* Expand fork or exec calls.  TARGET is the desired target of the
5042    call.  EXP is the call. FN is the
5043    identificator of the actual function.  IGNORE is nonzero if the
5044    value is to be ignored.  */
5045
5046 static rtx
5047 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5048 {
5049   tree id, decl;
5050   tree call;
5051
5052   /* If we are not profiling, just call the function.  */
5053   if (!profile_arc_flag)
5054     return NULL_RTX;
5055
5056   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5057      compiler, so the code does not diverge, and the wrapper may run the
5058      code necessary for keeping the profiling sane.  */
5059
5060   switch (DECL_FUNCTION_CODE (fn))
5061     {
5062     case BUILT_IN_FORK:
5063       id = get_identifier ("__gcov_fork");
5064       break;
5065
5066     case BUILT_IN_EXECL:
5067       id = get_identifier ("__gcov_execl");
5068       break;
5069
5070     case BUILT_IN_EXECV:
5071       id = get_identifier ("__gcov_execv");
5072       break;
5073
5074     case BUILT_IN_EXECLP:
5075       id = get_identifier ("__gcov_execlp");
5076       break;
5077
5078     case BUILT_IN_EXECLE:
5079       id = get_identifier ("__gcov_execle");
5080       break;
5081
5082     case BUILT_IN_EXECVP:
5083       id = get_identifier ("__gcov_execvp");
5084       break;
5085
5086     case BUILT_IN_EXECVE:
5087       id = get_identifier ("__gcov_execve");
5088       break;
5089
5090     default:
5091       gcc_unreachable ();
5092     }
5093
5094   decl = build_decl (DECL_SOURCE_LOCATION (fn),
5095                      FUNCTION_DECL, id, TREE_TYPE (fn));
5096   DECL_EXTERNAL (decl) = 1;
5097   TREE_PUBLIC (decl) = 1;
5098   DECL_ARTIFICIAL (decl) = 1;
5099   TREE_NOTHROW (decl) = 1;
5100   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5101   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5102   call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5103   return expand_call (call, target, ignore);
5104  }
5105
5106
5107 \f
5108 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5109    the pointer in these functions is void*, the tree optimizers may remove
5110    casts.  The mode computed in expand_builtin isn't reliable either, due
5111    to __sync_bool_compare_and_swap.
5112
5113    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5114    group of builtins.  This gives us log2 of the mode size.  */
5115
5116 static inline enum machine_mode
5117 get_builtin_sync_mode (int fcode_diff)
5118 {
5119   /* The size is not negotiable, so ask not to get BLKmode in return
5120      if the target indicates that a smaller size would be better.  */
5121   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5122 }
5123
5124 /* Expand the memory expression LOC and return the appropriate memory operand
5125    for the builtin_sync operations.  */
5126
5127 static rtx
5128 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5129 {
5130   rtx addr, mem;
5131
5132   addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5133   addr = convert_memory_address (Pmode, addr);
5134
5135   /* Note that we explicitly do not want any alias information for this
5136      memory, so that we kill all other live memories.  Otherwise we don't
5137      satisfy the full barrier semantics of the intrinsic.  */
5138   mem = validize_mem (gen_rtx_MEM (mode, addr));
5139
5140   /* The alignment needs to be at least according to that of the mode.  */
5141   set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
5142                            get_pointer_alignment (loc)));
5143   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5144   MEM_VOLATILE_P (mem) = 1;
5145
5146   return mem;
5147 }
5148
5149 /* Make sure an argument is in the right mode.
5150    EXP is the tree argument. 
5151    MODE is the mode it should be in.  */
5152
5153 static rtx
5154 expand_expr_force_mode (tree exp, enum machine_mode mode)
5155 {
5156   rtx val;
5157   enum machine_mode old_mode;
5158
5159   val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
5160   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5161      of CONST_INTs, where we know the old_mode only from the call argument.  */
5162
5163   old_mode = GET_MODE (val);
5164   if (old_mode == VOIDmode)
5165     old_mode = TYPE_MODE (TREE_TYPE (exp));
5166   val = convert_modes (mode, old_mode, val, 1);
5167   return val;
5168 }
5169
5170
5171 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5172    EXP is the CALL_EXPR.  CODE is the rtx code
5173    that corresponds to the arithmetic or logical operation from the name;
5174    an exception here is that NOT actually means NAND.  TARGET is an optional
5175    place for us to store the results; AFTER is true if this is the
5176    fetch_and_xxx form.  */
5177
5178 static rtx
5179 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5180                                enum rtx_code code, bool after,
5181                                rtx target)
5182 {
5183   rtx val, mem;
5184   location_t loc = EXPR_LOCATION (exp);
5185
5186   if (code == NOT && warn_sync_nand)
5187     {
5188       tree fndecl = get_callee_fndecl (exp);
5189       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5190
5191       static bool warned_f_a_n, warned_n_a_f;
5192
5193       switch (fcode)
5194         {
5195         case BUILT_IN_SYNC_FETCH_AND_NAND_1:
5196         case BUILT_IN_SYNC_FETCH_AND_NAND_2:
5197         case BUILT_IN_SYNC_FETCH_AND_NAND_4:
5198         case BUILT_IN_SYNC_FETCH_AND_NAND_8:
5199         case BUILT_IN_SYNC_FETCH_AND_NAND_16:
5200           if (warned_f_a_n)
5201             break;
5202
5203           fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N);
5204           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5205           warned_f_a_n = true;
5206           break;
5207
5208         case BUILT_IN_SYNC_NAND_AND_FETCH_1:
5209         case BUILT_IN_SYNC_NAND_AND_FETCH_2:
5210         case BUILT_IN_SYNC_NAND_AND_FETCH_4:
5211         case BUILT_IN_SYNC_NAND_AND_FETCH_8:
5212         case BUILT_IN_SYNC_NAND_AND_FETCH_16:
5213           if (warned_n_a_f)
5214             break;
5215
5216          fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N);
5217           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5218           warned_n_a_f = true;
5219           break;
5220
5221         default:
5222           gcc_unreachable ();
5223         }
5224     }
5225
5226   /* Expand the operands.  */
5227   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5228   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5229
5230   return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SEQ_CST,
5231                                  after);
5232 }
5233
5234 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5235    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5236    true if this is the boolean form.  TARGET is a place for us to store the
5237    results; this is NOT optional if IS_BOOL is true.  */
5238
5239 static rtx
5240 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5241                                  bool is_bool, rtx target)
5242 {
5243   rtx old_val, new_val, mem;
5244   rtx *pbool, *poval;
5245
5246   /* Expand the operands.  */
5247   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5248   old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5249   new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5250
5251   pbool = poval = NULL;
5252   if (target != const0_rtx)
5253     {
5254       if (is_bool)
5255         pbool = &target;
5256       else
5257         poval = &target;
5258     }
5259   if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val,
5260                                        false, MEMMODEL_SEQ_CST,
5261                                        MEMMODEL_SEQ_CST))
5262     return NULL_RTX;
5263
5264   return target;
5265 }
5266
5267 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5268    general form is actually an atomic exchange, and some targets only
5269    support a reduced form with the second argument being a constant 1.
5270    EXP is the CALL_EXPR; TARGET is an optional place for us to store
5271    the results.  */
5272
5273 static rtx
5274 expand_builtin_sync_lock_test_and_set (enum machine_mode mode, tree exp,
5275                                        rtx target)
5276 {
5277   rtx val, mem;
5278
5279   /* Expand the operands.  */
5280   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5281   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5282
5283   return expand_sync_lock_test_and_set (target, mem, val);
5284 }
5285
5286 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
5287
5288 static void
5289 expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
5290 {
5291   rtx mem;
5292
5293   /* Expand the operands.  */
5294   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5295
5296   expand_atomic_store (mem, const0_rtx, MEMMODEL_RELEASE, true);
5297 }
5298
5299 /* Given an integer representing an ``enum memmodel'', verify its
5300    correctness and return the memory model enum.  */
5301
5302 static enum memmodel
5303 get_memmodel (tree exp)
5304 {
5305   rtx op;
5306
5307   /* If the parameter is not a constant, it's a run time value so we'll just
5308      convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking.  */
5309   if (TREE_CODE (exp) != INTEGER_CST)
5310     return MEMMODEL_SEQ_CST;
5311
5312   op = expand_normal (exp);
5313   if (INTVAL (op) < 0 || INTVAL (op) >= MEMMODEL_LAST)
5314     {
5315       warning (OPT_Winvalid_memory_model,
5316                "invalid memory model argument to builtin");
5317       return MEMMODEL_SEQ_CST;
5318     }
5319   return (enum memmodel) INTVAL (op);
5320 }
5321
5322 /* Expand the __atomic_exchange intrinsic:
5323         TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel)
5324    EXP is the CALL_EXPR.
5325    TARGET is an optional place for us to store the results.  */
5326
5327 static rtx
5328 expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
5329 {
5330   rtx val, mem;
5331   enum memmodel model;
5332
5333   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5334   if (model == MEMMODEL_CONSUME)
5335     {
5336       error ("invalid memory model for %<__atomic_exchange%>");
5337       return NULL_RTX;
5338     }
5339
5340   if (!flag_inline_atomics)
5341     return NULL_RTX;
5342
5343   /* Expand the operands.  */
5344   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5345   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5346
5347   return expand_atomic_exchange (target, mem, val, model);
5348 }
5349
5350 /* Expand the __atomic_compare_exchange intrinsic:
5351         bool __atomic_compare_exchange (TYPE *object, TYPE *expect, 
5352                                         TYPE desired, BOOL weak, 
5353                                         enum memmodel success,
5354                                         enum memmodel failure)
5355    EXP is the CALL_EXPR.
5356    TARGET is an optional place for us to store the results.  */
5357
5358 static rtx
5359 expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, 
5360                                         rtx target)
5361 {
5362   rtx expect, desired, mem, oldval;
5363   enum memmodel success, failure;
5364   tree weak;
5365   bool is_weak;
5366
5367   success = get_memmodel (CALL_EXPR_ARG (exp, 4));
5368   failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
5369
5370   if (failure == MEMMODEL_RELEASE || failure == MEMMODEL_ACQ_REL)
5371     {
5372       error ("invalid failure memory model for %<__atomic_compare_exchange%>");
5373       return NULL_RTX;
5374     }
5375
5376   if (failure > success)
5377     {
5378       error ("failure memory model cannot be stronger than success "
5379              "memory model for %<__atomic_compare_exchange%>");
5380       return NULL_RTX;
5381     }
5382   
5383   if (!flag_inline_atomics)
5384     return NULL_RTX;
5385
5386   /* Expand the operands.  */
5387   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5388
5389   expect = expand_normal (CALL_EXPR_ARG (exp, 1));
5390   expect = convert_memory_address (Pmode, expect);
5391   desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5392
5393   weak = CALL_EXPR_ARG (exp, 3);
5394   is_weak = false;
5395   if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
5396     is_weak = true;
5397
5398   oldval = copy_to_reg (gen_rtx_MEM (mode, expect));
5399
5400   if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
5401                                        &oldval, mem, oldval, desired,
5402                                        is_weak, success, failure))
5403     return NULL_RTX;
5404
5405   emit_move_insn (gen_rtx_MEM (mode, expect), oldval);
5406   return target;
5407 }
5408
5409 /* Expand the __atomic_load intrinsic:
5410         TYPE __atomic_load (TYPE *object, enum memmodel)
5411    EXP is the CALL_EXPR.
5412    TARGET is an optional place for us to store the results.  */
5413
5414 static rtx
5415 expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
5416 {
5417   rtx mem;
5418   enum memmodel model;
5419
5420   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5421   if (model == MEMMODEL_RELEASE
5422       || model == MEMMODEL_ACQ_REL)
5423     {
5424       error ("invalid memory model for %<__atomic_load%>");
5425       return NULL_RTX;
5426     }
5427
5428   if (!flag_inline_atomics)
5429     return NULL_RTX;
5430
5431   /* Expand the operand.  */
5432   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5433
5434   return expand_atomic_load (target, mem, model);
5435 }
5436
5437
5438 /* Expand the __atomic_store intrinsic:
5439         void __atomic_store (TYPE *object, TYPE desired, enum memmodel)
5440    EXP is the CALL_EXPR.
5441    TARGET is an optional place for us to store the results.  */
5442
5443 static rtx
5444 expand_builtin_atomic_store (enum machine_mode mode, tree exp)
5445 {
5446   rtx mem, val;
5447   enum memmodel model;
5448
5449   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5450   if (model != MEMMODEL_RELAXED
5451       && model != MEMMODEL_SEQ_CST
5452       && model != MEMMODEL_RELEASE)
5453     {
5454       error ("invalid memory model for %<__atomic_store%>");
5455       return NULL_RTX;
5456     }
5457
5458   if (!flag_inline_atomics)
5459     return NULL_RTX;
5460
5461   /* Expand the operands.  */
5462   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5463   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5464
5465   return expand_atomic_store (mem, val, model, false);
5466 }
5467
5468 /* Expand the __atomic_fetch_XXX intrinsic:
5469         TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
5470    EXP is the CALL_EXPR.
5471    TARGET is an optional place for us to store the results.
5472    CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR.
5473    FETCH_AFTER is true if returning the result of the operation.
5474    FETCH_AFTER is false if returning the value before the operation.
5475    IGNORE is true if the result is not used.
5476    EXT_CALL is the correct builtin for an external call if this cannot be
5477    resolved to an instruction sequence.  */
5478
5479 static rtx
5480 expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
5481                                 enum rtx_code code, bool fetch_after,
5482                                 bool ignore, enum built_in_function ext_call)
5483 {
5484   rtx val, mem, ret;
5485   enum memmodel model;
5486   tree fndecl;
5487   tree addr;
5488
5489   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5490
5491   /* Expand the operands.  */
5492   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5493   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5494
5495   /* Only try generating instructions if inlining is turned on.  */
5496   if (flag_inline_atomics)
5497     {
5498       ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after);
5499       if (ret)
5500         return ret;
5501     }
5502
5503   /* Return if a different routine isn't needed for the library call.  */
5504   if (ext_call == BUILT_IN_NONE)
5505     return NULL_RTX;
5506
5507   /* Change the call to the specified function.  */
5508   fndecl = get_callee_fndecl (exp);
5509   addr = CALL_EXPR_FN (exp);
5510   STRIP_NOPS (addr);
5511
5512   gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
5513   TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
5514
5515   /* Expand the call here so we can emit trailing code.  */
5516   ret = expand_call (exp, target, ignore);
5517
5518   /* Replace the original function just in case it matters.  */
5519   TREE_OPERAND (addr, 0) = fndecl;
5520
5521   /* Then issue the arithmetic correction to return the right result.  */
5522   if (!ignore)
5523     {
5524       if (code == NOT)
5525         {
5526           ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
5527                                      OPTAB_LIB_WIDEN);
5528           ret = expand_simple_unop (mode, NOT, ret, target, true);
5529         }
5530       else
5531         ret = expand_simple_binop (mode, code, ret, val, target, true,
5532                                    OPTAB_LIB_WIDEN);
5533     }
5534   return ret;
5535 }
5536
5537
5538 #ifndef HAVE_atomic_clear
5539 # define HAVE_atomic_clear 0
5540 # define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX)
5541 #endif
5542
5543 /* Expand an atomic clear operation.
5544         void _atomic_clear (BOOL *obj, enum memmodel)
5545    EXP is the call expression.  */
5546
5547 static rtx
5548 expand_builtin_atomic_clear (tree exp) 
5549 {
5550   enum machine_mode mode;
5551   rtx mem, ret;
5552   enum memmodel model;
5553
5554   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5555   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5556   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5557
5558   if (model == MEMMODEL_ACQUIRE || model == MEMMODEL_ACQ_REL)
5559     {
5560       error ("invalid memory model for %<__atomic_store%>");
5561       return const0_rtx;
5562     }
5563
5564   if (HAVE_atomic_clear)
5565     {
5566       emit_insn (gen_atomic_clear (mem, model));
5567       return const0_rtx;
5568     }
5569
5570   /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release.
5571      Failing that, a store is issued by __atomic_store.  The only way this can
5572      fail is if the bool type is larger than a word size.  Unlikely, but
5573      handle it anyway for completeness.  Assume a single threaded model since
5574      there is no atomic support in this case, and no barriers are required.  */
5575   ret = expand_atomic_store (mem, const0_rtx, model, true);
5576   if (!ret)
5577     emit_move_insn (mem, const0_rtx);
5578   return const0_rtx;
5579 }
5580
5581 /* Expand an atomic test_and_set operation.
5582         bool _atomic_test_and_set (BOOL *obj, enum memmodel)
5583    EXP is the call expression.  */
5584
5585 static rtx
5586 expand_builtin_atomic_test_and_set (tree exp, rtx target)
5587 {
5588   rtx mem;
5589   enum memmodel model;
5590   enum machine_mode mode;
5591
5592   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5593   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5594   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5595
5596   return expand_atomic_test_and_set (target, mem, model);
5597 }
5598
5599
5600 /* Return true if (optional) argument ARG1 of size ARG0 is always lock free on
5601    this architecture.  If ARG1 is NULL, use typical alignment for size ARG0.  */
5602
5603 static tree
5604 fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
5605 {
5606   int size;
5607   enum machine_mode mode;
5608   unsigned int mode_align, type_align;
5609
5610   if (TREE_CODE (arg0) != INTEGER_CST)
5611     return NULL_TREE;
5612
5613   size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT;
5614   mode = mode_for_size (size, MODE_INT, 0);
5615   mode_align = GET_MODE_ALIGNMENT (mode);
5616
5617   if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
5618     type_align = mode_align;
5619   else
5620     {
5621       tree ttype = TREE_TYPE (arg1);
5622
5623       /* This function is usually invoked and folded immediately by the front
5624          end before anything else has a chance to look at it.  The pointer
5625          parameter at this point is usually cast to a void *, so check for that
5626          and look past the cast.  */
5627       if (TREE_CODE (arg1) == NOP_EXPR && POINTER_TYPE_P (ttype)
5628           && VOID_TYPE_P (TREE_TYPE (ttype)))
5629         arg1 = TREE_OPERAND (arg1, 0);
5630
5631       ttype = TREE_TYPE (arg1);
5632       gcc_assert (POINTER_TYPE_P (ttype));
5633
5634       /* Get the underlying type of the object.  */
5635       ttype = TREE_TYPE (ttype);
5636       type_align = TYPE_ALIGN (ttype);
5637     }
5638
5639   /* If the object has smaller alignment, the the lock free routines cannot
5640      be used.  */
5641   if (type_align < mode_align)
5642     return integer_zero_node;
5643
5644   /* Check if a compare_and_swap pattern exists for the mode which represents
5645      the required size.  The pattern is not allowed to fail, so the existence
5646      of the pattern indicates support is present.  */
5647   if (can_compare_and_swap_p (mode, true))
5648     return integer_one_node;
5649   else
5650     return integer_zero_node;
5651 }
5652
5653 /* Return true if the parameters to call EXP represent an object which will
5654    always generate lock free instructions.  The first argument represents the
5655    size of the object, and the second parameter is a pointer to the object 
5656    itself.  If NULL is passed for the object, then the result is based on 
5657    typical alignment for an object of the specified size.  Otherwise return 
5658    false.  */
5659
5660 static rtx
5661 expand_builtin_atomic_always_lock_free (tree exp)
5662 {
5663   tree size;
5664   tree arg0 = CALL_EXPR_ARG (exp, 0);
5665   tree arg1 = CALL_EXPR_ARG (exp, 1);
5666
5667   if (TREE_CODE (arg0) != INTEGER_CST)
5668     {
5669       error ("non-constant argument 1 to __atomic_always_lock_free");
5670       return const0_rtx;
5671     }
5672
5673   size = fold_builtin_atomic_always_lock_free (arg0, arg1);
5674   if (size == integer_one_node)
5675     return const1_rtx;
5676   return const0_rtx;
5677 }
5678
5679 /* Return a one or zero if it can be determined that object ARG1 of size ARG 
5680    is lock free on this architecture.  */
5681
5682 static tree
5683 fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
5684 {
5685   if (!flag_inline_atomics)
5686     return NULL_TREE;
5687   
5688   /* If it isn't always lock free, don't generate a result.  */
5689   if (fold_builtin_atomic_always_lock_free (arg0, arg1) == integer_one_node)
5690     return integer_one_node;
5691
5692   return NULL_TREE;
5693 }
5694
5695 /* Return true if the parameters to call EXP represent an object which will
5696    always generate lock free instructions.  The first argument represents the
5697    size of the object, and the second parameter is a pointer to the object 
5698    itself.  If NULL is passed for the object, then the result is based on 
5699    typical alignment for an object of the specified size.  Otherwise return 
5700    NULL*/
5701
5702 static rtx
5703 expand_builtin_atomic_is_lock_free (tree exp)
5704 {
5705   tree size;
5706   tree arg0 = CALL_EXPR_ARG (exp, 0);
5707   tree arg1 = CALL_EXPR_ARG (exp, 1);
5708
5709   if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
5710     {
5711       error ("non-integer argument 1 to __atomic_is_lock_free");
5712       return NULL_RTX;
5713     }
5714
5715   if (!flag_inline_atomics)
5716     return NULL_RTX; 
5717
5718   /* If the value is known at compile time, return the RTX for it.  */
5719   size = fold_builtin_atomic_is_lock_free (arg0, arg1);
5720   if (size == integer_one_node)
5721     return const1_rtx;
5722
5723   return NULL_RTX;
5724 }
5725
5726 /* Expand the __atomic_thread_fence intrinsic:
5727         void __atomic_thread_fence (enum memmodel)
5728    EXP is the CALL_EXPR.  */
5729
5730 static void
5731 expand_builtin_atomic_thread_fence (tree exp)
5732 {
5733   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5734   expand_mem_thread_fence (model);
5735 }
5736
5737 /* Expand the __atomic_signal_fence intrinsic:
5738         void __atomic_signal_fence (enum memmodel)
5739    EXP is the CALL_EXPR.  */
5740
5741 static void
5742 expand_builtin_atomic_signal_fence (tree exp)
5743 {
5744   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5745   expand_mem_signal_fence (model);
5746 }
5747
5748 /* Expand the __sync_synchronize intrinsic.  */
5749
5750 static void
5751 expand_builtin_sync_synchronize (void)
5752 {
5753   expand_mem_thread_fence (MEMMODEL_SEQ_CST);
5754 }
5755
5756 \f
5757 /* Expand an expression EXP that calls a built-in function,
5758    with result going to TARGET if that's convenient
5759    (and in mode MODE if that's convenient).
5760    SUBTARGET may be used as the target for computing one of EXP's operands.
5761    IGNORE is nonzero if the value is to be ignored.  */
5762
5763 rtx
5764 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5765                 int ignore)
5766 {
5767   tree fndecl = get_callee_fndecl (exp);
5768   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5769   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5770   int flags;
5771
5772   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5773     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5774
5775   /* When not optimizing, generate calls to library functions for a certain
5776      set of builtins.  */
5777   if (!optimize
5778       && !called_as_built_in (fndecl)
5779       && fcode != BUILT_IN_ALLOCA
5780       && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
5781       && fcode != BUILT_IN_FREE)
5782     return expand_call (exp, target, ignore);
5783
5784   /* The built-in function expanders test for target == const0_rtx
5785      to determine whether the function's result will be ignored.  */
5786   if (ignore)
5787     target = const0_rtx;
5788
5789   /* If the result of a pure or const built-in function is ignored, and
5790      none of its arguments are volatile, we can avoid expanding the
5791      built-in call and just evaluate the arguments for side-effects.  */
5792   if (target == const0_rtx
5793       && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
5794       && !(flags & ECF_LOOPING_CONST_OR_PURE))
5795     {
5796       bool volatilep = false;
5797       tree arg;
5798       call_expr_arg_iterator iter;
5799
5800       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5801         if (TREE_THIS_VOLATILE (arg))
5802           {
5803             volatilep = true;
5804             break;
5805           }
5806
5807       if (! volatilep)
5808         {
5809           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5810             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5811           return const0_rtx;
5812         }
5813     }
5814
5815   switch (fcode)
5816     {
5817     CASE_FLT_FN (BUILT_IN_FABS):
5818       target = expand_builtin_fabs (exp, target, subtarget);
5819       if (target)
5820         return target;
5821       break;
5822
5823     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5824       target = expand_builtin_copysign (exp, target, subtarget);
5825       if (target)
5826         return target;
5827       break;
5828
5829       /* Just do a normal library call if we were unable to fold
5830          the values.  */
5831     CASE_FLT_FN (BUILT_IN_CABS):
5832       break;
5833
5834     CASE_FLT_FN (BUILT_IN_EXP):
5835     CASE_FLT_FN (BUILT_IN_EXP10):
5836     CASE_FLT_FN (BUILT_IN_POW10):
5837     CASE_FLT_FN (BUILT_IN_EXP2):
5838     CASE_FLT_FN (BUILT_IN_EXPM1):
5839     CASE_FLT_FN (BUILT_IN_LOGB):
5840     CASE_FLT_FN (BUILT_IN_LOG):
5841     CASE_FLT_FN (BUILT_IN_LOG10):
5842     CASE_FLT_FN (BUILT_IN_LOG2):
5843     CASE_FLT_FN (BUILT_IN_LOG1P):
5844     CASE_FLT_FN (BUILT_IN_TAN):
5845     CASE_FLT_FN (BUILT_IN_ASIN):
5846     CASE_FLT_FN (BUILT_IN_ACOS):
5847     CASE_FLT_FN (BUILT_IN_ATAN):
5848     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5849       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5850          because of possible accuracy problems.  */
5851       if (! flag_unsafe_math_optimizations)
5852         break;
5853     CASE_FLT_FN (BUILT_IN_SQRT):
5854     CASE_FLT_FN (BUILT_IN_FLOOR):
5855     CASE_FLT_FN (BUILT_IN_CEIL):
5856     CASE_FLT_FN (BUILT_IN_TRUNC):
5857     CASE_FLT_FN (BUILT_IN_ROUND):
5858     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5859     CASE_FLT_FN (BUILT_IN_RINT):
5860       target = expand_builtin_mathfn (exp, target, subtarget);
5861       if (target)
5862         return target;
5863       break;
5864
5865     CASE_FLT_FN (BUILT_IN_FMA):
5866       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
5867       if (target)
5868         return target;
5869       break;
5870
5871     CASE_FLT_FN (BUILT_IN_ILOGB):
5872       if (! flag_unsafe_math_optimizations)
5873         break;
5874     CASE_FLT_FN (BUILT_IN_ISINF):
5875     CASE_FLT_FN (BUILT_IN_FINITE):
5876     case BUILT_IN_ISFINITE:
5877     case BUILT_IN_ISNORMAL:
5878       target = expand_builtin_interclass_mathfn (exp, target);
5879       if (target)
5880         return target;
5881       break;
5882
5883     CASE_FLT_FN (BUILT_IN_ICEIL):
5884     CASE_FLT_FN (BUILT_IN_LCEIL):
5885     CASE_FLT_FN (BUILT_IN_LLCEIL):
5886     CASE_FLT_FN (BUILT_IN_LFLOOR):
5887     CASE_FLT_FN (BUILT_IN_IFLOOR):
5888     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5889       target = expand_builtin_int_roundingfn (exp, target);
5890       if (target)
5891         return target;
5892       break;
5893
5894     CASE_FLT_FN (BUILT_IN_IRINT):
5895     CASE_FLT_FN (BUILT_IN_LRINT):
5896     CASE_FLT_FN (BUILT_IN_LLRINT):
5897     CASE_FLT_FN (BUILT_IN_IROUND):
5898     CASE_FLT_FN (BUILT_IN_LROUND):
5899     CASE_FLT_FN (BUILT_IN_LLROUND):
5900       target = expand_builtin_int_roundingfn_2 (exp, target);
5901       if (target)
5902         return target;
5903       break;
5904
5905     CASE_FLT_FN (BUILT_IN_POWI):
5906       target = expand_builtin_powi (exp, target);
5907       if (target)
5908         return target;
5909       break;
5910
5911     CASE_FLT_FN (BUILT_IN_ATAN2):
5912     CASE_FLT_FN (BUILT_IN_LDEXP):
5913     CASE_FLT_FN (BUILT_IN_SCALB):
5914     CASE_FLT_FN (BUILT_IN_SCALBN):
5915     CASE_FLT_FN (BUILT_IN_SCALBLN):
5916       if (! flag_unsafe_math_optimizations)
5917         break;
5918
5919     CASE_FLT_FN (BUILT_IN_FMOD):
5920     CASE_FLT_FN (BUILT_IN_REMAINDER):
5921     CASE_FLT_FN (BUILT_IN_DREM):
5922     CASE_FLT_FN (BUILT_IN_POW):
5923       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5924       if (target)
5925         return target;
5926       break;
5927
5928     CASE_FLT_FN (BUILT_IN_CEXPI):
5929       target = expand_builtin_cexpi (exp, target);
5930       gcc_assert (target);
5931       return target;
5932
5933     CASE_FLT_FN (BUILT_IN_SIN):
5934     CASE_FLT_FN (BUILT_IN_COS):
5935       if (! flag_unsafe_math_optimizations)
5936         break;
5937       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5938       if (target)
5939         return target;
5940       break;
5941
5942     CASE_FLT_FN (BUILT_IN_SINCOS):
5943       if (! flag_unsafe_math_optimizations)
5944         break;
5945       target = expand_builtin_sincos (exp);
5946       if (target)
5947         return target;
5948       break;
5949
5950     case BUILT_IN_APPLY_ARGS:
5951       return expand_builtin_apply_args ();
5952
5953       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5954          FUNCTION with a copy of the parameters described by
5955          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5956          allocated on the stack into which is stored all the registers
5957          that might possibly be used for returning the result of a
5958          function.  ARGUMENTS is the value returned by
5959          __builtin_apply_args.  ARGSIZE is the number of bytes of
5960          arguments that must be copied.  ??? How should this value be
5961          computed?  We'll also need a safe worst case value for varargs
5962          functions.  */
5963     case BUILT_IN_APPLY:
5964       if (!validate_arglist (exp, POINTER_TYPE,
5965                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5966           && !validate_arglist (exp, REFERENCE_TYPE,
5967                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5968         return const0_rtx;
5969       else
5970         {
5971           rtx ops[3];
5972
5973           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
5974           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
5975           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
5976
5977           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5978         }
5979
5980       /* __builtin_return (RESULT) causes the function to return the
5981          value described by RESULT.  RESULT is address of the block of
5982          memory returned by __builtin_apply.  */
5983     case BUILT_IN_RETURN:
5984       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5985         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
5986       return const0_rtx;
5987
5988     case BUILT_IN_SAVEREGS:
5989       return expand_builtin_saveregs ();
5990
5991     case BUILT_IN_VA_ARG_PACK:
5992       /* All valid uses of __builtin_va_arg_pack () are removed during
5993          inlining.  */
5994       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
5995       return const0_rtx;
5996
5997     case BUILT_IN_VA_ARG_PACK_LEN:
5998       /* All valid uses of __builtin_va_arg_pack_len () are removed during
5999          inlining.  */
6000       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6001       return const0_rtx;
6002
6003       /* Return the address of the first anonymous stack arg.  */
6004     case BUILT_IN_NEXT_ARG:
6005       if (fold_builtin_next_arg (exp, false))
6006         return const0_rtx;
6007       return expand_builtin_next_arg ();
6008
6009     case BUILT_IN_CLEAR_CACHE:
6010       target = expand_builtin___clear_cache (exp);
6011       if (target)
6012         return target;
6013       break;
6014
6015     case BUILT_IN_CLASSIFY_TYPE:
6016       return expand_builtin_classify_type (exp);
6017
6018     case BUILT_IN_CONSTANT_P:
6019       return const0_rtx;
6020
6021     case BUILT_IN_FRAME_ADDRESS:
6022     case BUILT_IN_RETURN_ADDRESS:
6023       return expand_builtin_frame_address (fndecl, exp);
6024
6025     /* Returns the address of the area where the structure is returned.
6026        0 otherwise.  */
6027     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6028       if (call_expr_nargs (exp) != 0
6029           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6030           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6031         return const0_rtx;
6032       else
6033         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6034
6035     case BUILT_IN_ALLOCA:
6036     case BUILT_IN_ALLOCA_WITH_ALIGN:
6037       /* If the allocation stems from the declaration of a variable-sized
6038          object, it cannot accumulate.  */
6039       target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp));
6040       if (target)
6041         return target;
6042       break;
6043
6044     case BUILT_IN_STACK_SAVE:
6045       return expand_stack_save ();
6046
6047     case BUILT_IN_STACK_RESTORE:
6048       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6049       return const0_rtx;
6050
6051     case BUILT_IN_BSWAP32:
6052     case BUILT_IN_BSWAP64:
6053       target = expand_builtin_bswap (exp, target, subtarget);
6054
6055       if (target)
6056         return target;
6057       break;
6058
6059     CASE_INT_FN (BUILT_IN_FFS):
6060     case BUILT_IN_FFSIMAX:
6061       target = expand_builtin_unop (target_mode, exp, target,
6062                                     subtarget, ffs_optab);
6063       if (target)
6064         return target;
6065       break;
6066
6067     CASE_INT_FN (BUILT_IN_CLZ):
6068     case BUILT_IN_CLZIMAX:
6069       target = expand_builtin_unop (target_mode, exp, target,
6070                                     subtarget, clz_optab);
6071       if (target)
6072         return target;
6073       break;
6074
6075     CASE_INT_FN (BUILT_IN_CTZ):
6076     case BUILT_IN_CTZIMAX:
6077       target = expand_builtin_unop (target_mode, exp, target,
6078                                     subtarget, ctz_optab);
6079       if (target)
6080         return target;
6081       break;
6082
6083     CASE_INT_FN (BUILT_IN_CLRSB):
6084     case BUILT_IN_CLRSBIMAX:
6085       target = expand_builtin_unop (target_mode, exp, target,
6086                                     subtarget, clrsb_optab);
6087       if (target)
6088         return target;
6089       break;
6090
6091     CASE_INT_FN (BUILT_IN_POPCOUNT):
6092     case BUILT_IN_POPCOUNTIMAX:
6093       target = expand_builtin_unop (target_mode, exp, target,
6094                                     subtarget, popcount_optab);
6095       if (target)
6096         return target;
6097       break;
6098
6099     CASE_INT_FN (BUILT_IN_PARITY):
6100     case BUILT_IN_PARITYIMAX:
6101       target = expand_builtin_unop (target_mode, exp, target,
6102                                     subtarget, parity_optab);
6103       if (target)
6104         return target;
6105       break;
6106
6107     case BUILT_IN_STRLEN:
6108       target = expand_builtin_strlen (exp, target, target_mode);
6109       if (target)
6110         return target;
6111       break;
6112
6113     case BUILT_IN_STRCPY:
6114       target = expand_builtin_strcpy (exp, target);
6115       if (target)
6116         return target;
6117       break;
6118
6119     case BUILT_IN_STRNCPY:
6120       target = expand_builtin_strncpy (exp, target);
6121       if (target)
6122         return target;
6123       break;
6124
6125     case BUILT_IN_STPCPY:
6126       target = expand_builtin_stpcpy (exp, target, mode);
6127       if (target)
6128         return target;
6129       break;
6130
6131     case BUILT_IN_MEMCPY:
6132       target = expand_builtin_memcpy (exp, target);
6133       if (target)
6134         return target;
6135       break;
6136
6137     case BUILT_IN_MEMPCPY:
6138       target = expand_builtin_mempcpy (exp, target, mode);
6139       if (target)
6140         return target;
6141       break;
6142
6143     case BUILT_IN_MEMSET:
6144       target = expand_builtin_memset (exp, target, mode);
6145       if (target)
6146         return target;
6147       break;
6148
6149     case BUILT_IN_BZERO:
6150       target = expand_builtin_bzero (exp);
6151       if (target)
6152         return target;
6153       break;
6154
6155     case BUILT_IN_STRCMP:
6156       target = expand_builtin_strcmp (exp, target);
6157       if (target)
6158         return target;
6159       break;
6160
6161     case BUILT_IN_STRNCMP:
6162       target = expand_builtin_strncmp (exp, target, mode);
6163       if (target)
6164         return target;
6165       break;
6166
6167     case BUILT_IN_BCMP:
6168     case BUILT_IN_MEMCMP:
6169       target = expand_builtin_memcmp (exp, target, mode);
6170       if (target)
6171         return target;
6172       break;
6173
6174     case BUILT_IN_SETJMP:
6175       /* This should have been lowered to the builtins below.  */
6176       gcc_unreachable ();
6177
6178     case BUILT_IN_SETJMP_SETUP:
6179       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6180           and the receiver label.  */
6181       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6182         {
6183           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6184                                       VOIDmode, EXPAND_NORMAL);
6185           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6186           rtx label_r = label_rtx (label);
6187
6188           /* This is copied from the handling of non-local gotos.  */
6189           expand_builtin_setjmp_setup (buf_addr, label_r);
6190           nonlocal_goto_handler_labels
6191             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6192                                  nonlocal_goto_handler_labels);
6193           /* ??? Do not let expand_label treat us as such since we would
6194              not want to be both on the list of non-local labels and on
6195              the list of forced labels.  */
6196           FORCED_LABEL (label) = 0;
6197           return const0_rtx;
6198         }
6199       break;
6200
6201     case BUILT_IN_SETJMP_DISPATCHER:
6202        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6203       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6204         {
6205           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6206           rtx label_r = label_rtx (label);
6207
6208           /* Remove the dispatcher label from the list of non-local labels
6209              since the receiver labels have been added to it above.  */
6210           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6211           return const0_rtx;
6212         }
6213       break;
6214
6215     case BUILT_IN_SETJMP_RECEIVER:
6216        /* __builtin_setjmp_receiver is passed the receiver label.  */
6217       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6218         {
6219           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6220           rtx label_r = label_rtx (label);
6221
6222           expand_builtin_setjmp_receiver (label_r);
6223           return const0_rtx;
6224         }
6225       break;
6226
6227       /* __builtin_longjmp is passed a pointer to an array of five words.
6228          It's similar to the C library longjmp function but works with
6229          __builtin_setjmp above.  */
6230     case BUILT_IN_LONGJMP:
6231       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6232         {
6233           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6234                                       VOIDmode, EXPAND_NORMAL);
6235           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6236
6237           if (value != const1_rtx)
6238             {
6239               error ("%<__builtin_longjmp%> second argument must be 1");
6240               return const0_rtx;
6241             }
6242
6243           expand_builtin_longjmp (buf_addr, value);
6244           return const0_rtx;
6245         }
6246       break;
6247
6248     case BUILT_IN_NONLOCAL_GOTO:
6249       target = expand_builtin_nonlocal_goto (exp);
6250       if (target)
6251         return target;
6252       break;
6253
6254       /* This updates the setjmp buffer that is its argument with the value
6255          of the current stack pointer.  */
6256     case BUILT_IN_UPDATE_SETJMP_BUF:
6257       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6258         {
6259           rtx buf_addr
6260             = expand_normal (CALL_EXPR_ARG (exp, 0));
6261
6262           expand_builtin_update_setjmp_buf (buf_addr);
6263           return const0_rtx;
6264         }
6265       break;
6266
6267     case BUILT_IN_TRAP:
6268       expand_builtin_trap ();
6269       return const0_rtx;
6270
6271     case BUILT_IN_UNREACHABLE:
6272       expand_builtin_unreachable ();
6273       return const0_rtx;
6274
6275     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6276     case BUILT_IN_SIGNBITD32:
6277     case BUILT_IN_SIGNBITD64:
6278     case BUILT_IN_SIGNBITD128:
6279       target = expand_builtin_signbit (exp, target);
6280       if (target)
6281         return target;
6282       break;
6283
6284       /* Various hooks for the DWARF 2 __throw routine.  */
6285     case BUILT_IN_UNWIND_INIT:
6286       expand_builtin_unwind_init ();
6287       return const0_rtx;
6288     case BUILT_IN_DWARF_CFA:
6289       return virtual_cfa_rtx;
6290 #ifdef DWARF2_UNWIND_INFO
6291     case BUILT_IN_DWARF_SP_COLUMN:
6292       return expand_builtin_dwarf_sp_column ();
6293     case BUILT_IN_INIT_DWARF_REG_SIZES:
6294       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6295       return const0_rtx;
6296 #endif
6297     case BUILT_IN_FROB_RETURN_ADDR:
6298       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6299     case BUILT_IN_EXTRACT_RETURN_ADDR:
6300       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6301     case BUILT_IN_EH_RETURN:
6302       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6303                                 CALL_EXPR_ARG (exp, 1));
6304       return const0_rtx;
6305 #ifdef EH_RETURN_DATA_REGNO
6306     case BUILT_IN_EH_RETURN_DATA_REGNO:
6307       return expand_builtin_eh_return_data_regno (exp);
6308 #endif
6309     case BUILT_IN_EXTEND_POINTER:
6310       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6311     case BUILT_IN_EH_POINTER:
6312       return expand_builtin_eh_pointer (exp);
6313     case BUILT_IN_EH_FILTER:
6314       return expand_builtin_eh_filter (exp);
6315     case BUILT_IN_EH_COPY_VALUES:
6316       return expand_builtin_eh_copy_values (exp);
6317
6318     case BUILT_IN_VA_START:
6319       return expand_builtin_va_start (exp);
6320     case BUILT_IN_VA_END:
6321       return expand_builtin_va_end (exp);
6322     case BUILT_IN_VA_COPY:
6323       return expand_builtin_va_copy (exp);
6324     case BUILT_IN_EXPECT:
6325       return expand_builtin_expect (exp, target);
6326     case BUILT_IN_ASSUME_ALIGNED:
6327       return expand_builtin_assume_aligned (exp, target);
6328     case BUILT_IN_PREFETCH:
6329       expand_builtin_prefetch (exp);
6330       return const0_rtx;
6331
6332     case BUILT_IN_INIT_TRAMPOLINE:
6333       return expand_builtin_init_trampoline (exp, true);
6334     case BUILT_IN_INIT_HEAP_TRAMPOLINE:
6335       return expand_builtin_init_trampoline (exp, false);
6336     case BUILT_IN_ADJUST_TRAMPOLINE:
6337       return expand_builtin_adjust_trampoline (exp);
6338
6339     case BUILT_IN_FORK:
6340     case BUILT_IN_EXECL:
6341     case BUILT_IN_EXECV:
6342     case BUILT_IN_EXECLP:
6343     case BUILT_IN_EXECLE:
6344     case BUILT_IN_EXECVP:
6345     case BUILT_IN_EXECVE:
6346       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6347       if (target)
6348         return target;
6349       break;
6350
6351     case BUILT_IN_SYNC_FETCH_AND_ADD_1:
6352     case BUILT_IN_SYNC_FETCH_AND_ADD_2:
6353     case BUILT_IN_SYNC_FETCH_AND_ADD_4:
6354     case BUILT_IN_SYNC_FETCH_AND_ADD_8:
6355     case BUILT_IN_SYNC_FETCH_AND_ADD_16:
6356       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1);
6357       target = expand_builtin_sync_operation (mode, exp, PLUS, false, target);
6358       if (target)
6359         return target;
6360       break;
6361
6362     case BUILT_IN_SYNC_FETCH_AND_SUB_1:
6363     case BUILT_IN_SYNC_FETCH_AND_SUB_2:
6364     case BUILT_IN_SYNC_FETCH_AND_SUB_4:
6365     case BUILT_IN_SYNC_FETCH_AND_SUB_8:
6366     case BUILT_IN_SYNC_FETCH_AND_SUB_16:
6367       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1);
6368       target = expand_builtin_sync_operation (mode, exp, MINUS, false, target);
6369       if (target)
6370         return target;
6371       break;
6372
6373     case BUILT_IN_SYNC_FETCH_AND_OR_1:
6374     case BUILT_IN_SYNC_FETCH_AND_OR_2:
6375     case BUILT_IN_SYNC_FETCH_AND_OR_4:
6376     case BUILT_IN_SYNC_FETCH_AND_OR_8:
6377     case BUILT_IN_SYNC_FETCH_AND_OR_16:
6378       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1);
6379       target = expand_builtin_sync_operation (mode, exp, IOR, false, target);
6380       if (target)
6381         return target;
6382       break;
6383
6384     case BUILT_IN_SYNC_FETCH_AND_AND_1:
6385     case BUILT_IN_SYNC_FETCH_AND_AND_2:
6386     case BUILT_IN_SYNC_FETCH_AND_AND_4:
6387     case BUILT_IN_SYNC_FETCH_AND_AND_8:
6388     case BUILT_IN_SYNC_FETCH_AND_AND_16:
6389       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1);
6390       target = expand_builtin_sync_operation (mode, exp, AND, false, target);
6391       if (target)
6392         return target;
6393       break;
6394
6395     case BUILT_IN_SYNC_FETCH_AND_XOR_1:
6396     case BUILT_IN_SYNC_FETCH_AND_XOR_2:
6397     case BUILT_IN_SYNC_FETCH_AND_XOR_4:
6398     case BUILT_IN_SYNC_FETCH_AND_XOR_8:
6399     case BUILT_IN_SYNC_FETCH_AND_XOR_16:
6400       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1);
6401       target = expand_builtin_sync_operation (mode, exp, XOR, false, target);
6402       if (target)
6403         return target;
6404       break;
6405
6406     case BUILT_IN_SYNC_FETCH_AND_NAND_1:
6407     case BUILT_IN_SYNC_FETCH_AND_NAND_2:
6408     case BUILT_IN_SYNC_FETCH_AND_NAND_4:
6409     case BUILT_IN_SYNC_FETCH_AND_NAND_8:
6410     case BUILT_IN_SYNC_FETCH_AND_NAND_16:
6411       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1);
6412       target = expand_builtin_sync_operation (mode, exp, NOT, false, target);
6413       if (target)
6414         return target;
6415       break;
6416
6417     case BUILT_IN_SYNC_ADD_AND_FETCH_1:
6418     case BUILT_IN_SYNC_ADD_AND_FETCH_2:
6419     case BUILT_IN_SYNC_ADD_AND_FETCH_4:
6420     case BUILT_IN_SYNC_ADD_AND_FETCH_8:
6421     case BUILT_IN_SYNC_ADD_AND_FETCH_16:
6422       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1);
6423       target = expand_builtin_sync_operation (mode, exp, PLUS, true, target);
6424       if (target)
6425         return target;
6426       break;
6427
6428     case BUILT_IN_SYNC_SUB_AND_FETCH_1:
6429     case BUILT_IN_SYNC_SUB_AND_FETCH_2:
6430     case BUILT_IN_SYNC_SUB_AND_FETCH_4:
6431     case BUILT_IN_SYNC_SUB_AND_FETCH_8:
6432     case BUILT_IN_SYNC_SUB_AND_FETCH_16:
6433       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1);
6434       target = expand_builtin_sync_operation (mode, exp, MINUS, true, target);
6435       if (target)
6436         return target;
6437       break;
6438
6439     case BUILT_IN_SYNC_OR_AND_FETCH_1:
6440     case BUILT_IN_SYNC_OR_AND_FETCH_2:
6441     case BUILT_IN_SYNC_OR_AND_FETCH_4:
6442     case BUILT_IN_SYNC_OR_AND_FETCH_8:
6443     case BUILT_IN_SYNC_OR_AND_FETCH_16:
6444       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1);
6445       target = expand_builtin_sync_operation (mode, exp, IOR, true, target);
6446       if (target)
6447         return target;
6448       break;
6449
6450     case BUILT_IN_SYNC_AND_AND_FETCH_1:
6451     case BUILT_IN_SYNC_AND_AND_FETCH_2:
6452     case BUILT_IN_SYNC_AND_AND_FETCH_4:
6453     case BUILT_IN_SYNC_AND_AND_FETCH_8:
6454     case BUILT_IN_SYNC_AND_AND_FETCH_16:
6455       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1);
6456       target = expand_builtin_sync_operation (mode, exp, AND, true, target);
6457       if (target)
6458         return target;
6459       break;
6460
6461     case BUILT_IN_SYNC_XOR_AND_FETCH_1:
6462     case BUILT_IN_SYNC_XOR_AND_FETCH_2:
6463     case BUILT_IN_SYNC_XOR_AND_FETCH_4:
6464     case BUILT_IN_SYNC_XOR_AND_FETCH_8:
6465     case BUILT_IN_SYNC_XOR_AND_FETCH_16:
6466       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1);
6467       target = expand_builtin_sync_operation (mode, exp, XOR, true, target);
6468       if (target)
6469         return target;
6470       break;
6471
6472     case BUILT_IN_SYNC_NAND_AND_FETCH_1:
6473     case BUILT_IN_SYNC_NAND_AND_FETCH_2:
6474     case BUILT_IN_SYNC_NAND_AND_FETCH_4:
6475     case BUILT_IN_SYNC_NAND_AND_FETCH_8:
6476     case BUILT_IN_SYNC_NAND_AND_FETCH_16:
6477       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1);
6478       target = expand_builtin_sync_operation (mode, exp, NOT, true, target);
6479       if (target)
6480         return target;
6481       break;
6482
6483     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
6484     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
6485     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
6486     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
6487     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
6488       if (mode == VOIDmode)
6489         mode = TYPE_MODE (boolean_type_node);
6490       if (!target || !register_operand (target, mode))
6491         target = gen_reg_rtx (mode);
6492
6493       mode = get_builtin_sync_mode 
6494                                 (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1);
6495       target = expand_builtin_compare_and_swap (mode, exp, true, target);
6496       if (target)
6497         return target;
6498       break;
6499
6500     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
6501     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
6502     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
6503     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
6504     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
6505       mode = get_builtin_sync_mode 
6506                                 (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1);
6507       target = expand_builtin_compare_and_swap (mode, exp, false, target);
6508       if (target)
6509         return target;
6510       break;
6511
6512     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
6513     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
6514     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
6515     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
6516     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
6517       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1);
6518       target = expand_builtin_sync_lock_test_and_set (mode, exp, target);
6519       if (target)
6520         return target;
6521       break;
6522
6523     case BUILT_IN_SYNC_LOCK_RELEASE_1:
6524     case BUILT_IN_SYNC_LOCK_RELEASE_2:
6525     case BUILT_IN_SYNC_LOCK_RELEASE_4:
6526     case BUILT_IN_SYNC_LOCK_RELEASE_8:
6527     case BUILT_IN_SYNC_LOCK_RELEASE_16:
6528       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1);
6529       expand_builtin_sync_lock_release (mode, exp);
6530       return const0_rtx;
6531
6532     case BUILT_IN_SYNC_SYNCHRONIZE:
6533       expand_builtin_sync_synchronize ();
6534       return const0_rtx;
6535
6536     case BUILT_IN_ATOMIC_EXCHANGE_1:
6537     case BUILT_IN_ATOMIC_EXCHANGE_2:
6538     case BUILT_IN_ATOMIC_EXCHANGE_4:
6539     case BUILT_IN_ATOMIC_EXCHANGE_8:
6540     case BUILT_IN_ATOMIC_EXCHANGE_16:
6541       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1);
6542       target = expand_builtin_atomic_exchange (mode, exp, target);
6543       if (target)
6544         return target;
6545       break;
6546
6547     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
6548     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
6549     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
6550     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
6551     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
6552       {
6553         unsigned int nargs, z;
6554         VEC(tree,gc) *vec;
6555
6556         mode = 
6557             get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
6558         target = expand_builtin_atomic_compare_exchange (mode, exp, target);
6559         if (target)
6560           return target;
6561
6562         /* If this is turned into an external library call, the weak parameter
6563            must be dropped to match the expected parameter list.  */
6564         nargs = call_expr_nargs (exp);
6565         vec = VEC_alloc (tree, gc, nargs - 1);
6566         for (z = 0; z < 3; z++)
6567           VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6568         /* Skip the boolean weak parameter.  */
6569         for (z = 4; z < 6; z++)
6570           VEC_quick_push (tree, vec, CALL_EXPR_ARG (exp, z));
6571         exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
6572         break;
6573       }
6574
6575     case BUILT_IN_ATOMIC_LOAD_1:
6576     case BUILT_IN_ATOMIC_LOAD_2:
6577     case BUILT_IN_ATOMIC_LOAD_4:
6578     case BUILT_IN_ATOMIC_LOAD_8:
6579     case BUILT_IN_ATOMIC_LOAD_16:
6580       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1);
6581       target = expand_builtin_atomic_load (mode, exp, target);
6582       if (target)
6583         return target;
6584       break;
6585
6586     case BUILT_IN_ATOMIC_STORE_1:
6587     case BUILT_IN_ATOMIC_STORE_2:
6588     case BUILT_IN_ATOMIC_STORE_4:
6589     case BUILT_IN_ATOMIC_STORE_8:
6590     case BUILT_IN_ATOMIC_STORE_16:
6591       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1);
6592       target = expand_builtin_atomic_store (mode, exp);
6593       if (target)
6594         return const0_rtx;
6595       break;
6596
6597     case BUILT_IN_ATOMIC_ADD_FETCH_1:
6598     case BUILT_IN_ATOMIC_ADD_FETCH_2:
6599     case BUILT_IN_ATOMIC_ADD_FETCH_4:
6600     case BUILT_IN_ATOMIC_ADD_FETCH_8:
6601     case BUILT_IN_ATOMIC_ADD_FETCH_16:
6602       {
6603         enum built_in_function lib;
6604         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1);
6605         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 + 
6606                                        (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1));
6607         target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true,
6608                                                  ignore, lib);
6609         if (target)
6610           return target;
6611         break;
6612       }
6613     case BUILT_IN_ATOMIC_SUB_FETCH_1:
6614     case BUILT_IN_ATOMIC_SUB_FETCH_2:
6615     case BUILT_IN_ATOMIC_SUB_FETCH_4:
6616     case BUILT_IN_ATOMIC_SUB_FETCH_8:
6617     case BUILT_IN_ATOMIC_SUB_FETCH_16:
6618       {
6619         enum built_in_function lib;
6620         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1);
6621         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 + 
6622                                        (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1));
6623         target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true,
6624                                                  ignore, lib);
6625         if (target)
6626           return target;
6627         break;
6628       }
6629     case BUILT_IN_ATOMIC_AND_FETCH_1:
6630     case BUILT_IN_ATOMIC_AND_FETCH_2:
6631     case BUILT_IN_ATOMIC_AND_FETCH_4:
6632     case BUILT_IN_ATOMIC_AND_FETCH_8:
6633     case BUILT_IN_ATOMIC_AND_FETCH_16:
6634       {
6635         enum built_in_function lib;
6636         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1);
6637         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 + 
6638                                        (fcode - BUILT_IN_ATOMIC_AND_FETCH_1));
6639         target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true,
6640                                                  ignore, lib);
6641         if (target)
6642           return target;
6643         break;
6644       }
6645     case BUILT_IN_ATOMIC_NAND_FETCH_1:
6646     case BUILT_IN_ATOMIC_NAND_FETCH_2:
6647     case BUILT_IN_ATOMIC_NAND_FETCH_4:
6648     case BUILT_IN_ATOMIC_NAND_FETCH_8:
6649     case BUILT_IN_ATOMIC_NAND_FETCH_16:
6650       {
6651         enum built_in_function lib;
6652         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1);
6653         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 + 
6654                                        (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1));
6655         target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true,
6656                                                  ignore, lib);
6657         if (target)
6658           return target;
6659         break;
6660       }
6661     case BUILT_IN_ATOMIC_XOR_FETCH_1:
6662     case BUILT_IN_ATOMIC_XOR_FETCH_2:
6663     case BUILT_IN_ATOMIC_XOR_FETCH_4:
6664     case BUILT_IN_ATOMIC_XOR_FETCH_8:
6665     case BUILT_IN_ATOMIC_XOR_FETCH_16:
6666       {
6667         enum built_in_function lib;
6668         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1);
6669         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 + 
6670                                        (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1));
6671         target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true,
6672                                                  ignore, lib);
6673         if (target)
6674           return target;
6675         break;
6676       }
6677     case BUILT_IN_ATOMIC_OR_FETCH_1:
6678     case BUILT_IN_ATOMIC_OR_FETCH_2:
6679     case BUILT_IN_ATOMIC_OR_FETCH_4:
6680     case BUILT_IN_ATOMIC_OR_FETCH_8:
6681     case BUILT_IN_ATOMIC_OR_FETCH_16:
6682       {
6683         enum built_in_function lib;
6684         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1);
6685         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 + 
6686                                        (fcode - BUILT_IN_ATOMIC_OR_FETCH_1));
6687         target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true,
6688                                                  ignore, lib);
6689         if (target)
6690           return target;
6691         break;
6692       }
6693     case BUILT_IN_ATOMIC_FETCH_ADD_1:
6694     case BUILT_IN_ATOMIC_FETCH_ADD_2:
6695     case BUILT_IN_ATOMIC_FETCH_ADD_4:
6696     case BUILT_IN_ATOMIC_FETCH_ADD_8:
6697     case BUILT_IN_ATOMIC_FETCH_ADD_16:
6698       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1);
6699       target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false,
6700                                                ignore, BUILT_IN_NONE);
6701       if (target)
6702         return target;
6703       break;
6704  
6705     case BUILT_IN_ATOMIC_FETCH_SUB_1:
6706     case BUILT_IN_ATOMIC_FETCH_SUB_2:
6707     case BUILT_IN_ATOMIC_FETCH_SUB_4:
6708     case BUILT_IN_ATOMIC_FETCH_SUB_8:
6709     case BUILT_IN_ATOMIC_FETCH_SUB_16:
6710       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1);
6711       target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false,
6712                                                ignore, BUILT_IN_NONE);
6713       if (target)
6714         return target;
6715       break;
6716
6717     case BUILT_IN_ATOMIC_FETCH_AND_1:
6718     case BUILT_IN_ATOMIC_FETCH_AND_2:
6719     case BUILT_IN_ATOMIC_FETCH_AND_4:
6720     case BUILT_IN_ATOMIC_FETCH_AND_8:
6721     case BUILT_IN_ATOMIC_FETCH_AND_16:
6722       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1);
6723       target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false,
6724                                                ignore, BUILT_IN_NONE);
6725       if (target)
6726         return target;
6727       break;
6728   
6729     case BUILT_IN_ATOMIC_FETCH_NAND_1:
6730     case BUILT_IN_ATOMIC_FETCH_NAND_2:
6731     case BUILT_IN_ATOMIC_FETCH_NAND_4:
6732     case BUILT_IN_ATOMIC_FETCH_NAND_8:
6733     case BUILT_IN_ATOMIC_FETCH_NAND_16:
6734       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1);
6735       target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false,
6736                                                ignore, BUILT_IN_NONE);
6737       if (target)
6738         return target;
6739       break;
6740  
6741     case BUILT_IN_ATOMIC_FETCH_XOR_1:
6742     case BUILT_IN_ATOMIC_FETCH_XOR_2:
6743     case BUILT_IN_ATOMIC_FETCH_XOR_4:
6744     case BUILT_IN_ATOMIC_FETCH_XOR_8:
6745     case BUILT_IN_ATOMIC_FETCH_XOR_16:
6746       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1);
6747       target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false,
6748                                                ignore, BUILT_IN_NONE);
6749       if (target)
6750         return target;
6751       break;
6752  
6753     case BUILT_IN_ATOMIC_FETCH_OR_1:
6754     case BUILT_IN_ATOMIC_FETCH_OR_2:
6755     case BUILT_IN_ATOMIC_FETCH_OR_4:
6756     case BUILT_IN_ATOMIC_FETCH_OR_8:
6757     case BUILT_IN_ATOMIC_FETCH_OR_16:
6758       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1);
6759       target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false,
6760                                                ignore, BUILT_IN_NONE);
6761       if (target)
6762         return target;
6763       break;
6764
6765     case BUILT_IN_ATOMIC_TEST_AND_SET:
6766       return expand_builtin_atomic_test_and_set (exp, target);
6767
6768     case BUILT_IN_ATOMIC_CLEAR:
6769       return expand_builtin_atomic_clear (exp);
6770  
6771     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
6772       return expand_builtin_atomic_always_lock_free (exp);
6773
6774     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
6775       target = expand_builtin_atomic_is_lock_free (exp);
6776       if (target)
6777         return target;
6778       break;
6779
6780     case BUILT_IN_ATOMIC_THREAD_FENCE:
6781       expand_builtin_atomic_thread_fence (exp);
6782       return const0_rtx;
6783
6784     case BUILT_IN_ATOMIC_SIGNAL_FENCE:
6785       expand_builtin_atomic_signal_fence (exp);
6786       return const0_rtx;
6787
6788     case BUILT_IN_OBJECT_SIZE:
6789       return expand_builtin_object_size (exp);
6790
6791     case BUILT_IN_MEMCPY_CHK:
6792     case BUILT_IN_MEMPCPY_CHK:
6793     case BUILT_IN_MEMMOVE_CHK:
6794     case BUILT_IN_MEMSET_CHK:
6795       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6796       if (target)
6797         return target;
6798       break;
6799
6800     case BUILT_IN_STRCPY_CHK:
6801     case BUILT_IN_STPCPY_CHK:
6802     case BUILT_IN_STRNCPY_CHK:
6803     case BUILT_IN_STPNCPY_CHK:
6804     case BUILT_IN_STRCAT_CHK:
6805     case BUILT_IN_STRNCAT_CHK:
6806     case BUILT_IN_SNPRINTF_CHK:
6807     case BUILT_IN_VSNPRINTF_CHK:
6808       maybe_emit_chk_warning (exp, fcode);
6809       break;
6810
6811     case BUILT_IN_SPRINTF_CHK:
6812     case BUILT_IN_VSPRINTF_CHK:
6813       maybe_emit_sprintf_chk_warning (exp, fcode);
6814       break;
6815
6816     case BUILT_IN_FREE:
6817       if (warn_free_nonheap_object)
6818         maybe_emit_free_warning (exp);
6819       break;
6820
6821     default:    /* just do library call, if unknown builtin */
6822       break;
6823     }
6824
6825   /* The switch statement above can drop through to cause the function
6826      to be called normally.  */
6827   return expand_call (exp, target, ignore);
6828 }
6829
6830 /* Determine whether a tree node represents a call to a built-in
6831    function.  If the tree T is a call to a built-in function with
6832    the right number of arguments of the appropriate types, return
6833    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6834    Otherwise the return value is END_BUILTINS.  */
6835
6836 enum built_in_function
6837 builtin_mathfn_code (const_tree t)
6838 {
6839   const_tree fndecl, arg, parmlist;
6840   const_tree argtype, parmtype;
6841   const_call_expr_arg_iterator iter;
6842
6843   if (TREE_CODE (t) != CALL_EXPR
6844       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6845     return END_BUILTINS;
6846
6847   fndecl = get_callee_fndecl (t);
6848   if (fndecl == NULL_TREE
6849       || TREE_CODE (fndecl) != FUNCTION_DECL
6850       || ! DECL_BUILT_IN (fndecl)
6851       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6852     return END_BUILTINS;
6853
6854   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6855   init_const_call_expr_arg_iterator (t, &iter);
6856   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6857     {
6858       /* If a function doesn't take a variable number of arguments,
6859          the last element in the list will have type `void'.  */
6860       parmtype = TREE_VALUE (parmlist);
6861       if (VOID_TYPE_P (parmtype))
6862         {
6863           if (more_const_call_expr_args_p (&iter))
6864             return END_BUILTINS;
6865           return DECL_FUNCTION_CODE (fndecl);
6866         }
6867
6868       if (! more_const_call_expr_args_p (&iter))
6869         return END_BUILTINS;
6870
6871       arg = next_const_call_expr_arg (&iter);
6872       argtype = TREE_TYPE (arg);
6873
6874       if (SCALAR_FLOAT_TYPE_P (parmtype))
6875         {
6876           if (! SCALAR_FLOAT_TYPE_P (argtype))
6877             return END_BUILTINS;
6878         }
6879       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6880         {
6881           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6882             return END_BUILTINS;
6883         }
6884       else if (POINTER_TYPE_P (parmtype))
6885         {
6886           if (! POINTER_TYPE_P (argtype))
6887             return END_BUILTINS;
6888         }
6889       else if (INTEGRAL_TYPE_P (parmtype))
6890         {
6891           if (! INTEGRAL_TYPE_P (argtype))
6892             return END_BUILTINS;
6893         }
6894       else
6895         return END_BUILTINS;
6896     }
6897
6898   /* Variable-length argument list.  */
6899   return DECL_FUNCTION_CODE (fndecl);
6900 }
6901
6902 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
6903    evaluate to a constant.  */
6904
6905 static tree
6906 fold_builtin_constant_p (tree arg)
6907 {
6908   /* We return 1 for a numeric type that's known to be a constant
6909      value at compile-time or for an aggregate type that's a
6910      literal constant.  */
6911   STRIP_NOPS (arg);
6912
6913   /* If we know this is a constant, emit the constant of one.  */
6914   if (CONSTANT_CLASS_P (arg)
6915       || (TREE_CODE (arg) == CONSTRUCTOR
6916           && TREE_CONSTANT (arg)))
6917     return integer_one_node;
6918   if (TREE_CODE (arg) == ADDR_EXPR)
6919     {
6920        tree op = TREE_OPERAND (arg, 0);
6921        if (TREE_CODE (op) == STRING_CST
6922            || (TREE_CODE (op) == ARRAY_REF
6923                && integer_zerop (TREE_OPERAND (op, 1))
6924                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6925          return integer_one_node;
6926     }
6927
6928   /* If this expression has side effects, show we don't know it to be a
6929      constant.  Likewise if it's a pointer or aggregate type since in
6930      those case we only want literals, since those are only optimized
6931      when generating RTL, not later.
6932      And finally, if we are compiling an initializer, not code, we
6933      need to return a definite result now; there's not going to be any
6934      more optimization done.  */
6935   if (TREE_SIDE_EFFECTS (arg)
6936       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6937       || POINTER_TYPE_P (TREE_TYPE (arg))
6938       || cfun == 0
6939       || folding_initializer)
6940     return integer_zero_node;
6941
6942   return NULL_TREE;
6943 }
6944
6945 /* Create builtin_expect with PRED and EXPECTED as its arguments and
6946    return it as a truthvalue.  */
6947
6948 static tree
6949 build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6950 {
6951   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6952
6953   fn = builtin_decl_explicit (BUILT_IN_EXPECT);
6954   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6955   ret_type = TREE_TYPE (TREE_TYPE (fn));
6956   pred_type = TREE_VALUE (arg_types);
6957   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6958
6959   pred = fold_convert_loc (loc, pred_type, pred);
6960   expected = fold_convert_loc (loc, expected_type, expected);
6961   call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
6962
6963   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6964                  build_int_cst (ret_type, 0));
6965 }
6966
6967 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
6968    NULL_TREE if no simplification is possible.  */
6969
6970 static tree
6971 fold_builtin_expect (location_t loc, tree arg0, tree arg1)
6972 {
6973   tree inner, fndecl, inner_arg0;
6974   enum tree_code code;
6975
6976   /* Distribute the expected value over short-circuiting operators.
6977      See through the cast from truthvalue_type_node to long.  */
6978   inner_arg0 = arg0;
6979   while (TREE_CODE (inner_arg0) == NOP_EXPR
6980          && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0))
6981          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0))))
6982     inner_arg0 = TREE_OPERAND (inner_arg0, 0);
6983
6984   /* If this is a builtin_expect within a builtin_expect keep the
6985      inner one.  See through a comparison against a constant.  It
6986      might have been added to create a thruthvalue.  */
6987   inner = inner_arg0;
6988
6989   if (COMPARISON_CLASS_P (inner)
6990       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6991     inner = TREE_OPERAND (inner, 0);
6992
6993   if (TREE_CODE (inner) == CALL_EXPR
6994       && (fndecl = get_callee_fndecl (inner))
6995       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
6996       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
6997     return arg0;
6998
6999   inner = inner_arg0;
7000   code = TREE_CODE (inner);
7001   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7002     {
7003       tree op0 = TREE_OPERAND (inner, 0);
7004       tree op1 = TREE_OPERAND (inner, 1);
7005
7006       op0 = build_builtin_expect_predicate (loc, op0, arg1);
7007       op1 = build_builtin_expect_predicate (loc, op1, arg1);
7008       inner = build2 (code, TREE_TYPE (inner), op0, op1);
7009
7010       return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
7011     }
7012
7013   /* If the argument isn't invariant then there's nothing else we can do.  */
7014   if (!TREE_CONSTANT (inner_arg0))
7015     return NULL_TREE;
7016
7017   /* If we expect that a comparison against the argument will fold to
7018      a constant return the constant.  In practice, this means a true
7019      constant or the address of a non-weak symbol.  */
7020   inner = inner_arg0;
7021   STRIP_NOPS (inner);
7022   if (TREE_CODE (inner) == ADDR_EXPR)
7023     {
7024       do
7025         {
7026           inner = TREE_OPERAND (inner, 0);
7027         }
7028       while (TREE_CODE (inner) == COMPONENT_REF
7029              || TREE_CODE (inner) == ARRAY_REF);
7030       if ((TREE_CODE (inner) == VAR_DECL
7031            || TREE_CODE (inner) == FUNCTION_DECL)
7032           && DECL_WEAK (inner))
7033         return NULL_TREE;
7034     }
7035
7036   /* Otherwise, ARG0 already has the proper type for the return value.  */
7037   return arg0;
7038 }
7039
7040 /* Fold a call to __builtin_classify_type with argument ARG.  */
7041
7042 static tree
7043 fold_builtin_classify_type (tree arg)
7044 {
7045   if (arg == 0)
7046     return build_int_cst (integer_type_node, no_type_class);
7047
7048   return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg)));
7049 }
7050
7051 /* Fold a call to __builtin_strlen with argument ARG.  */
7052
7053 static tree
7054 fold_builtin_strlen (location_t loc, tree type, tree arg)
7055 {
7056   if (!validate_arg (arg, POINTER_TYPE))
7057     return NULL_TREE;
7058   else
7059     {
7060       tree len = c_strlen (arg, 0);
7061
7062       if (len)
7063         return fold_convert_loc (loc, type, len);
7064
7065       return NULL_TREE;
7066     }
7067 }
7068
7069 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
7070
7071 static tree
7072 fold_builtin_inf (location_t loc, tree type, int warn)
7073 {
7074   REAL_VALUE_TYPE real;
7075
7076   /* __builtin_inff is intended to be usable to define INFINITY on all
7077      targets.  If an infinity is not available, INFINITY expands "to a
7078      positive constant of type float that overflows at translation
7079      time", footnote "In this case, using INFINITY will violate the
7080      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7081      Thus we pedwarn to ensure this constraint violation is
7082      diagnosed.  */
7083   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7084     pedwarn (loc, 0, "target format does not support infinity");
7085
7086   real_inf (&real);
7087   return build_real (type, real);
7088 }
7089
7090 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7091
7092 static tree
7093 fold_builtin_nan (tree arg, tree type, int quiet)
7094 {
7095   REAL_VALUE_TYPE real;
7096   const char *str;
7097
7098   if (!validate_arg (arg, POINTER_TYPE))
7099     return NULL_TREE;
7100   str = c_getstr (arg);
7101   if (!str)
7102     return NULL_TREE;
7103
7104   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7105     return NULL_TREE;
7106
7107   return build_real (type, real);
7108 }
7109
7110 /* Return true if the floating point expression T has an integer value.
7111    We also allow +Inf, -Inf and NaN to be considered integer values.  */
7112
7113 static bool
7114 integer_valued_real_p (tree t)
7115 {
7116   switch (TREE_CODE (t))
7117     {
7118     case FLOAT_EXPR:
7119       return true;
7120
7121     case ABS_EXPR:
7122     case SAVE_EXPR:
7123       return integer_valued_real_p (TREE_OPERAND (t, 0));
7124
7125     case COMPOUND_EXPR:
7126     case MODIFY_EXPR:
7127     case BIND_EXPR:
7128       return integer_valued_real_p (TREE_OPERAND (t, 1));
7129
7130     case PLUS_EXPR:
7131     case MINUS_EXPR:
7132     case MULT_EXPR:
7133     case MIN_EXPR:
7134     case MAX_EXPR:
7135       return integer_valued_real_p (TREE_OPERAND (t, 0))
7136              && integer_valued_real_p (TREE_OPERAND (t, 1));
7137
7138     case COND_EXPR:
7139       return integer_valued_real_p (TREE_OPERAND (t, 1))
7140              && integer_valued_real_p (TREE_OPERAND (t, 2));
7141
7142     case REAL_CST:
7143       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7144
7145     case NOP_EXPR:
7146       {
7147         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7148         if (TREE_CODE (type) == INTEGER_TYPE)
7149           return true;
7150         if (TREE_CODE (type) == REAL_TYPE)
7151           return integer_valued_real_p (TREE_OPERAND (t, 0));
7152         break;
7153       }
7154
7155     case CALL_EXPR:
7156       switch (builtin_mathfn_code (t))
7157         {
7158         CASE_FLT_FN (BUILT_IN_CEIL):
7159         CASE_FLT_FN (BUILT_IN_FLOOR):
7160         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7161         CASE_FLT_FN (BUILT_IN_RINT):
7162         CASE_FLT_FN (BUILT_IN_ROUND):
7163         CASE_FLT_FN (BUILT_IN_TRUNC):
7164           return true;
7165
7166         CASE_FLT_FN (BUILT_IN_FMIN):
7167         CASE_FLT_FN (BUILT_IN_FMAX):
7168           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7169             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7170
7171         default:
7172           break;
7173         }
7174       break;
7175
7176     default:
7177       break;
7178     }
7179   return false;
7180 }
7181
7182 /* FNDECL is assumed to be a builtin where truncation can be propagated
7183    across (for instance floor((double)f) == (double)floorf (f).
7184    Do the transformation for a call with argument ARG.  */
7185
7186 static tree
7187 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7188 {
7189   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7190
7191   if (!validate_arg (arg, REAL_TYPE))
7192     return NULL_TREE;
7193
7194   /* Integer rounding functions are idempotent.  */
7195   if (fcode == builtin_mathfn_code (arg))
7196     return arg;
7197
7198   /* If argument is already integer valued, and we don't need to worry
7199      about setting errno, there's no need to perform rounding.  */
7200   if (! flag_errno_math && integer_valued_real_p (arg))
7201     return arg;
7202
7203   if (optimize)
7204     {
7205       tree arg0 = strip_float_extensions (arg);
7206       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7207       tree newtype = TREE_TYPE (arg0);
7208       tree decl;
7209
7210       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7211           && (decl = mathfn_built_in (newtype, fcode)))
7212         return fold_convert_loc (loc, ftype,
7213                                  build_call_expr_loc (loc, decl, 1,
7214                                                   fold_convert_loc (loc,
7215                                                                     newtype,
7216                                                                     arg0)));
7217     }
7218   return NULL_TREE;
7219 }
7220
7221 /* FNDECL is assumed to be builtin which can narrow the FP type of
7222    the argument, for instance lround((double)f) -> lroundf (f).
7223    Do the transformation for a call with argument ARG.  */
7224
7225 static tree
7226 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7227 {
7228   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7229
7230   if (!validate_arg (arg, REAL_TYPE))
7231     return NULL_TREE;
7232
7233   /* If argument is already integer valued, and we don't need to worry
7234      about setting errno, there's no need to perform rounding.  */
7235   if (! flag_errno_math && integer_valued_real_p (arg))
7236     return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7237                         TREE_TYPE (TREE_TYPE (fndecl)), arg);
7238
7239   if (optimize)
7240     {
7241       tree ftype = TREE_TYPE (arg);
7242       tree arg0 = strip_float_extensions (arg);
7243       tree newtype = TREE_TYPE (arg0);
7244       tree decl;
7245
7246       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7247           && (decl = mathfn_built_in (newtype, fcode)))
7248         return build_call_expr_loc (loc, decl, 1,
7249                                 fold_convert_loc (loc, newtype, arg0));
7250     }
7251
7252   /* Canonicalize iround (x) to lround (x) on ILP32 targets where
7253      sizeof (int) == sizeof (long).  */
7254   if (TYPE_PRECISION (integer_type_node)
7255       == TYPE_PRECISION (long_integer_type_node))
7256     {
7257       tree newfn = NULL_TREE;
7258       switch (fcode)
7259         {
7260         CASE_FLT_FN (BUILT_IN_ICEIL):
7261           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7262           break;
7263
7264         CASE_FLT_FN (BUILT_IN_IFLOOR):
7265           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7266           break;
7267
7268         CASE_FLT_FN (BUILT_IN_IROUND):
7269           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7270           break;
7271
7272         CASE_FLT_FN (BUILT_IN_IRINT):
7273           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7274           break;
7275
7276         default:
7277           break;
7278         }
7279
7280       if (newfn)
7281         {
7282           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7283           return fold_convert_loc (loc,
7284                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7285         }
7286     }
7287
7288   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7289      sizeof (long long) == sizeof (long).  */
7290   if (TYPE_PRECISION (long_long_integer_type_node)
7291       == TYPE_PRECISION (long_integer_type_node))
7292     {
7293       tree newfn = NULL_TREE;
7294       switch (fcode)
7295         {
7296         CASE_FLT_FN (BUILT_IN_LLCEIL):
7297           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7298           break;
7299
7300         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7301           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7302           break;
7303
7304         CASE_FLT_FN (BUILT_IN_LLROUND):
7305           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7306           break;
7307
7308         CASE_FLT_FN (BUILT_IN_LLRINT):
7309           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7310           break;
7311
7312         default:
7313           break;
7314         }
7315
7316       if (newfn)
7317         {
7318           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7319           return fold_convert_loc (loc,
7320                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7321         }
7322     }
7323
7324   return NULL_TREE;
7325 }
7326
7327 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7328    return type.  Return NULL_TREE if no simplification can be made.  */
7329
7330 static tree
7331 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7332 {
7333   tree res;
7334
7335   if (!validate_arg (arg, COMPLEX_TYPE)
7336       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7337     return NULL_TREE;
7338
7339   /* Calculate the result when the argument is a constant.  */
7340   if (TREE_CODE (arg) == COMPLEX_CST
7341       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7342                               type, mpfr_hypot)))
7343     return res;
7344
7345   if (TREE_CODE (arg) == COMPLEX_EXPR)
7346     {
7347       tree real = TREE_OPERAND (arg, 0);
7348       tree imag = TREE_OPERAND (arg, 1);
7349
7350       /* If either part is zero, cabs is fabs of the other.  */
7351       if (real_zerop (real))
7352         return fold_build1_loc (loc, ABS_EXPR, type, imag);
7353       if (real_zerop (imag))
7354         return fold_build1_loc (loc, ABS_EXPR, type, real);
7355
7356       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7357       if (flag_unsafe_math_optimizations
7358           && operand_equal_p (real, imag, OEP_PURE_SAME))
7359         {
7360           const REAL_VALUE_TYPE sqrt2_trunc
7361             = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7362           STRIP_NOPS (real);
7363           return fold_build2_loc (loc, MULT_EXPR, type,
7364                               fold_build1_loc (loc, ABS_EXPR, type, real),
7365                               build_real (type, sqrt2_trunc));
7366         }
7367     }
7368
7369   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7370   if (TREE_CODE (arg) == NEGATE_EXPR
7371       || TREE_CODE (arg) == CONJ_EXPR)
7372     return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7373
7374   /* Don't do this when optimizing for size.  */
7375   if (flag_unsafe_math_optimizations
7376       && optimize && optimize_function_for_speed_p (cfun))
7377     {
7378       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7379
7380       if (sqrtfn != NULL_TREE)
7381         {
7382           tree rpart, ipart, result;
7383
7384           arg = builtin_save_expr (arg);
7385
7386           rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7387           ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7388
7389           rpart = builtin_save_expr (rpart);
7390           ipart = builtin_save_expr (ipart);
7391
7392           result = fold_build2_loc (loc, PLUS_EXPR, type,
7393                                 fold_build2_loc (loc, MULT_EXPR, type,
7394                                              rpart, rpart),
7395                                 fold_build2_loc (loc, MULT_EXPR, type,
7396                                              ipart, ipart));
7397
7398           return build_call_expr_loc (loc, sqrtfn, 1, result);
7399         }
7400     }
7401
7402   return NULL_TREE;
7403 }
7404
7405 /* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
7406    complex tree type of the result.  If NEG is true, the imaginary
7407    zero is negative.  */
7408
7409 static tree
7410 build_complex_cproj (tree type, bool neg)
7411 {
7412   REAL_VALUE_TYPE rinf, rzero = dconst0;
7413   
7414   real_inf (&rinf);
7415   rzero.sign = neg;
7416   return build_complex (type, build_real (TREE_TYPE (type), rinf),
7417                         build_real (TREE_TYPE (type), rzero));
7418 }
7419
7420 /* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
7421    return type.  Return NULL_TREE if no simplification can be made.  */
7422
7423 static tree
7424 fold_builtin_cproj (location_t loc, tree arg, tree type)
7425 {
7426   if (!validate_arg (arg, COMPLEX_TYPE)
7427       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7428     return NULL_TREE;
7429
7430   /* If there are no infinities, return arg.  */
7431   if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
7432     return non_lvalue_loc (loc, arg);
7433
7434   /* Calculate the result when the argument is a constant.  */
7435   if (TREE_CODE (arg) == COMPLEX_CST)
7436     {
7437       const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
7438       const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
7439       
7440       if (real_isinf (real) || real_isinf (imag))
7441         return build_complex_cproj (type, imag->sign);
7442       else
7443         return arg;
7444     }
7445   else if (TREE_CODE (arg) == COMPLEX_EXPR)
7446     {
7447       tree real = TREE_OPERAND (arg, 0);
7448       tree imag = TREE_OPERAND (arg, 1);
7449
7450       STRIP_NOPS (real);
7451       STRIP_NOPS (imag);
7452       
7453       /* If the real part is inf and the imag part is known to be
7454          nonnegative, return (inf + 0i).  Remember side-effects are
7455          possible in the imag part.  */
7456       if (TREE_CODE (real) == REAL_CST
7457           && real_isinf (TREE_REAL_CST_PTR (real))
7458           && tree_expr_nonnegative_p (imag))
7459         return omit_one_operand_loc (loc, type,
7460                                      build_complex_cproj (type, false),
7461                                      arg);
7462       
7463       /* If the imag part is inf, return (inf+I*copysign(0,imag)).
7464          Remember side-effects are possible in the real part.  */
7465       if (TREE_CODE (imag) == REAL_CST
7466           && real_isinf (TREE_REAL_CST_PTR (imag)))
7467         return
7468           omit_one_operand_loc (loc, type,
7469                                 build_complex_cproj (type, TREE_REAL_CST_PTR
7470                                                      (imag)->sign), arg);
7471     }
7472
7473   return NULL_TREE;
7474 }
7475
7476 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7477    Return NULL_TREE if no simplification can be made.  */
7478
7479 static tree
7480 fold_builtin_sqrt (location_t loc, tree arg, tree type)
7481 {
7482
7483   enum built_in_function fcode;
7484   tree res;
7485
7486   if (!validate_arg (arg, REAL_TYPE))
7487     return NULL_TREE;
7488
7489   /* Calculate the result when the argument is a constant.  */
7490   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7491     return res;
7492
7493   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7494   fcode = builtin_mathfn_code (arg);
7495   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7496     {
7497       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7498       arg = fold_build2_loc (loc, MULT_EXPR, type,
7499                          CALL_EXPR_ARG (arg, 0),
7500                          build_real (type, dconsthalf));
7501       return build_call_expr_loc (loc, expfn, 1, arg);
7502     }
7503
7504   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7505   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7506     {
7507       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7508
7509       if (powfn)
7510         {
7511           tree arg0 = CALL_EXPR_ARG (arg, 0);
7512           tree tree_root;
7513           /* The inner root was either sqrt or cbrt.  */
7514           /* This was a conditional expression but it triggered a bug
7515              in Sun C 5.5.  */
7516           REAL_VALUE_TYPE dconstroot;
7517           if (BUILTIN_SQRT_P (fcode))
7518             dconstroot = dconsthalf;
7519           else
7520             dconstroot = dconst_third ();
7521
7522           /* Adjust for the outer root.  */
7523           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7524           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7525           tree_root = build_real (type, dconstroot);
7526           return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7527         }
7528     }
7529
7530   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7531   if (flag_unsafe_math_optimizations
7532       && (fcode == BUILT_IN_POW
7533           || fcode == BUILT_IN_POWF
7534           || fcode == BUILT_IN_POWL))
7535     {
7536       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7537       tree arg0 = CALL_EXPR_ARG (arg, 0);
7538       tree arg1 = CALL_EXPR_ARG (arg, 1);
7539       tree narg1;
7540       if (!tree_expr_nonnegative_p (arg0))
7541         arg0 = build1 (ABS_EXPR, type, arg0);
7542       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7543                            build_real (type, dconsthalf));
7544       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7545     }
7546
7547   return NULL_TREE;
7548 }
7549
7550 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7551    Return NULL_TREE if no simplification can be made.  */
7552
7553 static tree
7554 fold_builtin_cbrt (location_t loc, tree arg, tree type)
7555 {
7556   const enum built_in_function fcode = builtin_mathfn_code (arg);
7557   tree res;
7558
7559   if (!validate_arg (arg, REAL_TYPE))
7560     return NULL_TREE;
7561
7562   /* Calculate the result when the argument is a constant.  */
7563   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7564     return res;
7565
7566   if (flag_unsafe_math_optimizations)
7567     {
7568       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7569       if (BUILTIN_EXPONENT_P (fcode))
7570         {
7571           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7572           const REAL_VALUE_TYPE third_trunc =
7573             real_value_truncate (TYPE_MODE (type), dconst_third ());
7574           arg = fold_build2_loc (loc, MULT_EXPR, type,
7575                              CALL_EXPR_ARG (arg, 0),
7576                              build_real (type, third_trunc));
7577           return build_call_expr_loc (loc, expfn, 1, arg);
7578         }
7579
7580       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7581       if (BUILTIN_SQRT_P (fcode))
7582         {
7583           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7584
7585           if (powfn)
7586             {
7587               tree arg0 = CALL_EXPR_ARG (arg, 0);
7588               tree tree_root;
7589               REAL_VALUE_TYPE dconstroot = dconst_third ();
7590
7591               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7592               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7593               tree_root = build_real (type, dconstroot);
7594               return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7595             }
7596         }
7597
7598       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7599       if (BUILTIN_CBRT_P (fcode))
7600         {
7601           tree arg0 = CALL_EXPR_ARG (arg, 0);
7602           if (tree_expr_nonnegative_p (arg0))
7603             {
7604               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7605
7606               if (powfn)
7607                 {
7608                   tree tree_root;
7609                   REAL_VALUE_TYPE dconstroot;
7610
7611                   real_arithmetic (&dconstroot, MULT_EXPR,
7612                                    dconst_third_ptr (), dconst_third_ptr ());
7613                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7614                   tree_root = build_real (type, dconstroot);
7615                   return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7616                 }
7617             }
7618         }
7619
7620       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7621       if (fcode == BUILT_IN_POW
7622           || fcode == BUILT_IN_POWF
7623           || fcode == BUILT_IN_POWL)
7624         {
7625           tree arg00 = CALL_EXPR_ARG (arg, 0);
7626           tree arg01 = CALL_EXPR_ARG (arg, 1);
7627           if (tree_expr_nonnegative_p (arg00))
7628             {
7629               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7630               const REAL_VALUE_TYPE dconstroot
7631                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7632               tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7633                                          build_real (type, dconstroot));
7634               return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7635             }
7636         }
7637     }
7638   return NULL_TREE;
7639 }
7640
7641 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7642    TYPE is the type of the return value.  Return NULL_TREE if no
7643    simplification can be made.  */
7644
7645 static tree
7646 fold_builtin_cos (location_t loc,
7647                   tree arg, tree type, tree fndecl)
7648 {
7649   tree res, narg;
7650
7651   if (!validate_arg (arg, REAL_TYPE))
7652     return NULL_TREE;
7653
7654   /* Calculate the result when the argument is a constant.  */
7655   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7656     return res;
7657
7658   /* Optimize cos(-x) into cos (x).  */
7659   if ((narg = fold_strip_sign_ops (arg)))
7660     return build_call_expr_loc (loc, fndecl, 1, narg);
7661
7662   return NULL_TREE;
7663 }
7664
7665 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7666    Return NULL_TREE if no simplification can be made.  */
7667
7668 static tree
7669 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7670 {
7671   if (validate_arg (arg, REAL_TYPE))
7672     {
7673       tree res, narg;
7674
7675       /* Calculate the result when the argument is a constant.  */
7676       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7677         return res;
7678
7679       /* Optimize cosh(-x) into cosh (x).  */
7680       if ((narg = fold_strip_sign_ops (arg)))
7681         return build_call_expr_loc (loc, fndecl, 1, narg);
7682     }
7683
7684   return NULL_TREE;
7685 }
7686
7687 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7688    argument ARG.  TYPE is the type of the return value.  Return
7689    NULL_TREE if no simplification can be made.  */
7690
7691 static tree
7692 fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl,
7693                    bool hyper)
7694 {
7695   if (validate_arg (arg, COMPLEX_TYPE)
7696       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7697     {
7698       tree tmp;
7699
7700       /* Calculate the result when the argument is a constant.  */
7701       if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7702         return tmp;
7703
7704       /* Optimize fn(-x) into fn(x).  */
7705       if ((tmp = fold_strip_sign_ops (arg)))
7706         return build_call_expr_loc (loc, fndecl, 1, tmp);
7707     }
7708
7709   return NULL_TREE;
7710 }
7711
7712 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7713    Return NULL_TREE if no simplification can be made.  */
7714
7715 static tree
7716 fold_builtin_tan (tree arg, tree type)
7717 {
7718   enum built_in_function fcode;
7719   tree res;
7720
7721   if (!validate_arg (arg, REAL_TYPE))
7722     return NULL_TREE;
7723
7724   /* Calculate the result when the argument is a constant.  */
7725   if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7726     return res;
7727
7728   /* Optimize tan(atan(x)) = x.  */
7729   fcode = builtin_mathfn_code (arg);
7730   if (flag_unsafe_math_optimizations
7731       && (fcode == BUILT_IN_ATAN
7732           || fcode == BUILT_IN_ATANF
7733           || fcode == BUILT_IN_ATANL))
7734     return CALL_EXPR_ARG (arg, 0);
7735
7736   return NULL_TREE;
7737 }
7738
7739 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7740    NULL_TREE if no simplification can be made.  */
7741
7742 static tree
7743 fold_builtin_sincos (location_t loc,
7744                      tree arg0, tree arg1, tree arg2)
7745 {
7746   tree type;
7747   tree res, fn, call;
7748
7749   if (!validate_arg (arg0, REAL_TYPE)
7750       || !validate_arg (arg1, POINTER_TYPE)
7751       || !validate_arg (arg2, POINTER_TYPE))
7752     return NULL_TREE;
7753
7754   type = TREE_TYPE (arg0);
7755
7756   /* Calculate the result when the argument is a constant.  */
7757   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7758     return res;
7759
7760   /* Canonicalize sincos to cexpi.  */
7761   if (!TARGET_C99_FUNCTIONS)
7762     return NULL_TREE;
7763   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7764   if (!fn)
7765     return NULL_TREE;
7766
7767   call = build_call_expr_loc (loc, fn, 1, arg0);
7768   call = builtin_save_expr (call);
7769
7770   return build2 (COMPOUND_EXPR, void_type_node,
7771                  build2 (MODIFY_EXPR, void_type_node,
7772                          build_fold_indirect_ref_loc (loc, arg1),
7773                          build1 (IMAGPART_EXPR, type, call)),
7774                  build2 (MODIFY_EXPR, void_type_node,
7775                          build_fold_indirect_ref_loc (loc, arg2),
7776                          build1 (REALPART_EXPR, type, call)));
7777 }
7778
7779 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7780    NULL_TREE if no simplification can be made.  */
7781
7782 static tree
7783 fold_builtin_cexp (location_t loc, tree arg0, tree type)
7784 {
7785   tree rtype;
7786   tree realp, imagp, ifn;
7787   tree res;
7788
7789   if (!validate_arg (arg0, COMPLEX_TYPE)
7790       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7791     return NULL_TREE;
7792
7793   /* Calculate the result when the argument is a constant.  */
7794   if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7795     return res;
7796
7797   rtype = TREE_TYPE (TREE_TYPE (arg0));
7798
7799   /* In case we can figure out the real part of arg0 and it is constant zero
7800      fold to cexpi.  */
7801   if (!TARGET_C99_FUNCTIONS)
7802     return NULL_TREE;
7803   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7804   if (!ifn)
7805     return NULL_TREE;
7806
7807   if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7808       && real_zerop (realp))
7809     {
7810       tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7811       return build_call_expr_loc (loc, ifn, 1, narg);
7812     }
7813
7814   /* In case we can easily decompose real and imaginary parts split cexp
7815      to exp (r) * cexpi (i).  */
7816   if (flag_unsafe_math_optimizations
7817       && realp)
7818     {
7819       tree rfn, rcall, icall;
7820
7821       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7822       if (!rfn)
7823         return NULL_TREE;
7824
7825       imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7826       if (!imagp)
7827         return NULL_TREE;
7828
7829       icall = build_call_expr_loc (loc, ifn, 1, imagp);
7830       icall = builtin_save_expr (icall);
7831       rcall = build_call_expr_loc (loc, rfn, 1, realp);
7832       rcall = builtin_save_expr (rcall);
7833       return fold_build2_loc (loc, COMPLEX_EXPR, type,
7834                           fold_build2_loc (loc, MULT_EXPR, rtype,
7835                                        rcall,
7836                                        fold_build1_loc (loc, REALPART_EXPR,
7837                                                     rtype, icall)),
7838                           fold_build2_loc (loc, MULT_EXPR, rtype,
7839                                        rcall,
7840                                        fold_build1_loc (loc, IMAGPART_EXPR,
7841                                                     rtype, icall)));
7842     }
7843
7844   return NULL_TREE;
7845 }
7846
7847 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7848    Return NULL_TREE if no simplification can be made.  */
7849
7850 static tree
7851 fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7852 {
7853   if (!validate_arg (arg, REAL_TYPE))
7854     return NULL_TREE;
7855
7856   /* Optimize trunc of constant value.  */
7857   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7858     {
7859       REAL_VALUE_TYPE r, x;
7860       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7861
7862       x = TREE_REAL_CST (arg);
7863       real_trunc (&r, TYPE_MODE (type), &x);
7864       return build_real (type, r);
7865     }
7866
7867   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7868 }
7869
7870 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7871    Return NULL_TREE if no simplification can be made.  */
7872
7873 static tree
7874 fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7875 {
7876   if (!validate_arg (arg, REAL_TYPE))
7877     return NULL_TREE;
7878
7879   /* Optimize floor of constant value.  */
7880   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7881     {
7882       REAL_VALUE_TYPE x;
7883
7884       x = TREE_REAL_CST (arg);
7885       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7886         {
7887           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7888           REAL_VALUE_TYPE r;
7889
7890           real_floor (&r, TYPE_MODE (type), &x);
7891           return build_real (type, r);
7892         }
7893     }
7894
7895   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7896   if (tree_expr_nonnegative_p (arg))
7897     {
7898       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7899       if (truncfn)
7900         return build_call_expr_loc (loc, truncfn, 1, arg);
7901     }
7902
7903   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7904 }
7905
7906 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7907    Return NULL_TREE if no simplification can be made.  */
7908
7909 static tree
7910 fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7911 {
7912   if (!validate_arg (arg, REAL_TYPE))
7913     return NULL_TREE;
7914
7915   /* Optimize ceil of constant value.  */
7916   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7917     {
7918       REAL_VALUE_TYPE x;
7919
7920       x = TREE_REAL_CST (arg);
7921       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7922         {
7923           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7924           REAL_VALUE_TYPE r;
7925
7926           real_ceil (&r, TYPE_MODE (type), &x);
7927           return build_real (type, r);
7928         }
7929     }
7930
7931   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7932 }
7933
7934 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7935    Return NULL_TREE if no simplification can be made.  */
7936
7937 static tree
7938 fold_builtin_round (location_t loc, tree fndecl, tree arg)
7939 {
7940   if (!validate_arg (arg, REAL_TYPE))
7941     return NULL_TREE;
7942
7943   /* Optimize round of constant value.  */
7944   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7945     {
7946       REAL_VALUE_TYPE x;
7947
7948       x = TREE_REAL_CST (arg);
7949       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7950         {
7951           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7952           REAL_VALUE_TYPE r;
7953
7954           real_round (&r, TYPE_MODE (type), &x);
7955           return build_real (type, r);
7956         }
7957     }
7958
7959   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7960 }
7961
7962 /* Fold function call to builtin lround, lroundf or lroundl (or the
7963    corresponding long long versions) and other rounding functions.  ARG
7964    is the argument to the call.  Return NULL_TREE if no simplification
7965    can be made.  */
7966
7967 static tree
7968 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
7969 {
7970   if (!validate_arg (arg, REAL_TYPE))
7971     return NULL_TREE;
7972
7973   /* Optimize lround of constant value.  */
7974   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7975     {
7976       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7977
7978       if (real_isfinite (&x))
7979         {
7980           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7981           tree ftype = TREE_TYPE (arg);
7982           double_int val;
7983           REAL_VALUE_TYPE r;
7984
7985           switch (DECL_FUNCTION_CODE (fndecl))
7986             {
7987             CASE_FLT_FN (BUILT_IN_IFLOOR):
7988             CASE_FLT_FN (BUILT_IN_LFLOOR):
7989             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7990               real_floor (&r, TYPE_MODE (ftype), &x);
7991               break;
7992
7993             CASE_FLT_FN (BUILT_IN_ICEIL):
7994             CASE_FLT_FN (BUILT_IN_LCEIL):
7995             CASE_FLT_FN (BUILT_IN_LLCEIL):
7996               real_ceil (&r, TYPE_MODE (ftype), &x);
7997               break;
7998
7999             CASE_FLT_FN (BUILT_IN_IROUND):
8000             CASE_FLT_FN (BUILT_IN_LROUND):
8001             CASE_FLT_FN (BUILT_IN_LLROUND):
8002               real_round (&r, TYPE_MODE (ftype), &x);
8003               break;
8004
8005             default:
8006               gcc_unreachable ();
8007             }
8008
8009           real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
8010           if (double_int_fits_to_tree_p (itype, val))
8011             return double_int_to_tree (itype, val);
8012         }
8013     }
8014
8015   switch (DECL_FUNCTION_CODE (fndecl))
8016     {
8017     CASE_FLT_FN (BUILT_IN_LFLOOR):
8018     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8019       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8020       if (tree_expr_nonnegative_p (arg))
8021         return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8022                             TREE_TYPE (TREE_TYPE (fndecl)), arg);
8023       break;
8024     default:;
8025     }
8026
8027   return fold_fixed_mathfn (loc, fndecl, arg);
8028 }
8029
8030 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8031    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8032    the argument to the call.  Return NULL_TREE if no simplification can
8033    be made.  */
8034
8035 static tree
8036 fold_builtin_bitop (tree fndecl, tree arg)
8037 {
8038   if (!validate_arg (arg, INTEGER_TYPE))
8039     return NULL_TREE;
8040
8041   /* Optimize for constant argument.  */
8042   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8043     {
8044       HOST_WIDE_INT hi, width, result;
8045       unsigned HOST_WIDE_INT lo;
8046       tree type;
8047
8048       type = TREE_TYPE (arg);
8049       width = TYPE_PRECISION (type);
8050       lo = TREE_INT_CST_LOW (arg);
8051
8052       /* Clear all the bits that are beyond the type's precision.  */
8053       if (width > HOST_BITS_PER_WIDE_INT)
8054         {
8055           hi = TREE_INT_CST_HIGH (arg);
8056           if (width < 2 * HOST_BITS_PER_WIDE_INT)
8057             hi &= ~((unsigned HOST_WIDE_INT) (-1)
8058                     << (width - HOST_BITS_PER_WIDE_INT));
8059         }
8060       else
8061         {
8062           hi = 0;
8063           if (width < HOST_BITS_PER_WIDE_INT)
8064             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8065         }
8066
8067       switch (DECL_FUNCTION_CODE (fndecl))
8068         {
8069         CASE_INT_FN (BUILT_IN_FFS):
8070           if (lo != 0)
8071             result = ffs_hwi (lo);
8072           else if (hi != 0)
8073             result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
8074           else
8075             result = 0;
8076           break;
8077
8078         CASE_INT_FN (BUILT_IN_CLZ):
8079           if (hi != 0)
8080             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8081           else if (lo != 0)
8082             result = width - floor_log2 (lo) - 1;
8083           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8084             result = width;
8085           break;
8086
8087         CASE_INT_FN (BUILT_IN_CTZ):
8088           if (lo != 0)
8089             result = ctz_hwi (lo);
8090           else if (hi != 0)
8091             result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
8092           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8093             result = width;
8094           break;
8095
8096         CASE_INT_FN (BUILT_IN_CLRSB):
8097           if (width > HOST_BITS_PER_WIDE_INT
8098               && (hi & ((unsigned HOST_WIDE_INT) 1
8099                         << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
8100             {
8101               hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
8102                            << (width - HOST_BITS_PER_WIDE_INT - 1));
8103               lo = ~lo;
8104             }
8105           else if (width <= HOST_BITS_PER_WIDE_INT
8106                    && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
8107             lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
8108           if (hi != 0)
8109             result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
8110           else if (lo != 0)
8111             result = width - floor_log2 (lo) - 2;
8112           else
8113             result = width - 1;
8114           break;
8115
8116         CASE_INT_FN (BUILT_IN_POPCOUNT):
8117           result = 0;
8118           while (lo)
8119             result++, lo &= lo - 1;
8120           while (hi)
8121             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8122           break;
8123
8124         CASE_INT_FN (BUILT_IN_PARITY):
8125           result = 0;
8126           while (lo)
8127             result++, lo &= lo - 1;
8128           while (hi)
8129             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8130           result &= 1;
8131           break;
8132
8133         default:
8134           gcc_unreachable ();
8135         }
8136
8137       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8138     }
8139
8140   return NULL_TREE;
8141 }
8142
8143 /* Fold function call to builtin_bswap and the long and long long
8144    variants.  Return NULL_TREE if no simplification can be made.  */
8145 static tree
8146 fold_builtin_bswap (tree fndecl, tree arg)
8147 {
8148   if (! validate_arg (arg, INTEGER_TYPE))
8149     return NULL_TREE;
8150
8151   /* Optimize constant value.  */
8152   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8153     {
8154       HOST_WIDE_INT hi, width, r_hi = 0;
8155       unsigned HOST_WIDE_INT lo, r_lo = 0;
8156       tree type;
8157
8158       type = TREE_TYPE (arg);
8159       width = TYPE_PRECISION (type);
8160       lo = TREE_INT_CST_LOW (arg);
8161       hi = TREE_INT_CST_HIGH (arg);
8162
8163       switch (DECL_FUNCTION_CODE (fndecl))
8164         {
8165           case BUILT_IN_BSWAP32:
8166           case BUILT_IN_BSWAP64:
8167             {
8168               int s;
8169
8170               for (s = 0; s < width; s += 8)
8171                 {
8172                   int d = width - s - 8;
8173                   unsigned HOST_WIDE_INT byte;
8174
8175                   if (s < HOST_BITS_PER_WIDE_INT)
8176                     byte = (lo >> s) & 0xff;
8177                   else
8178                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8179
8180                   if (d < HOST_BITS_PER_WIDE_INT)
8181                     r_lo |= byte << d;
8182                   else
8183                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8184                 }
8185             }
8186
8187             break;
8188
8189         default:
8190           gcc_unreachable ();
8191         }
8192
8193       if (width < HOST_BITS_PER_WIDE_INT)
8194         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8195       else
8196         return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8197     }
8198
8199   return NULL_TREE;
8200 }
8201
8202 /* A subroutine of fold_builtin to fold the various logarithmic
8203    functions.  Return NULL_TREE if no simplification can me made.
8204    FUNC is the corresponding MPFR logarithm function.  */
8205
8206 static tree
8207 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
8208                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8209 {
8210   if (validate_arg (arg, REAL_TYPE))
8211     {
8212       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8213       tree res;
8214       const enum built_in_function fcode = builtin_mathfn_code (arg);
8215
8216       /* Calculate the result when the argument is a constant.  */
8217       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8218         return res;
8219
8220       /* Special case, optimize logN(expN(x)) = x.  */
8221       if (flag_unsafe_math_optimizations
8222           && ((func == mpfr_log
8223                && (fcode == BUILT_IN_EXP
8224                    || fcode == BUILT_IN_EXPF
8225                    || fcode == BUILT_IN_EXPL))
8226               || (func == mpfr_log2
8227                   && (fcode == BUILT_IN_EXP2
8228                       || fcode == BUILT_IN_EXP2F
8229                       || fcode == BUILT_IN_EXP2L))
8230               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8231         return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8232
8233       /* Optimize logN(func()) for various exponential functions.  We
8234          want to determine the value "x" and the power "exponent" in
8235          order to transform logN(x**exponent) into exponent*logN(x).  */
8236       if (flag_unsafe_math_optimizations)
8237         {
8238           tree exponent = 0, x = 0;
8239
8240           switch (fcode)
8241           {
8242           CASE_FLT_FN (BUILT_IN_EXP):
8243             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8244             x = build_real (type, real_value_truncate (TYPE_MODE (type),
8245                                                        dconst_e ()));
8246             exponent = CALL_EXPR_ARG (arg, 0);
8247             break;
8248           CASE_FLT_FN (BUILT_IN_EXP2):
8249             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8250             x = build_real (type, dconst2);
8251             exponent = CALL_EXPR_ARG (arg, 0);
8252             break;
8253           CASE_FLT_FN (BUILT_IN_EXP10):
8254           CASE_FLT_FN (BUILT_IN_POW10):
8255             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8256             {
8257               REAL_VALUE_TYPE dconst10;
8258               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8259               x = build_real (type, dconst10);
8260             }
8261             exponent = CALL_EXPR_ARG (arg, 0);
8262             break;
8263           CASE_FLT_FN (BUILT_IN_SQRT):
8264             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8265             x = CALL_EXPR_ARG (arg, 0);
8266             exponent = build_real (type, dconsthalf);
8267             break;
8268           CASE_FLT_FN (BUILT_IN_CBRT):
8269             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8270             x = CALL_EXPR_ARG (arg, 0);
8271             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8272                                                               dconst_third ()));
8273             break;
8274           CASE_FLT_FN (BUILT_IN_POW):
8275             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8276             x = CALL_EXPR_ARG (arg, 0);
8277             exponent = CALL_EXPR_ARG (arg, 1);
8278             break;
8279           default:
8280             break;
8281           }
8282
8283           /* Now perform the optimization.  */
8284           if (x && exponent)
8285             {
8286               tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8287               return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8288             }
8289         }
8290     }
8291
8292   return NULL_TREE;
8293 }
8294
8295 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8296    NULL_TREE if no simplification can be made.  */
8297
8298 static tree
8299 fold_builtin_hypot (location_t loc, tree fndecl,
8300                     tree arg0, tree arg1, tree type)
8301 {
8302   tree res, narg0, narg1;
8303
8304   if (!validate_arg (arg0, REAL_TYPE)
8305       || !validate_arg (arg1, REAL_TYPE))
8306     return NULL_TREE;
8307
8308   /* Calculate the result when the argument is a constant.  */
8309   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8310     return res;
8311
8312   /* If either argument to hypot has a negate or abs, strip that off.
8313      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8314   narg0 = fold_strip_sign_ops (arg0);
8315   narg1 = fold_strip_sign_ops (arg1);
8316   if (narg0 || narg1)
8317     {
8318       return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
8319                               narg1 ? narg1 : arg1);
8320     }
8321
8322   /* If either argument is zero, hypot is fabs of the other.  */
8323   if (real_zerop (arg0))
8324     return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8325   else if (real_zerop (arg1))
8326     return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8327
8328   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8329   if (flag_unsafe_math_optimizations
8330       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8331     {
8332       const REAL_VALUE_TYPE sqrt2_trunc
8333         = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8334       return fold_build2_loc (loc, MULT_EXPR, type,
8335                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
8336                           build_real (type, sqrt2_trunc));
8337     }
8338
8339   return NULL_TREE;
8340 }
8341
8342
8343 /* Fold a builtin function call to pow, powf, or powl.  Return
8344    NULL_TREE if no simplification can be made.  */
8345 static tree
8346 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8347 {
8348   tree res;
8349
8350   if (!validate_arg (arg0, REAL_TYPE)
8351        || !validate_arg (arg1, REAL_TYPE))
8352     return NULL_TREE;
8353
8354   /* Calculate the result when the argument is a constant.  */
8355   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8356     return res;
8357
8358   /* Optimize pow(1.0,y) = 1.0.  */
8359   if (real_onep (arg0))
8360     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8361
8362   if (TREE_CODE (arg1) == REAL_CST
8363       && !TREE_OVERFLOW (arg1))
8364     {
8365       REAL_VALUE_TYPE cint;
8366       REAL_VALUE_TYPE c;
8367       HOST_WIDE_INT n;
8368
8369       c = TREE_REAL_CST (arg1);
8370
8371       /* Optimize pow(x,0.0) = 1.0.  */
8372       if (REAL_VALUES_EQUAL (c, dconst0))
8373         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8374                                  arg0);
8375
8376       /* Optimize pow(x,1.0) = x.  */
8377       if (REAL_VALUES_EQUAL (c, dconst1))
8378         return arg0;
8379
8380       /* Optimize pow(x,-1.0) = 1.0/x.  */
8381       if (REAL_VALUES_EQUAL (c, dconstm1))
8382         return fold_build2_loc (loc, RDIV_EXPR, type,
8383                             build_real (type, dconst1), arg0);
8384
8385       /* Optimize pow(x,0.5) = sqrt(x).  */
8386       if (flag_unsafe_math_optimizations
8387           && REAL_VALUES_EQUAL (c, dconsthalf))
8388         {
8389           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8390
8391           if (sqrtfn != NULL_TREE)
8392             return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8393         }
8394
8395       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8396       if (flag_unsafe_math_optimizations)
8397         {
8398           const REAL_VALUE_TYPE dconstroot
8399             = real_value_truncate (TYPE_MODE (type), dconst_third ());
8400
8401           if (REAL_VALUES_EQUAL (c, dconstroot))
8402             {
8403               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8404               if (cbrtfn != NULL_TREE)
8405                 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8406             }
8407         }
8408
8409       /* Check for an integer exponent.  */
8410       n = real_to_integer (&c);
8411       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8412       if (real_identical (&c, &cint))
8413         {
8414           /* Attempt to evaluate pow at compile-time, unless this should
8415              raise an exception.  */
8416           if (TREE_CODE (arg0) == REAL_CST
8417               && !TREE_OVERFLOW (arg0)
8418               && (n > 0
8419                   || (!flag_trapping_math && !flag_errno_math)
8420                   || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8421             {
8422               REAL_VALUE_TYPE x;
8423               bool inexact;
8424
8425               x = TREE_REAL_CST (arg0);
8426               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8427               if (flag_unsafe_math_optimizations || !inexact)
8428                 return build_real (type, x);
8429             }
8430
8431           /* Strip sign ops from even integer powers.  */
8432           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8433             {
8434               tree narg0 = fold_strip_sign_ops (arg0);
8435               if (narg0)
8436                 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8437             }
8438         }
8439     }
8440
8441   if (flag_unsafe_math_optimizations)
8442     {
8443       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8444
8445       /* Optimize pow(expN(x),y) = expN(x*y).  */
8446       if (BUILTIN_EXPONENT_P (fcode))
8447         {
8448           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8449           tree arg = CALL_EXPR_ARG (arg0, 0);
8450           arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8451           return build_call_expr_loc (loc, expfn, 1, arg);
8452         }
8453
8454       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8455       if (BUILTIN_SQRT_P (fcode))
8456         {
8457           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8458           tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8459                                     build_real (type, dconsthalf));
8460           return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8461         }
8462
8463       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8464       if (BUILTIN_CBRT_P (fcode))
8465         {
8466           tree arg = CALL_EXPR_ARG (arg0, 0);
8467           if (tree_expr_nonnegative_p (arg))
8468             {
8469               const REAL_VALUE_TYPE dconstroot
8470                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8471               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8472                                         build_real (type, dconstroot));
8473               return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8474             }
8475         }
8476
8477       /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative.  */
8478       if (fcode == BUILT_IN_POW
8479           || fcode == BUILT_IN_POWF
8480           || fcode == BUILT_IN_POWL)
8481         {
8482           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8483           if (tree_expr_nonnegative_p (arg00))
8484             {
8485               tree arg01 = CALL_EXPR_ARG (arg0, 1);
8486               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8487               return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8488             }
8489         }
8490     }
8491
8492   return NULL_TREE;
8493 }
8494
8495 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8496    Return NULL_TREE if no simplification can be made.  */
8497 static tree
8498 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8499                    tree arg0, tree arg1, tree type)
8500 {
8501   if (!validate_arg (arg0, REAL_TYPE)
8502       || !validate_arg (arg1, INTEGER_TYPE))
8503     return NULL_TREE;
8504
8505   /* Optimize pow(1.0,y) = 1.0.  */
8506   if (real_onep (arg0))
8507     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8508
8509   if (host_integerp (arg1, 0))
8510     {
8511       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8512
8513       /* Evaluate powi at compile-time.  */
8514       if (TREE_CODE (arg0) == REAL_CST
8515           && !TREE_OVERFLOW (arg0))
8516         {
8517           REAL_VALUE_TYPE x;
8518           x = TREE_REAL_CST (arg0);
8519           real_powi (&x, TYPE_MODE (type), &x, c);
8520           return build_real (type, x);
8521         }
8522
8523       /* Optimize pow(x,0) = 1.0.  */
8524       if (c == 0)
8525         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8526                                  arg0);
8527
8528       /* Optimize pow(x,1) = x.  */
8529       if (c == 1)
8530         return arg0;
8531
8532       /* Optimize pow(x,-1) = 1.0/x.  */
8533       if (c == -1)
8534         return fold_build2_loc (loc, RDIV_EXPR, type,
8535                            build_real (type, dconst1), arg0);
8536     }
8537
8538   return NULL_TREE;
8539 }
8540
8541 /* A subroutine of fold_builtin to fold the various exponent
8542    functions.  Return NULL_TREE if no simplification can be made.
8543    FUNC is the corresponding MPFR exponent function.  */
8544
8545 static tree
8546 fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8547                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8548 {
8549   if (validate_arg (arg, REAL_TYPE))
8550     {
8551       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8552       tree res;
8553
8554       /* Calculate the result when the argument is a constant.  */
8555       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8556         return res;
8557
8558       /* Optimize expN(logN(x)) = x.  */
8559       if (flag_unsafe_math_optimizations)
8560         {
8561           const enum built_in_function fcode = builtin_mathfn_code (arg);
8562
8563           if ((func == mpfr_exp
8564                && (fcode == BUILT_IN_LOG
8565                    || fcode == BUILT_IN_LOGF
8566                    || fcode == BUILT_IN_LOGL))
8567               || (func == mpfr_exp2
8568                   && (fcode == BUILT_IN_LOG2
8569                       || fcode == BUILT_IN_LOG2F
8570                       || fcode == BUILT_IN_LOG2L))
8571               || (func == mpfr_exp10
8572                   && (fcode == BUILT_IN_LOG10
8573                       || fcode == BUILT_IN_LOG10F
8574                       || fcode == BUILT_IN_LOG10L)))
8575             return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8576         }
8577     }
8578
8579   return NULL_TREE;
8580 }
8581
8582 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8583
8584 static bool
8585 var_decl_component_p (tree var)
8586 {
8587   tree inner = var;
8588   while (handled_component_p (inner))
8589     inner = TREE_OPERAND (inner, 0);
8590   return SSA_VAR_P (inner);
8591 }
8592
8593 /* Fold function call to builtin memset.  Return
8594    NULL_TREE if no simplification can be made.  */
8595
8596 static tree
8597 fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8598                      tree type, bool ignore)
8599 {
8600   tree var, ret, etype;
8601   unsigned HOST_WIDE_INT length, cval;
8602
8603   if (! validate_arg (dest, POINTER_TYPE)
8604       || ! validate_arg (c, INTEGER_TYPE)
8605       || ! validate_arg (len, INTEGER_TYPE))
8606     return NULL_TREE;
8607
8608   if (! host_integerp (len, 1))
8609     return NULL_TREE;
8610
8611   /* If the LEN parameter is zero, return DEST.  */
8612   if (integer_zerop (len))
8613     return omit_one_operand_loc (loc, type, dest, c);
8614
8615   if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
8616     return NULL_TREE;
8617
8618   var = dest;
8619   STRIP_NOPS (var);
8620   if (TREE_CODE (var) != ADDR_EXPR)
8621     return NULL_TREE;
8622
8623   var = TREE_OPERAND (var, 0);
8624   if (TREE_THIS_VOLATILE (var))
8625     return NULL_TREE;
8626
8627   etype = TREE_TYPE (var);
8628   if (TREE_CODE (etype) == ARRAY_TYPE)
8629     etype = TREE_TYPE (etype);
8630
8631   if (!INTEGRAL_TYPE_P (etype)
8632       && !POINTER_TYPE_P (etype))
8633     return NULL_TREE;
8634
8635   if (! var_decl_component_p (var))
8636     return NULL_TREE;
8637
8638   length = tree_low_cst (len, 1);
8639   if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8640       || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
8641     return NULL_TREE;
8642
8643   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8644     return NULL_TREE;
8645
8646   if (integer_zerop (c))
8647     cval = 0;
8648   else
8649     {
8650       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8651         return NULL_TREE;
8652
8653       cval = TREE_INT_CST_LOW (c);
8654       cval &= 0xff;
8655       cval |= cval << 8;
8656       cval |= cval << 16;
8657       cval |= (cval << 31) << 1;
8658     }
8659
8660   ret = build_int_cst_type (etype, cval);
8661   var = build_fold_indirect_ref_loc (loc,
8662                                  fold_convert_loc (loc,
8663                                                    build_pointer_type (etype),
8664                                                    dest));
8665   ret = build2 (MODIFY_EXPR, etype, var, ret);
8666   if (ignore)
8667     return ret;
8668
8669   return omit_one_operand_loc (loc, type, dest, ret);
8670 }
8671
8672 /* Fold function call to builtin memset.  Return
8673    NULL_TREE if no simplification can be made.  */
8674
8675 static tree
8676 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8677 {
8678   if (! validate_arg (dest, POINTER_TYPE)
8679       || ! validate_arg (size, INTEGER_TYPE))
8680     return NULL_TREE;
8681
8682   if (!ignore)
8683     return NULL_TREE;
8684
8685   /* New argument list transforming bzero(ptr x, int y) to
8686      memset(ptr x, int 0, size_t y).   This is done this way
8687      so that if it isn't expanded inline, we fallback to
8688      calling bzero instead of memset.  */
8689
8690   return fold_builtin_memset (loc, dest, integer_zero_node,
8691                               fold_convert_loc (loc, size_type_node, size),
8692                               void_type_node, ignore);
8693 }
8694
8695 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8696    NULL_TREE if no simplification can be made.
8697    If ENDP is 0, return DEST (like memcpy).
8698    If ENDP is 1, return DEST+LEN (like mempcpy).
8699    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8700    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8701    (memmove).   */
8702
8703 static tree
8704 fold_builtin_memory_op (location_t loc, tree dest, tree src,
8705                         tree len, tree type, bool ignore, int endp)
8706 {
8707   tree destvar, srcvar, expr;
8708
8709   if (! validate_arg (dest, POINTER_TYPE)
8710       || ! validate_arg (src, POINTER_TYPE)
8711       || ! validate_arg (len, INTEGER_TYPE))
8712     return NULL_TREE;
8713
8714   /* If the LEN parameter is zero, return DEST.  */
8715   if (integer_zerop (len))
8716     return omit_one_operand_loc (loc, type, dest, src);
8717
8718   /* If SRC and DEST are the same (and not volatile), return
8719      DEST{,+LEN,+LEN-1}.  */
8720   if (operand_equal_p (src, dest, 0))
8721     expr = len;
8722   else
8723     {
8724       tree srctype, desttype;
8725       unsigned int src_align, dest_align;
8726       tree off0;
8727
8728       if (endp == 3)
8729         {
8730           src_align = get_pointer_alignment (src);
8731           dest_align = get_pointer_alignment (dest);
8732
8733           /* Both DEST and SRC must be pointer types.
8734              ??? This is what old code did.  Is the testing for pointer types
8735              really mandatory?
8736
8737              If either SRC is readonly or length is 1, we can use memcpy.  */
8738           if (!dest_align || !src_align)
8739             return NULL_TREE;
8740           if (readonly_data_expr (src)
8741               || (host_integerp (len, 1)
8742                   && (MIN (src_align, dest_align) / BITS_PER_UNIT
8743                       >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
8744             {
8745               tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8746               if (!fn)
8747                 return NULL_TREE;
8748               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8749             }
8750
8751           /* If *src and *dest can't overlap, optimize into memcpy as well.  */
8752           if (TREE_CODE (src) == ADDR_EXPR
8753               && TREE_CODE (dest) == ADDR_EXPR)
8754             {
8755               tree src_base, dest_base, fn;
8756               HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8757               HOST_WIDE_INT size = -1;
8758               HOST_WIDE_INT maxsize = -1;
8759
8760               srcvar = TREE_OPERAND (src, 0);
8761               src_base = get_ref_base_and_extent (srcvar, &src_offset,
8762                                                   &size, &maxsize);
8763               destvar = TREE_OPERAND (dest, 0);
8764               dest_base = get_ref_base_and_extent (destvar, &dest_offset,
8765                                                    &size, &maxsize);
8766               if (host_integerp (len, 1))
8767                 maxsize = tree_low_cst (len, 1);
8768               else
8769                 maxsize = -1;
8770               src_offset /= BITS_PER_UNIT;
8771               dest_offset /= BITS_PER_UNIT;
8772               if (SSA_VAR_P (src_base)
8773                   && SSA_VAR_P (dest_base))
8774                 {
8775                   if (operand_equal_p (src_base, dest_base, 0)
8776                       && ranges_overlap_p (src_offset, maxsize,
8777                                            dest_offset, maxsize))
8778                     return NULL_TREE;
8779                 }
8780               else if (TREE_CODE (src_base) == MEM_REF
8781                        && TREE_CODE (dest_base) == MEM_REF)
8782                 {
8783                   double_int off;
8784                   if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8785                                          TREE_OPERAND (dest_base, 0), 0))
8786                     return NULL_TREE;
8787                   off = double_int_add (mem_ref_offset (src_base),
8788                                         shwi_to_double_int (src_offset));
8789                   if (!double_int_fits_in_shwi_p (off))
8790                     return NULL_TREE;
8791                   src_offset = off.low;
8792                   off = double_int_add (mem_ref_offset (dest_base),
8793                                         shwi_to_double_int (dest_offset));
8794                   if (!double_int_fits_in_shwi_p (off))
8795                     return NULL_TREE;
8796                   dest_offset = off.low;
8797                   if (ranges_overlap_p (src_offset, maxsize,
8798                                         dest_offset, maxsize))
8799                     return NULL_TREE;
8800                 }
8801               else
8802                 return NULL_TREE;
8803
8804               fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8805               if (!fn)
8806                 return NULL_TREE;
8807               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8808             }
8809
8810           /* If the destination and source do not alias optimize into
8811              memcpy as well.  */
8812           if ((is_gimple_min_invariant (dest)
8813                || TREE_CODE (dest) == SSA_NAME)
8814               && (is_gimple_min_invariant (src)
8815                   || TREE_CODE (src) == SSA_NAME))
8816             {
8817               ao_ref destr, srcr;
8818               ao_ref_init_from_ptr_and_size (&destr, dest, len);
8819               ao_ref_init_from_ptr_and_size (&srcr, src, len);
8820               if (!refs_may_alias_p_1 (&destr, &srcr, false))
8821                 {
8822                   tree fn;
8823                   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8824                   if (!fn)
8825                     return NULL_TREE;
8826                   return build_call_expr_loc (loc, fn, 3, dest, src, len);
8827                 }
8828             }
8829
8830           return NULL_TREE;
8831         }
8832
8833       if (!host_integerp (len, 0))
8834         return NULL_TREE;
8835       /* FIXME:
8836          This logic lose for arguments like (type *)malloc (sizeof (type)),
8837          since we strip the casts of up to VOID return value from malloc.
8838          Perhaps we ought to inherit type from non-VOID argument here?  */
8839       STRIP_NOPS (src);
8840       STRIP_NOPS (dest);
8841       if (!POINTER_TYPE_P (TREE_TYPE (src))
8842           || !POINTER_TYPE_P (TREE_TYPE (dest)))
8843         return NULL_TREE;
8844       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
8845       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8846         {
8847           tree tem = TREE_OPERAND (src, 0);
8848           STRIP_NOPS (tem);
8849           if (tem != TREE_OPERAND (src, 0))
8850             src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8851         }
8852       if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8853         {
8854           tree tem = TREE_OPERAND (dest, 0);
8855           STRIP_NOPS (tem);
8856           if (tem != TREE_OPERAND (dest, 0))
8857             dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8858         }
8859       srctype = TREE_TYPE (TREE_TYPE (src));
8860       if (TREE_CODE (srctype) == ARRAY_TYPE
8861           && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8862         {
8863           srctype = TREE_TYPE (srctype);
8864           STRIP_NOPS (src);
8865           src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8866         }
8867       desttype = TREE_TYPE (TREE_TYPE (dest));
8868       if (TREE_CODE (desttype) == ARRAY_TYPE
8869           && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8870         {
8871           desttype = TREE_TYPE (desttype);
8872           STRIP_NOPS (dest);
8873           dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8874         }
8875       if (TREE_ADDRESSABLE (srctype)
8876           || TREE_ADDRESSABLE (desttype))
8877         return NULL_TREE;
8878
8879       src_align = get_pointer_alignment (src);
8880       dest_align = get_pointer_alignment (dest);
8881       if (dest_align < TYPE_ALIGN (desttype)
8882           || src_align < TYPE_ALIGN (srctype))
8883         return NULL_TREE;
8884
8885       if (!ignore)
8886         dest = builtin_save_expr (dest);
8887
8888       /* Build accesses at offset zero with a ref-all character type.  */
8889       off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
8890                                                          ptr_mode, true), 0);
8891
8892       destvar = dest;
8893       STRIP_NOPS (destvar);
8894       if (TREE_CODE (destvar) == ADDR_EXPR
8895           && var_decl_component_p (TREE_OPERAND (destvar, 0))
8896           && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8897         destvar = fold_build2 (MEM_REF, desttype, destvar, off0);
8898       else
8899         destvar = NULL_TREE;
8900
8901       srcvar = src;
8902       STRIP_NOPS (srcvar);
8903       if (TREE_CODE (srcvar) == ADDR_EXPR
8904           && var_decl_component_p (TREE_OPERAND (srcvar, 0))
8905           && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8906         {
8907           if (!destvar
8908               || src_align >= TYPE_ALIGN (desttype))
8909             srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
8910                                   srcvar, off0);
8911           else if (!STRICT_ALIGNMENT)
8912             {
8913               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8914                                             src_align);
8915               srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0);
8916             }
8917           else
8918             srcvar = NULL_TREE;
8919         }
8920       else
8921         srcvar = NULL_TREE;
8922
8923       if (srcvar == NULL_TREE && destvar == NULL_TREE)
8924         return NULL_TREE;
8925
8926       if (srcvar == NULL_TREE)
8927         {
8928           STRIP_NOPS (src);
8929           if (src_align >= TYPE_ALIGN (desttype))
8930             srcvar = fold_build2 (MEM_REF, desttype, src, off0);
8931           else
8932             {
8933               if (STRICT_ALIGNMENT)
8934                 return NULL_TREE;
8935               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8936                                             src_align);
8937               srcvar = fold_build2 (MEM_REF, srctype, src, off0);
8938             }
8939         }
8940       else if (destvar == NULL_TREE)
8941         {
8942           STRIP_NOPS (dest);
8943           if (dest_align >= TYPE_ALIGN (srctype))
8944             destvar = fold_build2 (MEM_REF, srctype, dest, off0);
8945           else
8946             {
8947               if (STRICT_ALIGNMENT)
8948                 return NULL_TREE;
8949               desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
8950                                              dest_align);
8951               destvar = fold_build2 (MEM_REF, desttype, dest, off0);
8952             }
8953         }
8954
8955       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar);
8956     }
8957
8958   if (ignore)
8959     return expr;
8960
8961   if (endp == 0 || endp == 3)
8962     return omit_one_operand_loc (loc, type, dest, expr);
8963
8964   if (expr == len)
8965     expr = NULL_TREE;
8966
8967   if (endp == 2)
8968     len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
8969                        ssize_int (1));
8970
8971   dest = fold_build_pointer_plus_loc (loc, dest, len);
8972   dest = fold_convert_loc (loc, type, dest);
8973   if (expr)
8974     dest = omit_one_operand_loc (loc, type, dest, expr);
8975   return dest;
8976 }
8977
8978 /* Fold function call to builtin strcpy with arguments DEST and SRC.
8979    If LEN is not NULL, it represents the length of the string to be
8980    copied.  Return NULL_TREE if no simplification can be made.  */
8981
8982 tree
8983 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
8984 {
8985   tree fn;
8986
8987   if (!validate_arg (dest, POINTER_TYPE)
8988       || !validate_arg (src, POINTER_TYPE))
8989     return NULL_TREE;
8990
8991   /* If SRC and DEST are the same (and not volatile), return DEST.  */
8992   if (operand_equal_p (src, dest, 0))
8993     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
8994
8995   if (optimize_function_for_size_p (cfun))
8996     return NULL_TREE;
8997
8998   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8999   if (!fn)
9000     return NULL_TREE;
9001
9002   if (!len)
9003     {
9004       len = c_strlen (src, 1);
9005       if (! len || TREE_SIDE_EFFECTS (len))
9006         return NULL_TREE;
9007     }
9008
9009   len = fold_convert_loc (loc, size_type_node, len);
9010   len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
9011   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9012                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9013 }
9014
9015 /* Fold function call to builtin stpcpy with arguments DEST and SRC.
9016    Return NULL_TREE if no simplification can be made.  */
9017
9018 static tree
9019 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
9020 {
9021   tree fn, len, lenp1, call, type;
9022
9023   if (!validate_arg (dest, POINTER_TYPE)
9024       || !validate_arg (src, POINTER_TYPE))
9025     return NULL_TREE;
9026
9027   len = c_strlen (src, 1);
9028   if (!len
9029       || TREE_CODE (len) != INTEGER_CST)
9030     return NULL_TREE;
9031
9032   if (optimize_function_for_size_p (cfun)
9033       /* If length is zero it's small enough.  */
9034       && !integer_zerop (len))
9035     return NULL_TREE;
9036
9037   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9038   if (!fn)
9039     return NULL_TREE;
9040
9041   lenp1 = size_binop_loc (loc, PLUS_EXPR,
9042                           fold_convert_loc (loc, size_type_node, len),
9043                           build_int_cst (size_type_node, 1));
9044   /* We use dest twice in building our expression.  Save it from
9045      multiple expansions.  */
9046   dest = builtin_save_expr (dest);
9047   call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
9048
9049   type = TREE_TYPE (TREE_TYPE (fndecl));
9050   dest = fold_build_pointer_plus_loc (loc, dest, len);
9051   dest = fold_convert_loc (loc, type, dest);
9052   dest = omit_one_operand_loc (loc, type, dest, call);
9053   return dest;
9054 }
9055
9056 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9057    If SLEN is not NULL, it represents the length of the source string.
9058    Return NULL_TREE if no simplification can be made.  */
9059
9060 tree
9061 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9062                       tree src, tree len, tree slen)
9063 {
9064   tree fn;
9065
9066   if (!validate_arg (dest, POINTER_TYPE)
9067       || !validate_arg (src, POINTER_TYPE)
9068       || !validate_arg (len, INTEGER_TYPE))
9069     return NULL_TREE;
9070
9071   /* If the LEN parameter is zero, return DEST.  */
9072   if (integer_zerop (len))
9073     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9074
9075   /* We can't compare slen with len as constants below if len is not a
9076      constant.  */
9077   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9078     return NULL_TREE;
9079
9080   if (!slen)
9081     slen = c_strlen (src, 1);
9082
9083   /* Now, we must be passed a constant src ptr parameter.  */
9084   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9085     return NULL_TREE;
9086
9087   slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
9088
9089   /* We do not support simplification of this case, though we do
9090      support it when expanding trees into RTL.  */
9091   /* FIXME: generate a call to __builtin_memset.  */
9092   if (tree_int_cst_lt (slen, len))
9093     return NULL_TREE;
9094
9095   /* OK transform into builtin memcpy.  */
9096   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9097   if (!fn)
9098     return NULL_TREE;
9099
9100   len = fold_convert_loc (loc, size_type_node, len);
9101   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9102                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9103 }
9104
9105 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
9106    arguments to the call, and TYPE is its return type.
9107    Return NULL_TREE if no simplification can be made.  */
9108
9109 static tree
9110 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
9111 {
9112   if (!validate_arg (arg1, POINTER_TYPE)
9113       || !validate_arg (arg2, INTEGER_TYPE)
9114       || !validate_arg (len, INTEGER_TYPE))
9115     return NULL_TREE;
9116   else
9117     {
9118       const char *p1;
9119
9120       if (TREE_CODE (arg2) != INTEGER_CST
9121           || !host_integerp (len, 1))
9122         return NULL_TREE;
9123
9124       p1 = c_getstr (arg1);
9125       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9126         {
9127           char c;
9128           const char *r;
9129           tree tem;
9130
9131           if (target_char_cast (arg2, &c))
9132             return NULL_TREE;
9133
9134           r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
9135
9136           if (r == NULL)
9137             return build_int_cst (TREE_TYPE (arg1), 0);
9138
9139           tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1);
9140           return fold_convert_loc (loc, type, tem);
9141         }
9142       return NULL_TREE;
9143     }
9144 }
9145
9146 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9147    Return NULL_TREE if no simplification can be made.  */
9148
9149 static tree
9150 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9151 {
9152   const char *p1, *p2;
9153
9154   if (!validate_arg (arg1, POINTER_TYPE)
9155       || !validate_arg (arg2, POINTER_TYPE)
9156       || !validate_arg (len, INTEGER_TYPE))
9157     return NULL_TREE;
9158
9159   /* If the LEN parameter is zero, return zero.  */
9160   if (integer_zerop (len))
9161     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9162                               arg1, arg2);
9163
9164   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9165   if (operand_equal_p (arg1, arg2, 0))
9166     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9167
9168   p1 = c_getstr (arg1);
9169   p2 = c_getstr (arg2);
9170
9171   /* If all arguments are constant, and the value of len is not greater
9172      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9173   if (host_integerp (len, 1) && p1 && p2
9174       && compare_tree_int (len, strlen (p1) + 1) <= 0
9175       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9176     {
9177       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9178
9179       if (r > 0)
9180         return integer_one_node;
9181       else if (r < 0)
9182         return integer_minus_one_node;
9183       else
9184         return integer_zero_node;
9185     }
9186
9187   /* If len parameter is one, return an expression corresponding to
9188      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9189   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9190     {
9191       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9192       tree cst_uchar_ptr_node
9193         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9194
9195       tree ind1
9196         = fold_convert_loc (loc, integer_type_node,
9197                             build1 (INDIRECT_REF, cst_uchar_node,
9198                                     fold_convert_loc (loc,
9199                                                       cst_uchar_ptr_node,
9200                                                       arg1)));
9201       tree ind2
9202         = fold_convert_loc (loc, integer_type_node,
9203                             build1 (INDIRECT_REF, cst_uchar_node,
9204                                     fold_convert_loc (loc,
9205                                                       cst_uchar_ptr_node,
9206                                                       arg2)));
9207       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9208     }
9209
9210   return NULL_TREE;
9211 }
9212
9213 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9214    Return NULL_TREE if no simplification can be made.  */
9215
9216 static tree
9217 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9218 {
9219   const char *p1, *p2;
9220
9221   if (!validate_arg (arg1, POINTER_TYPE)
9222       || !validate_arg (arg2, POINTER_TYPE))
9223     return NULL_TREE;
9224
9225   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9226   if (operand_equal_p (arg1, arg2, 0))
9227     return integer_zero_node;
9228
9229   p1 = c_getstr (arg1);
9230   p2 = c_getstr (arg2);
9231
9232   if (p1 && p2)
9233     {
9234       const int i = strcmp (p1, p2);
9235       if (i < 0)
9236         return integer_minus_one_node;
9237       else if (i > 0)
9238         return integer_one_node;
9239       else
9240         return integer_zero_node;
9241     }
9242
9243   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9244   if (p2 && *p2 == '\0')
9245     {
9246       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9247       tree cst_uchar_ptr_node
9248         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9249
9250       return fold_convert_loc (loc, integer_type_node,
9251                                build1 (INDIRECT_REF, cst_uchar_node,
9252                                        fold_convert_loc (loc,
9253                                                          cst_uchar_ptr_node,
9254                                                          arg1)));
9255     }
9256
9257   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9258   if (p1 && *p1 == '\0')
9259     {
9260       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9261       tree cst_uchar_ptr_node
9262         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9263
9264       tree temp
9265         = fold_convert_loc (loc, integer_type_node,
9266                             build1 (INDIRECT_REF, cst_uchar_node,
9267                                     fold_convert_loc (loc,
9268                                                       cst_uchar_ptr_node,
9269                                                       arg2)));
9270       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9271     }
9272
9273   return NULL_TREE;
9274 }
9275
9276 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9277    Return NULL_TREE if no simplification can be made.  */
9278
9279 static tree
9280 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9281 {
9282   const char *p1, *p2;
9283
9284   if (!validate_arg (arg1, POINTER_TYPE)
9285       || !validate_arg (arg2, POINTER_TYPE)
9286       || !validate_arg (len, INTEGER_TYPE))
9287     return NULL_TREE;
9288
9289   /* If the LEN parameter is zero, return zero.  */
9290   if (integer_zerop (len))
9291     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9292                               arg1, arg2);
9293
9294   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9295   if (operand_equal_p (arg1, arg2, 0))
9296     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9297
9298   p1 = c_getstr (arg1);
9299   p2 = c_getstr (arg2);
9300
9301   if (host_integerp (len, 1) && p1 && p2)
9302     {
9303       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9304       if (i > 0)
9305         return integer_one_node;
9306       else if (i < 0)
9307         return integer_minus_one_node;
9308       else
9309         return integer_zero_node;
9310     }
9311
9312   /* If the second arg is "", and the length is greater than zero,
9313      return *(const unsigned char*)arg1.  */
9314   if (p2 && *p2 == '\0'
9315       && TREE_CODE (len) == INTEGER_CST
9316       && tree_int_cst_sgn (len) == 1)
9317     {
9318       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9319       tree cst_uchar_ptr_node
9320         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9321
9322       return fold_convert_loc (loc, integer_type_node,
9323                                build1 (INDIRECT_REF, cst_uchar_node,
9324                                        fold_convert_loc (loc,
9325                                                          cst_uchar_ptr_node,
9326                                                          arg1)));
9327     }
9328
9329   /* If the first arg is "", and the length is greater than zero,
9330      return -*(const unsigned char*)arg2.  */
9331   if (p1 && *p1 == '\0'
9332       && TREE_CODE (len) == INTEGER_CST
9333       && tree_int_cst_sgn (len) == 1)
9334     {
9335       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9336       tree cst_uchar_ptr_node
9337         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9338
9339       tree temp = fold_convert_loc (loc, integer_type_node,
9340                                     build1 (INDIRECT_REF, cst_uchar_node,
9341                                             fold_convert_loc (loc,
9342                                                               cst_uchar_ptr_node,
9343                                                               arg2)));
9344       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9345     }
9346
9347   /* If len parameter is one, return an expression corresponding to
9348      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9349   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9350     {
9351       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9352       tree cst_uchar_ptr_node
9353         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9354
9355       tree ind1 = fold_convert_loc (loc, integer_type_node,
9356                                     build1 (INDIRECT_REF, cst_uchar_node,
9357                                             fold_convert_loc (loc,
9358                                                               cst_uchar_ptr_node,
9359                                                               arg1)));
9360       tree ind2 = fold_convert_loc (loc, integer_type_node,
9361                                     build1 (INDIRECT_REF, cst_uchar_node,
9362                                             fold_convert_loc (loc,
9363                                                               cst_uchar_ptr_node,
9364                                                               arg2)));
9365       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9366     }
9367
9368   return NULL_TREE;
9369 }
9370
9371 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9372    ARG.  Return NULL_TREE if no simplification can be made.  */
9373
9374 static tree
9375 fold_builtin_signbit (location_t loc, tree arg, tree type)
9376 {
9377   if (!validate_arg (arg, REAL_TYPE))
9378     return NULL_TREE;
9379
9380   /* If ARG is a compile-time constant, determine the result.  */
9381   if (TREE_CODE (arg) == REAL_CST
9382       && !TREE_OVERFLOW (arg))
9383     {
9384       REAL_VALUE_TYPE c;
9385
9386       c = TREE_REAL_CST (arg);
9387       return (REAL_VALUE_NEGATIVE (c)
9388               ? build_one_cst (type)
9389               : build_zero_cst (type));
9390     }
9391
9392   /* If ARG is non-negative, the result is always zero.  */
9393   if (tree_expr_nonnegative_p (arg))
9394     return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9395
9396   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9397   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9398     return fold_convert (type,
9399                          fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
9400                         build_real (TREE_TYPE (arg), dconst0)));
9401
9402   return NULL_TREE;
9403 }
9404
9405 /* Fold function call to builtin copysign, copysignf or copysignl with
9406    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9407    be made.  */
9408
9409 static tree
9410 fold_builtin_copysign (location_t loc, tree fndecl,
9411                        tree arg1, tree arg2, tree type)
9412 {
9413   tree tem;
9414
9415   if (!validate_arg (arg1, REAL_TYPE)
9416       || !validate_arg (arg2, REAL_TYPE))
9417     return NULL_TREE;
9418
9419   /* copysign(X,X) is X.  */
9420   if (operand_equal_p (arg1, arg2, 0))
9421     return fold_convert_loc (loc, type, arg1);
9422
9423   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9424   if (TREE_CODE (arg1) == REAL_CST
9425       && TREE_CODE (arg2) == REAL_CST
9426       && !TREE_OVERFLOW (arg1)
9427       && !TREE_OVERFLOW (arg2))
9428     {
9429       REAL_VALUE_TYPE c1, c2;
9430
9431       c1 = TREE_REAL_CST (arg1);
9432       c2 = TREE_REAL_CST (arg2);
9433       /* c1.sign := c2.sign.  */
9434       real_copysign (&c1, &c2);
9435       return build_real (type, c1);
9436     }
9437
9438   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9439      Remember to evaluate Y for side-effects.  */
9440   if (tree_expr_nonnegative_p (arg2))
9441     return omit_one_operand_loc (loc, type,
9442                              fold_build1_loc (loc, ABS_EXPR, type, arg1),
9443                              arg2);
9444
9445   /* Strip sign changing operations for the first argument.  */
9446   tem = fold_strip_sign_ops (arg1);
9447   if (tem)
9448     return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9449
9450   return NULL_TREE;
9451 }
9452
9453 /* Fold a call to builtin isascii with argument ARG.  */
9454
9455 static tree
9456 fold_builtin_isascii (location_t loc, tree arg)
9457 {
9458   if (!validate_arg (arg, INTEGER_TYPE))
9459     return NULL_TREE;
9460   else
9461     {
9462       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9463       arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9464                          build_int_cst (integer_type_node,
9465                                         ~ (unsigned HOST_WIDE_INT) 0x7f));
9466       return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9467                               arg, integer_zero_node);
9468     }
9469 }
9470
9471 /* Fold a call to builtin toascii with argument ARG.  */
9472
9473 static tree
9474 fold_builtin_toascii (location_t loc, tree arg)
9475 {
9476   if (!validate_arg (arg, INTEGER_TYPE))
9477     return NULL_TREE;
9478
9479   /* Transform toascii(c) -> (c & 0x7f).  */
9480   return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9481                           build_int_cst (integer_type_node, 0x7f));
9482 }
9483
9484 /* Fold a call to builtin isdigit with argument ARG.  */
9485
9486 static tree
9487 fold_builtin_isdigit (location_t loc, tree arg)
9488 {
9489   if (!validate_arg (arg, INTEGER_TYPE))
9490     return NULL_TREE;
9491   else
9492     {
9493       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9494       /* According to the C standard, isdigit is unaffected by locale.
9495          However, it definitely is affected by the target character set.  */
9496       unsigned HOST_WIDE_INT target_digit0
9497         = lang_hooks.to_target_charset ('0');
9498
9499       if (target_digit0 == 0)
9500         return NULL_TREE;
9501
9502       arg = fold_convert_loc (loc, unsigned_type_node, arg);
9503       arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9504                          build_int_cst (unsigned_type_node, target_digit0));
9505       return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9506                           build_int_cst (unsigned_type_node, 9));
9507     }
9508 }
9509
9510 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9511
9512 static tree
9513 fold_builtin_fabs (location_t loc, tree arg, tree type)
9514 {
9515   if (!validate_arg (arg, REAL_TYPE))
9516     return NULL_TREE;
9517
9518   arg = fold_convert_loc (loc, type, arg);
9519   if (TREE_CODE (arg) == REAL_CST)
9520     return fold_abs_const (arg, type);
9521   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9522 }
9523
9524 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9525
9526 static tree
9527 fold_builtin_abs (location_t loc, tree arg, tree type)
9528 {
9529   if (!validate_arg (arg, INTEGER_TYPE))
9530     return NULL_TREE;
9531
9532   arg = fold_convert_loc (loc, type, arg);
9533   if (TREE_CODE (arg) == INTEGER_CST)
9534     return fold_abs_const (arg, type);
9535   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9536 }
9537
9538 /* Fold a fma operation with arguments ARG[012].  */
9539
9540 tree
9541 fold_fma (location_t loc ATTRIBUTE_UNUSED,
9542           tree type, tree arg0, tree arg1, tree arg2)
9543 {
9544   if (TREE_CODE (arg0) == REAL_CST
9545       && TREE_CODE (arg1) == REAL_CST
9546       && TREE_CODE (arg2) == REAL_CST)
9547     return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
9548
9549   return NULL_TREE;
9550 }
9551
9552 /* Fold a call to fma, fmaf, or fmal with arguments ARG[012].  */
9553
9554 static tree
9555 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
9556 {
9557   if (validate_arg (arg0, REAL_TYPE)
9558       && validate_arg(arg1, REAL_TYPE)
9559       && validate_arg(arg2, REAL_TYPE))
9560     {
9561       tree tem = fold_fma (loc, type, arg0, arg1, arg2);
9562       if (tem)
9563         return tem;
9564
9565       /* ??? Only expand to FMA_EXPR if it's directly supported.  */
9566       if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
9567         return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2);
9568     }
9569   return NULL_TREE;
9570 }
9571
9572 /* Fold a call to builtin fmin or fmax.  */
9573
9574 static tree
9575 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9576                         tree type, bool max)
9577 {
9578   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9579     {
9580       /* Calculate the result when the argument is a constant.  */
9581       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9582
9583       if (res)
9584         return res;
9585
9586       /* If either argument is NaN, return the other one.  Avoid the
9587          transformation if we get (and honor) a signalling NaN.  Using
9588          omit_one_operand() ensures we create a non-lvalue.  */
9589       if (TREE_CODE (arg0) == REAL_CST
9590           && real_isnan (&TREE_REAL_CST (arg0))
9591           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9592               || ! TREE_REAL_CST (arg0).signalling))
9593         return omit_one_operand_loc (loc, type, arg1, arg0);
9594       if (TREE_CODE (arg1) == REAL_CST
9595           && real_isnan (&TREE_REAL_CST (arg1))
9596           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9597               || ! TREE_REAL_CST (arg1).signalling))
9598         return omit_one_operand_loc (loc, type, arg0, arg1);
9599
9600       /* Transform fmin/fmax(x,x) -> x.  */
9601       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9602         return omit_one_operand_loc (loc, type, arg0, arg1);
9603
9604       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9605          functions to return the numeric arg if the other one is NaN.
9606          These tree codes don't honor that, so only transform if
9607          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9608          handled, so we don't have to worry about it either.  */
9609       if (flag_finite_math_only)
9610         return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9611                             fold_convert_loc (loc, type, arg0),
9612                             fold_convert_loc (loc, type, arg1));
9613     }
9614   return NULL_TREE;
9615 }
9616
9617 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9618
9619 static tree
9620 fold_builtin_carg (location_t loc, tree arg, tree type)
9621 {
9622   if (validate_arg (arg, COMPLEX_TYPE)
9623       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9624     {
9625       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9626
9627       if (atan2_fn)
9628         {
9629           tree new_arg = builtin_save_expr (arg);
9630           tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9631           tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9632           return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9633         }
9634     }
9635
9636   return NULL_TREE;
9637 }
9638
9639 /* Fold a call to builtin logb/ilogb.  */
9640
9641 static tree
9642 fold_builtin_logb (location_t loc, tree arg, tree rettype)
9643 {
9644   if (! validate_arg (arg, REAL_TYPE))
9645     return NULL_TREE;
9646
9647   STRIP_NOPS (arg);
9648
9649   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9650     {
9651       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9652
9653       switch (value->cl)
9654       {
9655       case rvc_nan:
9656       case rvc_inf:
9657         /* If arg is Inf or NaN and we're logb, return it.  */
9658         if (TREE_CODE (rettype) == REAL_TYPE)
9659           return fold_convert_loc (loc, rettype, arg);
9660         /* Fall through... */
9661       case rvc_zero:
9662         /* Zero may set errno and/or raise an exception for logb, also
9663            for ilogb we don't know FP_ILOGB0.  */
9664         return NULL_TREE;
9665       case rvc_normal:
9666         /* For normal numbers, proceed iff radix == 2.  In GCC,
9667            normalized significands are in the range [0.5, 1.0).  We
9668            want the exponent as if they were [1.0, 2.0) so get the
9669            exponent and subtract 1.  */
9670         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9671           return fold_convert_loc (loc, rettype,
9672                                    build_int_cst (integer_type_node,
9673                                                   REAL_EXP (value)-1));
9674         break;
9675       }
9676     }
9677
9678   return NULL_TREE;
9679 }
9680
9681 /* Fold a call to builtin significand, if radix == 2.  */
9682
9683 static tree
9684 fold_builtin_significand (location_t loc, tree arg, tree rettype)
9685 {
9686   if (! validate_arg (arg, REAL_TYPE))
9687     return NULL_TREE;
9688
9689   STRIP_NOPS (arg);
9690
9691   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9692     {
9693       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9694
9695       switch (value->cl)
9696       {
9697       case rvc_zero:
9698       case rvc_nan:
9699       case rvc_inf:
9700         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9701         return fold_convert_loc (loc, rettype, arg);
9702       case rvc_normal:
9703         /* For normal numbers, proceed iff radix == 2.  */
9704         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9705           {
9706             REAL_VALUE_TYPE result = *value;
9707             /* In GCC, normalized significands are in the range [0.5,
9708                1.0).  We want them to be [1.0, 2.0) so set the
9709                exponent to 1.  */
9710             SET_REAL_EXP (&result, 1);
9711             return build_real (rettype, result);
9712           }
9713         break;
9714       }
9715     }
9716
9717   return NULL_TREE;
9718 }
9719
9720 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9721
9722 static tree
9723 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9724 {
9725   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9726     return NULL_TREE;
9727
9728   STRIP_NOPS (arg0);
9729
9730   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9731     return NULL_TREE;
9732
9733   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9734
9735   /* Proceed if a valid pointer type was passed in.  */
9736   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9737     {
9738       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9739       tree frac, exp;
9740
9741       switch (value->cl)
9742       {
9743       case rvc_zero:
9744         /* For +-0, return (*exp = 0, +-0).  */
9745         exp = integer_zero_node;
9746         frac = arg0;
9747         break;
9748       case rvc_nan:
9749       case rvc_inf:
9750         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9751         return omit_one_operand_loc (loc, rettype, arg0, arg1);
9752       case rvc_normal:
9753         {
9754           /* Since the frexp function always expects base 2, and in
9755              GCC normalized significands are already in the range
9756              [0.5, 1.0), we have exactly what frexp wants.  */
9757           REAL_VALUE_TYPE frac_rvt = *value;
9758           SET_REAL_EXP (&frac_rvt, 0);
9759           frac = build_real (rettype, frac_rvt);
9760           exp = build_int_cst (integer_type_node, REAL_EXP (value));
9761         }
9762         break;
9763       default:
9764         gcc_unreachable ();
9765       }
9766
9767       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9768       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9769       TREE_SIDE_EFFECTS (arg1) = 1;
9770       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9771     }
9772
9773   return NULL_TREE;
9774 }
9775
9776 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9777    then we can assume the base is two.  If it's false, then we have to
9778    check the mode of the TYPE parameter in certain cases.  */
9779
9780 static tree
9781 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9782                             tree type, bool ldexp)
9783 {
9784   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9785     {
9786       STRIP_NOPS (arg0);
9787       STRIP_NOPS (arg1);
9788
9789       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9790       if (real_zerop (arg0) || integer_zerop (arg1)
9791           || (TREE_CODE (arg0) == REAL_CST
9792               && !real_isfinite (&TREE_REAL_CST (arg0))))
9793         return omit_one_operand_loc (loc, type, arg0, arg1);
9794
9795       /* If both arguments are constant, then try to evaluate it.  */
9796       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9797           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9798           && host_integerp (arg1, 0))
9799         {
9800           /* Bound the maximum adjustment to twice the range of the
9801              mode's valid exponents.  Use abs to ensure the range is
9802              positive as a sanity check.  */
9803           const long max_exp_adj = 2 *
9804             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9805                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9806
9807           /* Get the user-requested adjustment.  */
9808           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9809
9810           /* The requested adjustment must be inside this range.  This
9811              is a preliminary cap to avoid things like overflow, we
9812              may still fail to compute the result for other reasons.  */
9813           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9814             {
9815               REAL_VALUE_TYPE initial_result;
9816
9817               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9818
9819               /* Ensure we didn't overflow.  */
9820               if (! real_isinf (&initial_result))
9821                 {
9822                   const REAL_VALUE_TYPE trunc_result
9823                     = real_value_truncate (TYPE_MODE (type), initial_result);
9824
9825                   /* Only proceed if the target mode can hold the
9826                      resulting value.  */
9827                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9828                     return build_real (type, trunc_result);
9829                 }
9830             }
9831         }
9832     }
9833
9834   return NULL_TREE;
9835 }
9836
9837 /* Fold a call to builtin modf.  */
9838
9839 static tree
9840 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9841 {
9842   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9843     return NULL_TREE;
9844
9845   STRIP_NOPS (arg0);
9846
9847   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9848     return NULL_TREE;
9849
9850   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9851
9852   /* Proceed if a valid pointer type was passed in.  */
9853   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9854     {
9855       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9856       REAL_VALUE_TYPE trunc, frac;
9857
9858       switch (value->cl)
9859       {
9860       case rvc_nan:
9861       case rvc_zero:
9862         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9863         trunc = frac = *value;
9864         break;
9865       case rvc_inf:
9866         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9867         frac = dconst0;
9868         frac.sign = value->sign;
9869         trunc = *value;
9870         break;
9871       case rvc_normal:
9872         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9873         real_trunc (&trunc, VOIDmode, value);
9874         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9875         /* If the original number was negative and already
9876            integral, then the fractional part is -0.0.  */
9877         if (value->sign && frac.cl == rvc_zero)
9878           frac.sign = value->sign;
9879         break;
9880       }
9881
9882       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9883       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9884                           build_real (rettype, trunc));
9885       TREE_SIDE_EFFECTS (arg1) = 1;
9886       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9887                           build_real (rettype, frac));
9888     }
9889
9890   return NULL_TREE;
9891 }
9892
9893 /* Given a location LOC, an interclass builtin function decl FNDECL
9894    and its single argument ARG, return an folded expression computing
9895    the same, or NULL_TREE if we either couldn't or didn't want to fold
9896    (the latter happen if there's an RTL instruction available).  */
9897
9898 static tree
9899 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9900 {
9901   enum machine_mode mode;
9902
9903   if (!validate_arg (arg, REAL_TYPE))
9904     return NULL_TREE;
9905
9906   if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9907     return NULL_TREE;
9908
9909   mode = TYPE_MODE (TREE_TYPE (arg));
9910
9911   /* If there is no optab, try generic code.  */
9912   switch (DECL_FUNCTION_CODE (fndecl))
9913     {
9914       tree result;
9915
9916     CASE_FLT_FN (BUILT_IN_ISINF):
9917       {
9918         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
9919         tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER);
9920         tree const type = TREE_TYPE (arg);
9921         REAL_VALUE_TYPE r;
9922         char buf[128];
9923
9924         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9925         real_from_string (&r, buf);
9926         result = build_call_expr (isgr_fn, 2,
9927                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9928                                   build_real (type, r));
9929         return result;
9930       }
9931     CASE_FLT_FN (BUILT_IN_FINITE):
9932     case BUILT_IN_ISFINITE:
9933       {
9934         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
9935         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9936         tree const type = TREE_TYPE (arg);
9937         REAL_VALUE_TYPE r;
9938         char buf[128];
9939
9940         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9941         real_from_string (&r, buf);
9942         result = build_call_expr (isle_fn, 2,
9943                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9944                                   build_real (type, r));
9945         /*result = fold_build2_loc (loc, UNGT_EXPR,
9946                                   TREE_TYPE (TREE_TYPE (fndecl)),
9947                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9948                                   build_real (type, r));
9949         result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9950                                   TREE_TYPE (TREE_TYPE (fndecl)),
9951                                   result);*/
9952         return result;
9953       }
9954     case BUILT_IN_ISNORMAL:
9955       {
9956         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9957            islessequal(fabs(x),DBL_MAX).  */
9958         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9959         tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL);
9960         tree const type = TREE_TYPE (arg);
9961         REAL_VALUE_TYPE rmax, rmin;
9962         char buf[128];
9963
9964         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9965         real_from_string (&rmax, buf);
9966         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9967         real_from_string (&rmin, buf);
9968         arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9969         result = build_call_expr (isle_fn, 2, arg,
9970                                   build_real (type, rmax));
9971         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9972                               build_call_expr (isge_fn, 2, arg,
9973                                                build_real (type, rmin)));
9974         return result;
9975       }
9976     default:
9977       break;
9978     }
9979
9980   return NULL_TREE;
9981 }
9982
9983 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9984    ARG is the argument for the call.  */
9985
9986 static tree
9987 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
9988 {
9989   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9990   REAL_VALUE_TYPE r;
9991
9992   if (!validate_arg (arg, REAL_TYPE))
9993     return NULL_TREE;
9994
9995   switch (builtin_index)
9996     {
9997     case BUILT_IN_ISINF:
9998       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9999         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10000
10001       if (TREE_CODE (arg) == REAL_CST)
10002         {
10003           r = TREE_REAL_CST (arg);
10004           if (real_isinf (&r))
10005             return real_compare (GT_EXPR, &r, &dconst0)
10006                    ? integer_one_node : integer_minus_one_node;
10007           else
10008             return integer_zero_node;
10009         }
10010
10011       return NULL_TREE;
10012
10013     case BUILT_IN_ISINF_SIGN:
10014       {
10015         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10016         /* In a boolean context, GCC will fold the inner COND_EXPR to
10017            1.  So e.g. "if (isinf_sign(x))" would be folded to just
10018            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10019         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10020         tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF);
10021         tree tmp = NULL_TREE;
10022
10023         arg = builtin_save_expr (arg);
10024
10025         if (signbit_fn && isinf_fn)
10026           {
10027             tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10028             tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
10029
10030             signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10031                                         signbit_call, integer_zero_node);
10032             isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10033                                       isinf_call, integer_zero_node);
10034
10035             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
10036                                integer_minus_one_node, integer_one_node);
10037             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10038                                isinf_call, tmp,
10039                                integer_zero_node);
10040           }
10041
10042         return tmp;
10043       }
10044
10045     case BUILT_IN_ISFINITE:
10046       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10047           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10048         return omit_one_operand_loc (loc, type, integer_one_node, arg);
10049
10050       if (TREE_CODE (arg) == REAL_CST)
10051         {
10052           r = TREE_REAL_CST (arg);
10053           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
10054         }
10055
10056       return NULL_TREE;
10057
10058     case BUILT_IN_ISNAN:
10059       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
10060         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10061
10062       if (TREE_CODE (arg) == REAL_CST)
10063         {
10064           r = TREE_REAL_CST (arg);
10065           return real_isnan (&r) ? integer_one_node : integer_zero_node;
10066         }
10067
10068       arg = builtin_save_expr (arg);
10069       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
10070
10071     default:
10072       gcc_unreachable ();
10073     }
10074 }
10075
10076 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10077    This builtin will generate code to return the appropriate floating
10078    point classification depending on the value of the floating point
10079    number passed in.  The possible return values must be supplied as
10080    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
10081    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
10082    one floating point argument which is "type generic".  */
10083
10084 static tree
10085 fold_builtin_fpclassify (location_t loc, tree exp)
10086 {
10087   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10088     arg, type, res, tmp;
10089   enum machine_mode mode;
10090   REAL_VALUE_TYPE r;
10091   char buf[128];
10092
10093   /* Verify the required arguments in the original call.  */
10094   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10095                          INTEGER_TYPE, INTEGER_TYPE,
10096                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10097     return NULL_TREE;
10098
10099   fp_nan = CALL_EXPR_ARG (exp, 0);
10100   fp_infinite = CALL_EXPR_ARG (exp, 1);
10101   fp_normal = CALL_EXPR_ARG (exp, 2);
10102   fp_subnormal = CALL_EXPR_ARG (exp, 3);
10103   fp_zero = CALL_EXPR_ARG (exp, 4);
10104   arg = CALL_EXPR_ARG (exp, 5);
10105   type = TREE_TYPE (arg);
10106   mode = TYPE_MODE (type);
10107   arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10108
10109   /* fpclassify(x) ->
10110        isnan(x) ? FP_NAN :
10111          (fabs(x) == Inf ? FP_INFINITE :
10112            (fabs(x) >= DBL_MIN ? FP_NORMAL :
10113              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
10114
10115   tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10116                      build_real (type, dconst0));
10117   res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10118                      tmp, fp_zero, fp_subnormal);
10119
10120   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10121   real_from_string (&r, buf);
10122   tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10123                      arg, build_real (type, r));
10124   res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
10125
10126   if (HONOR_INFINITIES (mode))
10127     {
10128       real_inf (&r);
10129       tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10130                          build_real (type, r));
10131       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10132                          fp_infinite, res);
10133     }
10134
10135   if (HONOR_NANS (mode))
10136     {
10137       tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10138       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
10139     }
10140
10141   return res;
10142 }
10143
10144 /* Fold a call to an unordered comparison function such as
10145    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
10146    being called and ARG0 and ARG1 are the arguments for the call.
10147    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10148    the opposite of the desired result.  UNORDERED_CODE is used
10149    for modes that can hold NaNs and ORDERED_CODE is used for
10150    the rest.  */
10151
10152 static tree
10153 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
10154                             enum tree_code unordered_code,
10155                             enum tree_code ordered_code)
10156 {
10157   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10158   enum tree_code code;
10159   tree type0, type1;
10160   enum tree_code code0, code1;
10161   tree cmp_type = NULL_TREE;
10162
10163   type0 = TREE_TYPE (arg0);
10164   type1 = TREE_TYPE (arg1);
10165
10166   code0 = TREE_CODE (type0);
10167   code1 = TREE_CODE (type1);
10168
10169   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10170     /* Choose the wider of two real types.  */
10171     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10172       ? type0 : type1;
10173   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10174     cmp_type = type0;
10175   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10176     cmp_type = type1;
10177
10178   arg0 = fold_convert_loc (loc, cmp_type, arg0);
10179   arg1 = fold_convert_loc (loc, cmp_type, arg1);
10180
10181   if (unordered_code == UNORDERED_EXPR)
10182     {
10183       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10184         return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10185       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
10186     }
10187
10188   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10189                                                    : ordered_code;
10190   return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10191                       fold_build2_loc (loc, code, type, arg0, arg1));
10192 }
10193
10194 /* Fold a call to built-in function FNDECL with 0 arguments.
10195    IGNORE is true if the result of the function call is ignored.  This
10196    function returns NULL_TREE if no simplification was possible.  */
10197
10198 static tree
10199 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10200 {
10201   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10202   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10203   switch (fcode)
10204     {
10205     CASE_FLT_FN (BUILT_IN_INF):
10206     case BUILT_IN_INFD32:
10207     case BUILT_IN_INFD64:
10208     case BUILT_IN_INFD128:
10209       return fold_builtin_inf (loc, type, true);
10210
10211     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10212       return fold_builtin_inf (loc, type, false);
10213
10214     case BUILT_IN_CLASSIFY_TYPE:
10215       return fold_builtin_classify_type (NULL_TREE);
10216
10217     default:
10218       break;
10219     }
10220   return NULL_TREE;
10221 }
10222
10223 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10224    IGNORE is true if the result of the function call is ignored.  This
10225    function returns NULL_TREE if no simplification was possible.  */
10226
10227 static tree
10228 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
10229 {
10230   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10231   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10232   switch (fcode)
10233     {
10234     case BUILT_IN_CONSTANT_P:
10235       {
10236         tree val = fold_builtin_constant_p (arg0);
10237
10238         /* Gimplification will pull the CALL_EXPR for the builtin out of
10239            an if condition.  When not optimizing, we'll not CSE it back.
10240            To avoid link error types of regressions, return false now.  */
10241         if (!val && !optimize)
10242           val = integer_zero_node;
10243
10244         return val;
10245       }
10246
10247     case BUILT_IN_CLASSIFY_TYPE:
10248       return fold_builtin_classify_type (arg0);
10249
10250     case BUILT_IN_STRLEN:
10251       return fold_builtin_strlen (loc, type, arg0);
10252
10253     CASE_FLT_FN (BUILT_IN_FABS):
10254       return fold_builtin_fabs (loc, arg0, type);
10255
10256     case BUILT_IN_ABS:
10257     case BUILT_IN_LABS:
10258     case BUILT_IN_LLABS:
10259     case BUILT_IN_IMAXABS:
10260       return fold_builtin_abs (loc, arg0, type);
10261
10262     CASE_FLT_FN (BUILT_IN_CONJ):
10263       if (validate_arg (arg0, COMPLEX_TYPE)
10264         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10265         return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
10266     break;
10267
10268     CASE_FLT_FN (BUILT_IN_CREAL):
10269       if (validate_arg (arg0, COMPLEX_TYPE)
10270         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10271         return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10272     break;
10273
10274     CASE_FLT_FN (BUILT_IN_CIMAG):
10275       if (validate_arg (arg0, COMPLEX_TYPE)
10276           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10277         return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10278     break;
10279
10280     CASE_FLT_FN (BUILT_IN_CCOS):
10281       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10282
10283     CASE_FLT_FN (BUILT_IN_CCOSH):
10284       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10285
10286     CASE_FLT_FN (BUILT_IN_CPROJ):
10287       return fold_builtin_cproj(loc, arg0, type);
10288
10289     CASE_FLT_FN (BUILT_IN_CSIN):
10290       if (validate_arg (arg0, COMPLEX_TYPE)
10291           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10292         return do_mpc_arg1 (arg0, type, mpc_sin);
10293     break;
10294
10295     CASE_FLT_FN (BUILT_IN_CSINH):
10296       if (validate_arg (arg0, COMPLEX_TYPE)
10297           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10298         return do_mpc_arg1 (arg0, type, mpc_sinh);
10299     break;
10300
10301     CASE_FLT_FN (BUILT_IN_CTAN):
10302       if (validate_arg (arg0, COMPLEX_TYPE)
10303           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10304         return do_mpc_arg1 (arg0, type, mpc_tan);
10305     break;
10306
10307     CASE_FLT_FN (BUILT_IN_CTANH):
10308       if (validate_arg (arg0, COMPLEX_TYPE)
10309           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10310         return do_mpc_arg1 (arg0, type, mpc_tanh);
10311     break;
10312
10313     CASE_FLT_FN (BUILT_IN_CLOG):
10314       if (validate_arg (arg0, COMPLEX_TYPE)
10315           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10316         return do_mpc_arg1 (arg0, type, mpc_log);
10317     break;
10318
10319     CASE_FLT_FN (BUILT_IN_CSQRT):
10320       if (validate_arg (arg0, COMPLEX_TYPE)
10321           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10322         return do_mpc_arg1 (arg0, type, mpc_sqrt);
10323     break;
10324
10325     CASE_FLT_FN (BUILT_IN_CASIN):
10326       if (validate_arg (arg0, COMPLEX_TYPE)
10327           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10328         return do_mpc_arg1 (arg0, type, mpc_asin);
10329     break;
10330
10331     CASE_FLT_FN (BUILT_IN_CACOS):
10332       if (validate_arg (arg0, COMPLEX_TYPE)
10333           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10334         return do_mpc_arg1 (arg0, type, mpc_acos);
10335     break;
10336
10337     CASE_FLT_FN (BUILT_IN_CATAN):
10338       if (validate_arg (arg0, COMPLEX_TYPE)
10339           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10340         return do_mpc_arg1 (arg0, type, mpc_atan);
10341     break;
10342
10343     CASE_FLT_FN (BUILT_IN_CASINH):
10344       if (validate_arg (arg0, COMPLEX_TYPE)
10345           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10346         return do_mpc_arg1 (arg0, type, mpc_asinh);
10347     break;
10348
10349     CASE_FLT_FN (BUILT_IN_CACOSH):
10350       if (validate_arg (arg0, COMPLEX_TYPE)
10351           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10352         return do_mpc_arg1 (arg0, type, mpc_acosh);
10353     break;
10354
10355     CASE_FLT_FN (BUILT_IN_CATANH):
10356       if (validate_arg (arg0, COMPLEX_TYPE)
10357           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10358         return do_mpc_arg1 (arg0, type, mpc_atanh);
10359     break;
10360
10361     CASE_FLT_FN (BUILT_IN_CABS):
10362       return fold_builtin_cabs (loc, arg0, type, fndecl);
10363
10364     CASE_FLT_FN (BUILT_IN_CARG):
10365       return fold_builtin_carg (loc, arg0, type);
10366
10367     CASE_FLT_FN (BUILT_IN_SQRT):
10368       return fold_builtin_sqrt (loc, arg0, type);
10369
10370     CASE_FLT_FN (BUILT_IN_CBRT):
10371       return fold_builtin_cbrt (loc, arg0, type);
10372
10373     CASE_FLT_FN (BUILT_IN_ASIN):
10374       if (validate_arg (arg0, REAL_TYPE))
10375         return do_mpfr_arg1 (arg0, type, mpfr_asin,
10376                              &dconstm1, &dconst1, true);
10377     break;
10378
10379     CASE_FLT_FN (BUILT_IN_ACOS):
10380       if (validate_arg (arg0, REAL_TYPE))
10381         return do_mpfr_arg1 (arg0, type, mpfr_acos,
10382                              &dconstm1, &dconst1, true);
10383     break;
10384
10385     CASE_FLT_FN (BUILT_IN_ATAN):
10386       if (validate_arg (arg0, REAL_TYPE))
10387         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10388     break;
10389
10390     CASE_FLT_FN (BUILT_IN_ASINH):
10391       if (validate_arg (arg0, REAL_TYPE))
10392         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10393     break;
10394
10395     CASE_FLT_FN (BUILT_IN_ACOSH):
10396       if (validate_arg (arg0, REAL_TYPE))
10397         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10398                              &dconst1, NULL, true);
10399     break;
10400
10401     CASE_FLT_FN (BUILT_IN_ATANH):
10402       if (validate_arg (arg0, REAL_TYPE))
10403         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10404                              &dconstm1, &dconst1, false);
10405     break;
10406
10407     CASE_FLT_FN (BUILT_IN_SIN):
10408       if (validate_arg (arg0, REAL_TYPE))
10409         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10410     break;
10411
10412     CASE_FLT_FN (BUILT_IN_COS):
10413       return fold_builtin_cos (loc, arg0, type, fndecl);
10414
10415     CASE_FLT_FN (BUILT_IN_TAN):
10416       return fold_builtin_tan (arg0, type);
10417
10418     CASE_FLT_FN (BUILT_IN_CEXP):
10419       return fold_builtin_cexp (loc, arg0, type);
10420
10421     CASE_FLT_FN (BUILT_IN_CEXPI):
10422       if (validate_arg (arg0, REAL_TYPE))
10423         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10424     break;
10425
10426     CASE_FLT_FN (BUILT_IN_SINH):
10427       if (validate_arg (arg0, REAL_TYPE))
10428         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10429     break;
10430
10431     CASE_FLT_FN (BUILT_IN_COSH):
10432       return fold_builtin_cosh (loc, arg0, type, fndecl);
10433
10434     CASE_FLT_FN (BUILT_IN_TANH):
10435       if (validate_arg (arg0, REAL_TYPE))
10436         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10437     break;
10438
10439     CASE_FLT_FN (BUILT_IN_ERF):
10440       if (validate_arg (arg0, REAL_TYPE))
10441         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10442     break;
10443
10444     CASE_FLT_FN (BUILT_IN_ERFC):
10445       if (validate_arg (arg0, REAL_TYPE))
10446         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10447     break;
10448
10449     CASE_FLT_FN (BUILT_IN_TGAMMA):
10450       if (validate_arg (arg0, REAL_TYPE))
10451         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10452     break;
10453
10454     CASE_FLT_FN (BUILT_IN_EXP):
10455       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10456
10457     CASE_FLT_FN (BUILT_IN_EXP2):
10458       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10459
10460     CASE_FLT_FN (BUILT_IN_EXP10):
10461     CASE_FLT_FN (BUILT_IN_POW10):
10462       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10463
10464     CASE_FLT_FN (BUILT_IN_EXPM1):
10465       if (validate_arg (arg0, REAL_TYPE))
10466         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10467     break;
10468
10469     CASE_FLT_FN (BUILT_IN_LOG):
10470     return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10471
10472     CASE_FLT_FN (BUILT_IN_LOG2):
10473       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10474
10475     CASE_FLT_FN (BUILT_IN_LOG10):
10476       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10477
10478     CASE_FLT_FN (BUILT_IN_LOG1P):
10479       if (validate_arg (arg0, REAL_TYPE))
10480         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10481                              &dconstm1, NULL, false);
10482     break;
10483
10484     CASE_FLT_FN (BUILT_IN_J0):
10485       if (validate_arg (arg0, REAL_TYPE))
10486         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10487                              NULL, NULL, 0);
10488     break;
10489
10490     CASE_FLT_FN (BUILT_IN_J1):
10491       if (validate_arg (arg0, REAL_TYPE))
10492         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10493                              NULL, NULL, 0);
10494     break;
10495
10496     CASE_FLT_FN (BUILT_IN_Y0):
10497       if (validate_arg (arg0, REAL_TYPE))
10498         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10499                              &dconst0, NULL, false);
10500     break;
10501
10502     CASE_FLT_FN (BUILT_IN_Y1):
10503       if (validate_arg (arg0, REAL_TYPE))
10504         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10505                              &dconst0, NULL, false);
10506     break;
10507
10508     CASE_FLT_FN (BUILT_IN_NAN):
10509     case BUILT_IN_NAND32:
10510     case BUILT_IN_NAND64:
10511     case BUILT_IN_NAND128:
10512       return fold_builtin_nan (arg0, type, true);
10513
10514     CASE_FLT_FN (BUILT_IN_NANS):
10515       return fold_builtin_nan (arg0, type, false);
10516
10517     CASE_FLT_FN (BUILT_IN_FLOOR):
10518       return fold_builtin_floor (loc, fndecl, arg0);
10519
10520     CASE_FLT_FN (BUILT_IN_CEIL):
10521       return fold_builtin_ceil (loc, fndecl, arg0);
10522
10523     CASE_FLT_FN (BUILT_IN_TRUNC):
10524       return fold_builtin_trunc (loc, fndecl, arg0);
10525
10526     CASE_FLT_FN (BUILT_IN_ROUND):
10527       return fold_builtin_round (loc, fndecl, arg0);
10528
10529     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10530     CASE_FLT_FN (BUILT_IN_RINT):
10531       return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10532
10533     CASE_FLT_FN (BUILT_IN_ICEIL):
10534     CASE_FLT_FN (BUILT_IN_LCEIL):
10535     CASE_FLT_FN (BUILT_IN_LLCEIL):
10536     CASE_FLT_FN (BUILT_IN_LFLOOR):
10537     CASE_FLT_FN (BUILT_IN_IFLOOR):
10538     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10539     CASE_FLT_FN (BUILT_IN_IROUND):
10540     CASE_FLT_FN (BUILT_IN_LROUND):
10541     CASE_FLT_FN (BUILT_IN_LLROUND):
10542       return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10543
10544     CASE_FLT_FN (BUILT_IN_IRINT):
10545     CASE_FLT_FN (BUILT_IN_LRINT):
10546     CASE_FLT_FN (BUILT_IN_LLRINT):
10547       return fold_fixed_mathfn (loc, fndecl, arg0);
10548
10549     case BUILT_IN_BSWAP32:
10550     case BUILT_IN_BSWAP64:
10551       return fold_builtin_bswap (fndecl, arg0);
10552
10553     CASE_INT_FN (BUILT_IN_FFS):
10554     CASE_INT_FN (BUILT_IN_CLZ):
10555     CASE_INT_FN (BUILT_IN_CTZ):
10556     CASE_INT_FN (BUILT_IN_CLRSB):
10557     CASE_INT_FN (BUILT_IN_POPCOUNT):
10558     CASE_INT_FN (BUILT_IN_PARITY):
10559       return fold_builtin_bitop (fndecl, arg0);
10560
10561     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10562       return fold_builtin_signbit (loc, arg0, type);
10563
10564     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10565       return fold_builtin_significand (loc, arg0, type);
10566
10567     CASE_FLT_FN (BUILT_IN_ILOGB):
10568     CASE_FLT_FN (BUILT_IN_LOGB):
10569       return fold_builtin_logb (loc, arg0, type);
10570
10571     case BUILT_IN_ISASCII:
10572       return fold_builtin_isascii (loc, arg0);
10573
10574     case BUILT_IN_TOASCII:
10575       return fold_builtin_toascii (loc, arg0);
10576
10577     case BUILT_IN_ISDIGIT:
10578       return fold_builtin_isdigit (loc, arg0);
10579
10580     CASE_FLT_FN (BUILT_IN_FINITE):
10581     case BUILT_IN_FINITED32:
10582     case BUILT_IN_FINITED64:
10583     case BUILT_IN_FINITED128:
10584     case BUILT_IN_ISFINITE:
10585       {
10586         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10587         if (ret)
10588           return ret;
10589         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10590       }
10591
10592     CASE_FLT_FN (BUILT_IN_ISINF):
10593     case BUILT_IN_ISINFD32:
10594     case BUILT_IN_ISINFD64:
10595     case BUILT_IN_ISINFD128:
10596       {
10597         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10598         if (ret)
10599           return ret;
10600         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10601       }
10602
10603     case BUILT_IN_ISNORMAL:
10604       return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10605
10606     case BUILT_IN_ISINF_SIGN:
10607       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10608
10609     CASE_FLT_FN (BUILT_IN_ISNAN):
10610     case BUILT_IN_ISNAND32:
10611     case BUILT_IN_ISNAND64:
10612     case BUILT_IN_ISNAND128:
10613       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10614
10615     case BUILT_IN_PRINTF:
10616     case BUILT_IN_PRINTF_UNLOCKED:
10617     case BUILT_IN_VPRINTF:
10618       return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10619
10620     case BUILT_IN_FREE:
10621       if (integer_zerop (arg0))
10622         return build_empty_stmt (loc);
10623       break;
10624
10625     default:
10626       break;
10627     }
10628
10629   return NULL_TREE;
10630
10631 }
10632
10633 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10634    IGNORE is true if the result of the function call is ignored.  This
10635    function returns NULL_TREE if no simplification was possible.  */
10636
10637 static tree
10638 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10639 {
10640   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10641   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10642
10643   switch (fcode)
10644     {
10645     CASE_FLT_FN (BUILT_IN_JN):
10646       if (validate_arg (arg0, INTEGER_TYPE)
10647           && validate_arg (arg1, REAL_TYPE))
10648         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10649     break;
10650
10651     CASE_FLT_FN (BUILT_IN_YN):
10652       if (validate_arg (arg0, INTEGER_TYPE)
10653           && validate_arg (arg1, REAL_TYPE))
10654         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10655                                  &dconst0, false);
10656     break;
10657
10658     CASE_FLT_FN (BUILT_IN_DREM):
10659     CASE_FLT_FN (BUILT_IN_REMAINDER):
10660       if (validate_arg (arg0, REAL_TYPE)
10661           && validate_arg(arg1, REAL_TYPE))
10662         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10663     break;
10664
10665     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10666     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10667       if (validate_arg (arg0, REAL_TYPE)
10668           && validate_arg(arg1, POINTER_TYPE))
10669         return do_mpfr_lgamma_r (arg0, arg1, type);
10670     break;
10671
10672     CASE_FLT_FN (BUILT_IN_ATAN2):
10673       if (validate_arg (arg0, REAL_TYPE)
10674           && validate_arg(arg1, REAL_TYPE))
10675         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10676     break;
10677
10678     CASE_FLT_FN (BUILT_IN_FDIM):
10679       if (validate_arg (arg0, REAL_TYPE)
10680           && validate_arg(arg1, REAL_TYPE))
10681         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10682     break;
10683
10684     CASE_FLT_FN (BUILT_IN_HYPOT):
10685       return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10686
10687     CASE_FLT_FN (BUILT_IN_CPOW):
10688       if (validate_arg (arg0, COMPLEX_TYPE)
10689           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10690           && validate_arg (arg1, COMPLEX_TYPE)
10691           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10692         return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10693     break;
10694
10695     CASE_FLT_FN (BUILT_IN_LDEXP):
10696       return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10697     CASE_FLT_FN (BUILT_IN_SCALBN):
10698     CASE_FLT_FN (BUILT_IN_SCALBLN):
10699       return fold_builtin_load_exponent (loc, arg0, arg1,
10700                                          type, /*ldexp=*/false);
10701
10702     CASE_FLT_FN (BUILT_IN_FREXP):
10703       return fold_builtin_frexp (loc, arg0, arg1, type);
10704
10705     CASE_FLT_FN (BUILT_IN_MODF):
10706       return fold_builtin_modf (loc, arg0, arg1, type);
10707
10708     case BUILT_IN_BZERO:
10709       return fold_builtin_bzero (loc, arg0, arg1, ignore);
10710
10711     case BUILT_IN_FPUTS:
10712       return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10713
10714     case BUILT_IN_FPUTS_UNLOCKED:
10715       return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10716
10717     case BUILT_IN_STRSTR:
10718       return fold_builtin_strstr (loc, arg0, arg1, type);
10719
10720     case BUILT_IN_STRCAT:
10721       return fold_builtin_strcat (loc, arg0, arg1);
10722
10723     case BUILT_IN_STRSPN:
10724       return fold_builtin_strspn (loc, arg0, arg1);
10725
10726     case BUILT_IN_STRCSPN:
10727       return fold_builtin_strcspn (loc, arg0, arg1);
10728
10729     case BUILT_IN_STRCHR:
10730     case BUILT_IN_INDEX:
10731       return fold_builtin_strchr (loc, arg0, arg1, type);
10732
10733     case BUILT_IN_STRRCHR:
10734     case BUILT_IN_RINDEX:
10735       return fold_builtin_strrchr (loc, arg0, arg1, type);
10736
10737     case BUILT_IN_STRCPY:
10738       return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10739
10740     case BUILT_IN_STPCPY:
10741       if (ignore)
10742         {
10743           tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
10744           if (!fn)
10745             break;
10746
10747           return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10748         }
10749       else
10750         return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10751       break;
10752
10753     case BUILT_IN_STRCMP:
10754       return fold_builtin_strcmp (loc, arg0, arg1);
10755
10756     case BUILT_IN_STRPBRK:
10757       return fold_builtin_strpbrk (loc, arg0, arg1, type);
10758
10759     case BUILT_IN_EXPECT:
10760       return fold_builtin_expect (loc, arg0, arg1);
10761
10762     CASE_FLT_FN (BUILT_IN_POW):
10763       return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10764
10765     CASE_FLT_FN (BUILT_IN_POWI):
10766       return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10767
10768     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10769       return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10770
10771     CASE_FLT_FN (BUILT_IN_FMIN):
10772       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10773
10774     CASE_FLT_FN (BUILT_IN_FMAX):
10775       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10776
10777     case BUILT_IN_ISGREATER:
10778       return fold_builtin_unordered_cmp (loc, fndecl,
10779                                          arg0, arg1, UNLE_EXPR, LE_EXPR);
10780     case BUILT_IN_ISGREATEREQUAL:
10781       return fold_builtin_unordered_cmp (loc, fndecl,
10782                                          arg0, arg1, UNLT_EXPR, LT_EXPR);
10783     case BUILT_IN_ISLESS:
10784       return fold_builtin_unordered_cmp (loc, fndecl,
10785                                          arg0, arg1, UNGE_EXPR, GE_EXPR);
10786     case BUILT_IN_ISLESSEQUAL:
10787       return fold_builtin_unordered_cmp (loc, fndecl,
10788                                          arg0, arg1, UNGT_EXPR, GT_EXPR);
10789     case BUILT_IN_ISLESSGREATER:
10790       return fold_builtin_unordered_cmp (loc, fndecl,
10791                                          arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10792     case BUILT_IN_ISUNORDERED:
10793       return fold_builtin_unordered_cmp (loc, fndecl,
10794                                          arg0, arg1, UNORDERED_EXPR,
10795                                          NOP_EXPR);
10796
10797       /* We do the folding for va_start in the expander.  */
10798     case BUILT_IN_VA_START:
10799       break;
10800
10801     case BUILT_IN_SPRINTF:
10802       return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10803
10804     case BUILT_IN_OBJECT_SIZE:
10805       return fold_builtin_object_size (arg0, arg1);
10806
10807     case BUILT_IN_PRINTF:
10808     case BUILT_IN_PRINTF_UNLOCKED:
10809     case BUILT_IN_VPRINTF:
10810       return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10811
10812     case BUILT_IN_PRINTF_CHK:
10813     case BUILT_IN_VPRINTF_CHK:
10814       if (!validate_arg (arg0, INTEGER_TYPE)
10815           || TREE_SIDE_EFFECTS (arg0))
10816         return NULL_TREE;
10817       else
10818         return fold_builtin_printf (loc, fndecl,
10819                                     arg1, NULL_TREE, ignore, fcode);
10820     break;
10821
10822     case BUILT_IN_FPRINTF:
10823     case BUILT_IN_FPRINTF_UNLOCKED:
10824     case BUILT_IN_VFPRINTF:
10825       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10826                                    ignore, fcode);
10827
10828     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
10829       return fold_builtin_atomic_always_lock_free (arg0, arg1);
10830
10831     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
10832       return fold_builtin_atomic_is_lock_free (arg0, arg1);
10833
10834     default:
10835       break;
10836     }
10837   return NULL_TREE;
10838 }
10839
10840 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10841    and ARG2.  IGNORE is true if the result of the function call is ignored.
10842    This function returns NULL_TREE if no simplification was possible.  */
10843
10844 static tree
10845 fold_builtin_3 (location_t loc, tree fndecl,
10846                 tree arg0, tree arg1, tree arg2, bool ignore)
10847 {
10848   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10849   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10850   switch (fcode)
10851     {
10852
10853     CASE_FLT_FN (BUILT_IN_SINCOS):
10854       return fold_builtin_sincos (loc, arg0, arg1, arg2);
10855
10856     CASE_FLT_FN (BUILT_IN_FMA):
10857       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
10858     break;
10859
10860     CASE_FLT_FN (BUILT_IN_REMQUO):
10861       if (validate_arg (arg0, REAL_TYPE)
10862           && validate_arg(arg1, REAL_TYPE)
10863           && validate_arg(arg2, POINTER_TYPE))
10864         return do_mpfr_remquo (arg0, arg1, arg2);
10865     break;
10866
10867     case BUILT_IN_MEMSET:
10868       return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10869
10870     case BUILT_IN_BCOPY:
10871       return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10872                                      void_type_node, true, /*endp=*/3);
10873
10874     case BUILT_IN_MEMCPY:
10875       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10876                                      type, ignore, /*endp=*/0);
10877
10878     case BUILT_IN_MEMPCPY:
10879       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10880                                      type, ignore, /*endp=*/1);
10881
10882     case BUILT_IN_MEMMOVE:
10883       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10884                                      type, ignore, /*endp=*/3);
10885
10886     case BUILT_IN_STRNCAT:
10887       return fold_builtin_strncat (loc, arg0, arg1, arg2);
10888
10889     case BUILT_IN_STRNCPY:
10890       return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10891
10892     case BUILT_IN_STRNCMP:
10893       return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10894
10895     case BUILT_IN_MEMCHR:
10896       return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10897
10898     case BUILT_IN_BCMP:
10899     case BUILT_IN_MEMCMP:
10900       return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10901
10902     case BUILT_IN_SPRINTF:
10903       return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10904
10905     case BUILT_IN_SNPRINTF:
10906       return fold_builtin_snprintf (loc, arg0, arg1, arg2, NULL_TREE, ignore);
10907
10908     case BUILT_IN_STRCPY_CHK:
10909     case BUILT_IN_STPCPY_CHK:
10910       return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10911                                       ignore, fcode);
10912
10913     case BUILT_IN_STRCAT_CHK:
10914       return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10915
10916     case BUILT_IN_PRINTF_CHK:
10917     case BUILT_IN_VPRINTF_CHK:
10918       if (!validate_arg (arg0, INTEGER_TYPE)
10919           || TREE_SIDE_EFFECTS (arg0))
10920         return NULL_TREE;
10921       else
10922         return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10923     break;
10924
10925     case BUILT_IN_FPRINTF:
10926     case BUILT_IN_FPRINTF_UNLOCKED:
10927     case BUILT_IN_VFPRINTF:
10928       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10929                                    ignore, fcode);
10930
10931     case BUILT_IN_FPRINTF_CHK:
10932     case BUILT_IN_VFPRINTF_CHK:
10933       if (!validate_arg (arg1, INTEGER_TYPE)
10934           || TREE_SIDE_EFFECTS (arg1))
10935         return NULL_TREE;
10936       else
10937         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
10938                                      ignore, fcode);
10939
10940     default:
10941       break;
10942     }
10943   return NULL_TREE;
10944 }
10945
10946 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10947    ARG2, and ARG3.  IGNORE is true if the result of the function call is
10948    ignored.  This function returns NULL_TREE if no simplification was
10949    possible.  */
10950
10951 static tree
10952 fold_builtin_4 (location_t loc, tree fndecl,
10953                 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
10954 {
10955   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10956
10957   switch (fcode)
10958     {
10959     case BUILT_IN_MEMCPY_CHK:
10960     case BUILT_IN_MEMPCPY_CHK:
10961     case BUILT_IN_MEMMOVE_CHK:
10962     case BUILT_IN_MEMSET_CHK:
10963       return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
10964                                       NULL_TREE, ignore,
10965                                       DECL_FUNCTION_CODE (fndecl));
10966
10967     case BUILT_IN_STRNCPY_CHK:
10968     case BUILT_IN_STPNCPY_CHK:
10969       return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE,
10970                                        ignore, fcode);
10971
10972     case BUILT_IN_STRNCAT_CHK:
10973       return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
10974
10975     case BUILT_IN_SNPRINTF:
10976       return fold_builtin_snprintf (loc, arg0, arg1, arg2, arg3, ignore);
10977
10978     case BUILT_IN_FPRINTF_CHK:
10979     case BUILT_IN_VFPRINTF_CHK:
10980       if (!validate_arg (arg1, INTEGER_TYPE)
10981           || TREE_SIDE_EFFECTS (arg1))
10982         return NULL_TREE;
10983       else
10984         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
10985                                      ignore, fcode);
10986     break;
10987
10988     default:
10989       break;
10990     }
10991   return NULL_TREE;
10992 }
10993
10994 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
10995     arguments, where NARGS <= 4.  IGNORE is true if the result of the
10996     function call is ignored.  This function returns NULL_TREE if no
10997     simplification was possible.  Note that this only folds builtins with
10998     fixed argument patterns.  Foldings that do varargs-to-varargs
10999     transformations, or that match calls with more than 4 arguments,
11000     need to be handled with fold_builtin_varargs instead.  */
11001
11002 #define MAX_ARGS_TO_FOLD_BUILTIN 4
11003
11004 static tree
11005 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
11006 {
11007   tree ret = NULL_TREE;
11008
11009   switch (nargs)
11010     {
11011     case 0:
11012       ret = fold_builtin_0 (loc, fndecl, ignore);
11013       break;
11014     case 1:
11015       ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
11016       break;
11017     case 2:
11018       ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
11019       break;
11020     case 3:
11021       ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
11022       break;
11023     case 4:
11024       ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
11025                             ignore);
11026       break;
11027     default:
11028       break;
11029     }
11030   if (ret)
11031     {
11032       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11033       SET_EXPR_LOCATION (ret, loc);
11034       TREE_NO_WARNING (ret) = 1;
11035       return ret;
11036     }
11037   return NULL_TREE;
11038 }
11039
11040 /* Builtins with folding operations that operate on "..." arguments
11041    need special handling; we need to store the arguments in a convenient
11042    data structure before attempting any folding.  Fortunately there are
11043    only a few builtins that fall into this category.  FNDECL is the
11044    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11045    result of the function call is ignored.  */
11046
11047 static tree
11048 fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11049                       bool ignore ATTRIBUTE_UNUSED)
11050 {
11051   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11052   tree ret = NULL_TREE;
11053
11054   switch (fcode)
11055     {
11056     case BUILT_IN_SPRINTF_CHK:
11057     case BUILT_IN_VSPRINTF_CHK:
11058       ret = fold_builtin_sprintf_chk (loc, exp, fcode);
11059       break;
11060
11061     case BUILT_IN_SNPRINTF_CHK:
11062     case BUILT_IN_VSNPRINTF_CHK:
11063       ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
11064       break;
11065
11066     case BUILT_IN_FPCLASSIFY:
11067       ret = fold_builtin_fpclassify (loc, exp);
11068       break;
11069
11070     default:
11071       break;
11072     }
11073   if (ret)
11074     {
11075       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11076       SET_EXPR_LOCATION (ret, loc);
11077       TREE_NO_WARNING (ret) = 1;
11078       return ret;
11079     }
11080   return NULL_TREE;
11081 }
11082
11083 /* Return true if FNDECL shouldn't be folded right now.
11084    If a built-in function has an inline attribute always_inline
11085    wrapper, defer folding it after always_inline functions have
11086    been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11087    might not be performed.  */
11088
11089 bool
11090 avoid_folding_inline_builtin (tree fndecl)
11091 {
11092   return (DECL_DECLARED_INLINE_P (fndecl)
11093           && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11094           && cfun
11095           && !cfun->always_inline_functions_inlined
11096           && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11097 }
11098
11099 /* A wrapper function for builtin folding that prevents warnings for
11100    "statement without effect" and the like, caused by removing the
11101    call node earlier than the warning is generated.  */
11102
11103 tree
11104 fold_call_expr (location_t loc, tree exp, bool ignore)
11105 {
11106   tree ret = NULL_TREE;
11107   tree fndecl = get_callee_fndecl (exp);
11108   if (fndecl
11109       && TREE_CODE (fndecl) == FUNCTION_DECL
11110       && DECL_BUILT_IN (fndecl)
11111       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11112          yet.  Defer folding until we see all the arguments
11113          (after inlining).  */
11114       && !CALL_EXPR_VA_ARG_PACK (exp))
11115     {
11116       int nargs = call_expr_nargs (exp);
11117
11118       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11119          instead last argument is __builtin_va_arg_pack ().  Defer folding
11120          even in that case, until arguments are finalized.  */
11121       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11122         {
11123           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11124           if (fndecl2
11125               && TREE_CODE (fndecl2) == FUNCTION_DECL
11126               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11127               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11128             return NULL_TREE;
11129         }
11130
11131       if (avoid_folding_inline_builtin (fndecl))
11132         return NULL_TREE;
11133
11134       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11135         return targetm.fold_builtin (fndecl, call_expr_nargs (exp),
11136                                      CALL_EXPR_ARGP (exp), ignore);
11137       else
11138         {
11139           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11140             {
11141               tree *args = CALL_EXPR_ARGP (exp);
11142               ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
11143             }
11144           if (!ret)
11145             ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
11146           if (ret)
11147             return ret;
11148         }
11149     }
11150   return NULL_TREE;
11151 }
11152
11153 /* Conveniently construct a function call expression.  FNDECL names the
11154    function to be called and N arguments are passed in the array
11155    ARGARRAY.  */
11156
11157 tree
11158 build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
11159 {
11160   tree fntype = TREE_TYPE (fndecl);
11161   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11162  
11163   return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
11164 }
11165
11166 /* Conveniently construct a function call expression.  FNDECL names the
11167    function to be called and the arguments are passed in the vector
11168    VEC.  */
11169
11170 tree
11171 build_call_expr_loc_vec (location_t loc, tree fndecl, VEC(tree,gc) *vec)
11172 {
11173   return build_call_expr_loc_array (loc, fndecl, VEC_length (tree, vec),
11174                                     VEC_address (tree, vec));
11175 }
11176
11177
11178 /* Conveniently construct a function call expression.  FNDECL names the
11179    function to be called, N is the number of arguments, and the "..."
11180    parameters are the argument expressions.  */
11181
11182 tree
11183 build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
11184 {
11185   va_list ap;
11186   tree *argarray = XALLOCAVEC (tree, n);
11187   int i;
11188
11189   va_start (ap, n);
11190   for (i = 0; i < n; i++)
11191     argarray[i] = va_arg (ap, tree);
11192   va_end (ap);
11193   return build_call_expr_loc_array (loc, fndecl, n, argarray);
11194 }
11195
11196 /* Like build_call_expr_loc (UNKNOWN_LOCATION, ...).  Duplicated because
11197    varargs macros aren't supported by all bootstrap compilers.  */
11198
11199 tree
11200 build_call_expr (tree fndecl, int n, ...)
11201 {
11202   va_list ap;
11203   tree *argarray = XALLOCAVEC (tree, n);
11204   int i;
11205
11206   va_start (ap, n);
11207   for (i = 0; i < n; i++)
11208     argarray[i] = va_arg (ap, tree);
11209   va_end (ap);
11210   return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
11211 }
11212
11213 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
11214    N arguments are passed in the array ARGARRAY.  */
11215
11216 tree
11217 fold_builtin_call_array (location_t loc, tree type,
11218                          tree fn,
11219                          int n,
11220                          tree *argarray)
11221 {
11222   tree ret = NULL_TREE;
11223    tree exp;
11224
11225   if (TREE_CODE (fn) == ADDR_EXPR)
11226   {
11227     tree fndecl = TREE_OPERAND (fn, 0);
11228     if (TREE_CODE (fndecl) == FUNCTION_DECL
11229         && DECL_BUILT_IN (fndecl))
11230       {
11231         /* If last argument is __builtin_va_arg_pack (), arguments to this
11232            function are not finalized yet.  Defer folding until they are.  */
11233         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11234           {
11235             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11236             if (fndecl2
11237                 && TREE_CODE (fndecl2) == FUNCTION_DECL
11238                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11239                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11240               return build_call_array_loc (loc, type, fn, n, argarray);
11241           }
11242         if (avoid_folding_inline_builtin (fndecl))
11243           return build_call_array_loc (loc, type, fn, n, argarray);
11244         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11245           {
11246             ret = targetm.fold_builtin (fndecl, n, argarray, false);
11247             if (ret)
11248               return ret;
11249
11250             return build_call_array_loc (loc, type, fn, n, argarray);
11251           }
11252         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11253           {
11254             /* First try the transformations that don't require consing up
11255                an exp.  */
11256             ret = fold_builtin_n (loc, fndecl, argarray, n, false);
11257             if (ret)
11258               return ret;
11259           }
11260
11261         /* If we got this far, we need to build an exp.  */
11262         exp = build_call_array_loc (loc, type, fn, n, argarray);
11263         ret = fold_builtin_varargs (loc, fndecl, exp, false);
11264         return ret ? ret : exp;
11265       }
11266   }
11267
11268   return build_call_array_loc (loc, type, fn, n, argarray);
11269 }
11270
11271 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11272    list ARGS along with N new arguments in NEWARGS.  SKIP is the number
11273    of arguments in ARGS to be omitted.  OLDNARGS is the number of
11274    elements in ARGS.  */
11275
11276 static tree
11277 rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
11278                           int skip, tree fndecl, int n, va_list newargs)
11279 {
11280   int nargs = oldnargs - skip + n;
11281   tree *buffer;
11282
11283   if (n > 0)
11284     {
11285       int i, j;
11286
11287       buffer = XALLOCAVEC (tree, nargs);
11288       for (i = 0; i < n; i++)
11289         buffer[i] = va_arg (newargs, tree);
11290       for (j = skip; j < oldnargs; j++, i++)
11291         buffer[i] = args[j];
11292     }
11293   else
11294     buffer = args + skip;
11295
11296   return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
11297 }
11298
11299 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11300    list ARGS along with N new arguments specified as the "..."
11301    parameters.  SKIP is the number of arguments in ARGS to be omitted.
11302    OLDNARGS is the number of elements in ARGS.  */
11303
11304 static tree
11305 rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
11306                          int skip, tree fndecl, int n, ...)
11307 {
11308   va_list ap;
11309   tree t;
11310
11311   va_start (ap, n);
11312   t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
11313   va_end (ap);
11314
11315   return t;
11316 }
11317
11318 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
11319    along with N new arguments specified as the "..." parameters.  SKIP
11320    is the number of arguments in EXP to be omitted.  This function is used
11321    to do varargs-to-varargs transformations.  */
11322
11323 static tree
11324 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
11325 {
11326   va_list ap;
11327   tree t;
11328
11329   va_start (ap, n);
11330   t = rewrite_call_expr_valist (loc, call_expr_nargs (exp),
11331                                 CALL_EXPR_ARGP (exp), skip, fndecl, n, ap);
11332   va_end (ap);
11333
11334   return t;
11335 }
11336
11337 /* Validate a single argument ARG against a tree code CODE representing
11338    a type.  */
11339
11340 static bool
11341 validate_arg (const_tree arg, enum tree_code code)
11342 {
11343   if (!arg)
11344     return false;
11345   else if (code == POINTER_TYPE)
11346     return POINTER_TYPE_P (TREE_TYPE (arg));
11347   else if (code == INTEGER_TYPE)
11348     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11349   return code == TREE_CODE (TREE_TYPE (arg));
11350 }
11351
11352 /* This function validates the types of a function call argument list
11353    against a specified list of tree_codes.  If the last specifier is a 0,
11354    that represents an ellipses, otherwise the last specifier must be a
11355    VOID_TYPE.
11356
11357    This is the GIMPLE version of validate_arglist.  Eventually we want to
11358    completely convert builtins.c to work from GIMPLEs and the tree based
11359    validate_arglist will then be removed.  */
11360
11361 bool
11362 validate_gimple_arglist (const_gimple call, ...)
11363 {
11364   enum tree_code code;
11365   bool res = 0;
11366   va_list ap;
11367   const_tree arg;
11368   size_t i;
11369
11370   va_start (ap, call);
11371   i = 0;
11372
11373   do
11374     {
11375       code = (enum tree_code) va_arg (ap, int);
11376       switch (code)
11377         {
11378         case 0:
11379           /* This signifies an ellipses, any further arguments are all ok.  */
11380           res = true;
11381           goto end;
11382         case VOID_TYPE:
11383           /* This signifies an endlink, if no arguments remain, return
11384              true, otherwise return false.  */
11385           res = (i == gimple_call_num_args (call));
11386           goto end;
11387         default:
11388           /* If no parameters remain or the parameter's code does not
11389              match the specified code, return false.  Otherwise continue
11390              checking any remaining arguments.  */
11391           arg = gimple_call_arg (call, i++);
11392           if (!validate_arg (arg, code))
11393             goto end;
11394           break;
11395         }
11396     }
11397   while (1);
11398
11399   /* We need gotos here since we can only have one VA_CLOSE in a
11400      function.  */
11401  end: ;
11402   va_end (ap);
11403
11404   return res;
11405 }
11406
11407 /* This function validates the types of a function call argument list
11408    against a specified list of tree_codes.  If the last specifier is a 0,
11409    that represents an ellipses, otherwise the last specifier must be a
11410    VOID_TYPE.  */
11411
11412 bool
11413 validate_arglist (const_tree callexpr, ...)
11414 {
11415   enum tree_code code;
11416   bool res = 0;
11417   va_list ap;
11418   const_call_expr_arg_iterator iter;
11419   const_tree arg;
11420
11421   va_start (ap, callexpr);
11422   init_const_call_expr_arg_iterator (callexpr, &iter);
11423
11424   do
11425     {
11426       code = (enum tree_code) va_arg (ap, int);
11427       switch (code)
11428         {
11429         case 0:
11430           /* This signifies an ellipses, any further arguments are all ok.  */
11431           res = true;
11432           goto end;
11433         case VOID_TYPE:
11434           /* This signifies an endlink, if no arguments remain, return
11435              true, otherwise return false.  */
11436           res = !more_const_call_expr_args_p (&iter);
11437           goto end;
11438         default:
11439           /* If no parameters remain or the parameter's code does not
11440              match the specified code, return false.  Otherwise continue
11441              checking any remaining arguments.  */
11442           arg = next_const_call_expr_arg (&iter);
11443           if (!validate_arg (arg, code))
11444             goto end;
11445           break;
11446         }
11447     }
11448   while (1);
11449
11450   /* We need gotos here since we can only have one VA_CLOSE in a
11451      function.  */
11452  end: ;
11453   va_end (ap);
11454
11455   return res;
11456 }
11457
11458 /* Default target-specific builtin expander that does nothing.  */
11459
11460 rtx
11461 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11462                         rtx target ATTRIBUTE_UNUSED,
11463                         rtx subtarget ATTRIBUTE_UNUSED,
11464                         enum machine_mode mode ATTRIBUTE_UNUSED,
11465                         int ignore ATTRIBUTE_UNUSED)
11466 {
11467   return NULL_RTX;
11468 }
11469
11470 /* Returns true is EXP represents data that would potentially reside
11471    in a readonly section.  */
11472
11473 static bool
11474 readonly_data_expr (tree exp)
11475 {
11476   STRIP_NOPS (exp);
11477
11478   if (TREE_CODE (exp) != ADDR_EXPR)
11479     return false;
11480
11481   exp = get_base_address (TREE_OPERAND (exp, 0));
11482   if (!exp)
11483     return false;
11484
11485   /* Make sure we call decl_readonly_section only for trees it
11486      can handle (since it returns true for everything it doesn't
11487      understand).  */
11488   if (TREE_CODE (exp) == STRING_CST
11489       || TREE_CODE (exp) == CONSTRUCTOR
11490       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11491     return decl_readonly_section (exp, 0);
11492   else
11493     return false;
11494 }
11495
11496 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11497    to the call, and TYPE is its return type.
11498
11499    Return NULL_TREE if no simplification was possible, otherwise return the
11500    simplified form of the call as a tree.
11501
11502    The simplified form may be a constant or other expression which
11503    computes the same value, but in a more efficient manner (including
11504    calls to other builtin functions).
11505
11506    The call may contain arguments which need to be evaluated, but
11507    which are not useful to determine the result of the call.  In
11508    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11509    COMPOUND_EXPR will be an argument which must be evaluated.
11510    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11511    COMPOUND_EXPR in the chain will contain the tree for the simplified
11512    form of the builtin function call.  */
11513
11514 static tree
11515 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11516 {
11517   if (!validate_arg (s1, POINTER_TYPE)
11518       || !validate_arg (s2, POINTER_TYPE))
11519     return NULL_TREE;
11520   else
11521     {
11522       tree fn;
11523       const char *p1, *p2;
11524
11525       p2 = c_getstr (s2);
11526       if (p2 == NULL)
11527         return NULL_TREE;
11528
11529       p1 = c_getstr (s1);
11530       if (p1 != NULL)
11531         {
11532           const char *r = strstr (p1, p2);
11533           tree tem;
11534
11535           if (r == NULL)
11536             return build_int_cst (TREE_TYPE (s1), 0);
11537
11538           /* Return an offset into the constant string argument.  */
11539           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11540           return fold_convert_loc (loc, type, tem);
11541         }
11542
11543       /* The argument is const char *, and the result is char *, so we need
11544          a type conversion here to avoid a warning.  */
11545       if (p2[0] == '\0')
11546         return fold_convert_loc (loc, type, s1);
11547
11548       if (p2[1] != '\0')
11549         return NULL_TREE;
11550
11551       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11552       if (!fn)
11553         return NULL_TREE;
11554
11555       /* New argument list transforming strstr(s1, s2) to
11556          strchr(s1, s2[0]).  */
11557       return build_call_expr_loc (loc, fn, 2, s1,
11558                                   build_int_cst (integer_type_node, p2[0]));
11559     }
11560 }
11561
11562 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11563    the call, and TYPE is its return type.
11564
11565    Return NULL_TREE if no simplification was possible, otherwise return the
11566    simplified form of the call as a tree.
11567
11568    The simplified form may be a constant or other expression which
11569    computes the same value, but in a more efficient manner (including
11570    calls to other builtin functions).
11571
11572    The call may contain arguments which need to be evaluated, but
11573    which are not useful to determine the result of the call.  In
11574    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11575    COMPOUND_EXPR will be an argument which must be evaluated.
11576    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11577    COMPOUND_EXPR in the chain will contain the tree for the simplified
11578    form of the builtin function call.  */
11579
11580 static tree
11581 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11582 {
11583   if (!validate_arg (s1, POINTER_TYPE)
11584       || !validate_arg (s2, INTEGER_TYPE))
11585     return NULL_TREE;
11586   else
11587     {
11588       const char *p1;
11589
11590       if (TREE_CODE (s2) != INTEGER_CST)
11591         return NULL_TREE;
11592
11593       p1 = c_getstr (s1);
11594       if (p1 != NULL)
11595         {
11596           char c;
11597           const char *r;
11598           tree tem;
11599
11600           if (target_char_cast (s2, &c))
11601             return NULL_TREE;
11602
11603           r = strchr (p1, c);
11604
11605           if (r == NULL)
11606             return build_int_cst (TREE_TYPE (s1), 0);
11607
11608           /* Return an offset into the constant string argument.  */
11609           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11610           return fold_convert_loc (loc, type, tem);
11611         }
11612       return NULL_TREE;
11613     }
11614 }
11615
11616 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11617    the call, and TYPE is its return type.
11618
11619    Return NULL_TREE if no simplification was possible, otherwise return the
11620    simplified form of the call as a tree.
11621
11622    The simplified form may be a constant or other expression which
11623    computes the same value, but in a more efficient manner (including
11624    calls to other builtin functions).
11625
11626    The call may contain arguments which need to be evaluated, but
11627    which are not useful to determine the result of the call.  In
11628    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11629    COMPOUND_EXPR will be an argument which must be evaluated.
11630    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11631    COMPOUND_EXPR in the chain will contain the tree for the simplified
11632    form of the builtin function call.  */
11633
11634 static tree
11635 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11636 {
11637   if (!validate_arg (s1, POINTER_TYPE)
11638       || !validate_arg (s2, INTEGER_TYPE))
11639     return NULL_TREE;
11640   else
11641     {
11642       tree fn;
11643       const char *p1;
11644
11645       if (TREE_CODE (s2) != INTEGER_CST)
11646         return NULL_TREE;
11647
11648       p1 = c_getstr (s1);
11649       if (p1 != NULL)
11650         {
11651           char c;
11652           const char *r;
11653           tree tem;
11654
11655           if (target_char_cast (s2, &c))
11656             return NULL_TREE;
11657
11658           r = strrchr (p1, c);
11659
11660           if (r == NULL)
11661             return build_int_cst (TREE_TYPE (s1), 0);
11662
11663           /* Return an offset into the constant string argument.  */
11664           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11665           return fold_convert_loc (loc, type, tem);
11666         }
11667
11668       if (! integer_zerop (s2))
11669         return NULL_TREE;
11670
11671       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11672       if (!fn)
11673         return NULL_TREE;
11674
11675       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11676       return build_call_expr_loc (loc, fn, 2, s1, s2);
11677     }
11678 }
11679
11680 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11681    to the call, and TYPE is its return type.
11682
11683    Return NULL_TREE if no simplification was possible, otherwise return the
11684    simplified form of the call as a tree.
11685
11686    The simplified form may be a constant or other expression which
11687    computes the same value, but in a more efficient manner (including
11688    calls to other builtin functions).
11689
11690    The call may contain arguments which need to be evaluated, but
11691    which are not useful to determine the result of the call.  In
11692    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11693    COMPOUND_EXPR will be an argument which must be evaluated.
11694    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11695    COMPOUND_EXPR in the chain will contain the tree for the simplified
11696    form of the builtin function call.  */
11697
11698 static tree
11699 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11700 {
11701   if (!validate_arg (s1, POINTER_TYPE)
11702       || !validate_arg (s2, POINTER_TYPE))
11703     return NULL_TREE;
11704   else
11705     {
11706       tree fn;
11707       const char *p1, *p2;
11708
11709       p2 = c_getstr (s2);
11710       if (p2 == NULL)
11711         return NULL_TREE;
11712
11713       p1 = c_getstr (s1);
11714       if (p1 != NULL)
11715         {
11716           const char *r = strpbrk (p1, p2);
11717           tree tem;
11718
11719           if (r == NULL)
11720             return build_int_cst (TREE_TYPE (s1), 0);
11721
11722           /* Return an offset into the constant string argument.  */
11723           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11724           return fold_convert_loc (loc, type, tem);
11725         }
11726
11727       if (p2[0] == '\0')
11728         /* strpbrk(x, "") == NULL.
11729            Evaluate and ignore s1 in case it had side-effects.  */
11730         return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11731
11732       if (p2[1] != '\0')
11733         return NULL_TREE;  /* Really call strpbrk.  */
11734
11735       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11736       if (!fn)
11737         return NULL_TREE;
11738
11739       /* New argument list transforming strpbrk(s1, s2) to
11740          strchr(s1, s2[0]).  */
11741       return build_call_expr_loc (loc, fn, 2, s1,
11742                                   build_int_cst (integer_type_node, p2[0]));
11743     }
11744 }
11745
11746 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11747    to the call.
11748
11749    Return NULL_TREE if no simplification was possible, otherwise return the
11750    simplified form of the call as a tree.
11751
11752    The simplified form may be a constant or other expression which
11753    computes the same value, but in a more efficient manner (including
11754    calls to other builtin functions).
11755
11756    The call may contain arguments which need to be evaluated, but
11757    which are not useful to determine the result of the call.  In
11758    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11759    COMPOUND_EXPR will be an argument which must be evaluated.
11760    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11761    COMPOUND_EXPR in the chain will contain the tree for the simplified
11762    form of the builtin function call.  */
11763
11764 static tree
11765 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11766 {
11767   if (!validate_arg (dst, POINTER_TYPE)
11768       || !validate_arg (src, POINTER_TYPE))
11769     return NULL_TREE;
11770   else
11771     {
11772       const char *p = c_getstr (src);
11773
11774       /* If the string length is zero, return the dst parameter.  */
11775       if (p && *p == '\0')
11776         return dst;
11777
11778       if (optimize_insn_for_speed_p ())
11779         {
11780           /* See if we can store by pieces into (dst + strlen(dst)).  */
11781           tree newdst, call;
11782           tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11783           tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
11784
11785           if (!strlen_fn || !strcpy_fn)
11786             return NULL_TREE;
11787
11788           /* If we don't have a movstr we don't want to emit an strcpy
11789              call.  We have to do that if the length of the source string
11790              isn't computable (in that case we can use memcpy probably
11791              later expanding to a sequence of mov instructions).  If we
11792              have movstr instructions we can emit strcpy calls.  */
11793           if (!HAVE_movstr)
11794             {
11795               tree len = c_strlen (src, 1);
11796               if (! len || TREE_SIDE_EFFECTS (len))
11797                 return NULL_TREE;
11798             }
11799
11800           /* Stabilize the argument list.  */
11801           dst = builtin_save_expr (dst);
11802
11803           /* Create strlen (dst).  */
11804           newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11805           /* Create (dst p+ strlen (dst)).  */
11806
11807           newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
11808           newdst = builtin_save_expr (newdst);
11809
11810           call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11811           return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11812         }
11813       return NULL_TREE;
11814     }
11815 }
11816
11817 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11818    arguments to the call.
11819
11820    Return NULL_TREE if no simplification was possible, otherwise return the
11821    simplified form of the call as a tree.
11822
11823    The simplified form may be a constant or other expression which
11824    computes the same value, but in a more efficient manner (including
11825    calls to other builtin functions).
11826
11827    The call may contain arguments which need to be evaluated, but
11828    which are not useful to determine the result of the call.  In
11829    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11830    COMPOUND_EXPR will be an argument which must be evaluated.
11831    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11832    COMPOUND_EXPR in the chain will contain the tree for the simplified
11833    form of the builtin function call.  */
11834
11835 static tree
11836 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11837 {
11838   if (!validate_arg (dst, POINTER_TYPE)
11839       || !validate_arg (src, POINTER_TYPE)
11840       || !validate_arg (len, INTEGER_TYPE))
11841     return NULL_TREE;
11842   else
11843     {
11844       const char *p = c_getstr (src);
11845
11846       /* If the requested length is zero, or the src parameter string
11847          length is zero, return the dst parameter.  */
11848       if (integer_zerop (len) || (p && *p == '\0'))
11849         return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11850
11851       /* If the requested len is greater than or equal to the string
11852          length, call strcat.  */
11853       if (TREE_CODE (len) == INTEGER_CST && p
11854           && compare_tree_int (len, strlen (p)) >= 0)
11855         {
11856           tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
11857
11858           /* If the replacement _DECL isn't initialized, don't do the
11859              transformation.  */
11860           if (!fn)
11861             return NULL_TREE;
11862
11863           return build_call_expr_loc (loc, fn, 2, dst, src);
11864         }
11865       return NULL_TREE;
11866     }
11867 }
11868
11869 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11870    to the call.
11871
11872    Return NULL_TREE if no simplification was possible, otherwise return the
11873    simplified form of the call as a tree.
11874
11875    The simplified form may be a constant or other expression which
11876    computes the same value, but in a more efficient manner (including
11877    calls to other builtin functions).
11878
11879    The call may contain arguments which need to be evaluated, but
11880    which are not useful to determine the result of the call.  In
11881    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11882    COMPOUND_EXPR will be an argument which must be evaluated.
11883    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11884    COMPOUND_EXPR in the chain will contain the tree for the simplified
11885    form of the builtin function call.  */
11886
11887 static tree
11888 fold_builtin_strspn (location_t loc, tree s1, tree s2)
11889 {
11890   if (!validate_arg (s1, POINTER_TYPE)
11891       || !validate_arg (s2, POINTER_TYPE))
11892     return NULL_TREE;
11893   else
11894     {
11895       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11896
11897       /* If both arguments are constants, evaluate at compile-time.  */
11898       if (p1 && p2)
11899         {
11900           const size_t r = strspn (p1, p2);
11901           return size_int (r);
11902         }
11903
11904       /* If either argument is "", return NULL_TREE.  */
11905       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11906         /* Evaluate and ignore both arguments in case either one has
11907            side-effects.  */
11908         return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11909                                   s1, s2);
11910       return NULL_TREE;
11911     }
11912 }
11913
11914 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11915    to the call.
11916
11917    Return NULL_TREE if no simplification was possible, otherwise return the
11918    simplified form of the call as a tree.
11919
11920    The simplified form may be a constant or other expression which
11921    computes the same value, but in a more efficient manner (including
11922    calls to other builtin functions).
11923
11924    The call may contain arguments which need to be evaluated, but
11925    which are not useful to determine the result of the call.  In
11926    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11927    COMPOUND_EXPR will be an argument which must be evaluated.
11928    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11929    COMPOUND_EXPR in the chain will contain the tree for the simplified
11930    form of the builtin function call.  */
11931
11932 static tree
11933 fold_builtin_strcspn (location_t loc, tree s1, tree s2)
11934 {
11935   if (!validate_arg (s1, POINTER_TYPE)
11936       || !validate_arg (s2, POINTER_TYPE))
11937     return NULL_TREE;
11938   else
11939     {
11940       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11941
11942       /* If both arguments are constants, evaluate at compile-time.  */
11943       if (p1 && p2)
11944         {
11945           const size_t r = strcspn (p1, p2);
11946           return size_int (r);
11947         }
11948
11949       /* If the first argument is "", return NULL_TREE.  */
11950       if (p1 && *p1 == '\0')
11951         {
11952           /* Evaluate and ignore argument s2 in case it has
11953              side-effects.  */
11954           return omit_one_operand_loc (loc, size_type_node,
11955                                    size_zero_node, s2);
11956         }
11957
11958       /* If the second argument is "", return __builtin_strlen(s1).  */
11959       if (p2 && *p2 == '\0')
11960         {
11961           tree fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11962
11963           /* If the replacement _DECL isn't initialized, don't do the
11964              transformation.  */
11965           if (!fn)
11966             return NULL_TREE;
11967
11968           return build_call_expr_loc (loc, fn, 1, s1);
11969         }
11970       return NULL_TREE;
11971     }
11972 }
11973
11974 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
11975    to the call.  IGNORE is true if the value returned
11976    by the builtin will be ignored.  UNLOCKED is true is true if this
11977    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
11978    the known length of the string.  Return NULL_TREE if no simplification
11979    was possible.  */
11980
11981 tree
11982 fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11983                     bool ignore, bool unlocked, tree len)
11984 {
11985   /* If we're using an unlocked function, assume the other unlocked
11986      functions exist explicitly.  */
11987   tree const fn_fputc = (unlocked
11988                          ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
11989                          : builtin_decl_implicit (BUILT_IN_FPUTC));
11990   tree const fn_fwrite = (unlocked
11991                           ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
11992                           : builtin_decl_implicit (BUILT_IN_FWRITE));
11993
11994   /* If the return value is used, don't do the transformation.  */
11995   if (!ignore)
11996     return NULL_TREE;
11997
11998   /* Verify the arguments in the original call.  */
11999   if (!validate_arg (arg0, POINTER_TYPE)
12000       || !validate_arg (arg1, POINTER_TYPE))
12001     return NULL_TREE;
12002
12003   if (! len)
12004     len = c_strlen (arg0, 0);
12005
12006   /* Get the length of the string passed to fputs.  If the length
12007      can't be determined, punt.  */
12008   if (!len
12009       || TREE_CODE (len) != INTEGER_CST)
12010     return NULL_TREE;
12011
12012   switch (compare_tree_int (len, 1))
12013     {
12014     case -1: /* length is 0, delete the call entirely .  */
12015       return omit_one_operand_loc (loc, integer_type_node,
12016                                integer_zero_node, arg1);;
12017
12018     case 0: /* length is 1, call fputc.  */
12019       {
12020         const char *p = c_getstr (arg0);
12021
12022         if (p != NULL)
12023           {
12024             if (fn_fputc)
12025               return build_call_expr_loc (loc, fn_fputc, 2,
12026                                           build_int_cst
12027                                             (integer_type_node, p[0]), arg1);
12028             else
12029               return NULL_TREE;
12030           }
12031       }
12032       /* FALLTHROUGH */
12033     case 1: /* length is greater than 1, call fwrite.  */
12034       {
12035         /* If optimizing for size keep fputs.  */
12036         if (optimize_function_for_size_p (cfun))
12037           return NULL_TREE;
12038         /* New argument list transforming fputs(string, stream) to
12039            fwrite(string, 1, len, stream).  */
12040         if (fn_fwrite)
12041           return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12042                                   size_one_node, len, arg1);
12043         else
12044           return NULL_TREE;
12045       }
12046     default:
12047       gcc_unreachable ();
12048     }
12049   return NULL_TREE;
12050 }
12051
12052 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
12053    produced.  False otherwise.  This is done so that we don't output the error
12054    or warning twice or three times.  */
12055
12056 bool
12057 fold_builtin_next_arg (tree exp, bool va_start_p)
12058 {
12059   tree fntype = TREE_TYPE (current_function_decl);
12060   int nargs = call_expr_nargs (exp);
12061   tree arg;
12062
12063   if (!stdarg_p (fntype))
12064     {
12065       error ("%<va_start%> used in function with fixed args");
12066       return true;
12067     }
12068
12069   if (va_start_p)
12070     {
12071       if (va_start_p && (nargs != 2))
12072         {
12073           error ("wrong number of arguments to function %<va_start%>");
12074           return true;
12075         }
12076       arg = CALL_EXPR_ARG (exp, 1);
12077     }
12078   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12079      when we checked the arguments and if needed issued a warning.  */
12080   else
12081     {
12082       if (nargs == 0)
12083         {
12084           /* Evidently an out of date version of <stdarg.h>; can't validate
12085              va_start's second argument, but can still work as intended.  */
12086           warning (0, "%<__builtin_next_arg%> called without an argument");
12087           return true;
12088         }
12089       else if (nargs > 1)
12090         {
12091           error ("wrong number of arguments to function %<__builtin_next_arg%>");
12092           return true;
12093         }
12094       arg = CALL_EXPR_ARG (exp, 0);
12095     }
12096
12097   if (TREE_CODE (arg) == SSA_NAME)
12098     arg = SSA_NAME_VAR (arg);
12099
12100   /* We destructively modify the call to be __builtin_va_start (ap, 0)
12101      or __builtin_next_arg (0) the first time we see it, after checking
12102      the arguments and if needed issuing a warning.  */
12103   if (!integer_zerop (arg))
12104     {
12105       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
12106
12107       /* Strip off all nops for the sake of the comparison.  This
12108          is not quite the same as STRIP_NOPS.  It does more.
12109          We must also strip off INDIRECT_EXPR for C++ reference
12110          parameters.  */
12111       while (CONVERT_EXPR_P (arg)
12112              || TREE_CODE (arg) == INDIRECT_REF)
12113         arg = TREE_OPERAND (arg, 0);
12114       if (arg != last_parm)
12115         {
12116           /* FIXME: Sometimes with the tree optimizers we can get the
12117              not the last argument even though the user used the last
12118              argument.  We just warn and set the arg to be the last
12119              argument so that we will get wrong-code because of
12120              it.  */
12121           warning (0, "second parameter of %<va_start%> not last named argument");
12122         }
12123
12124       /* Undefined by C99 7.15.1.4p4 (va_start):
12125          "If the parameter parmN is declared with the register storage
12126          class, with a function or array type, or with a type that is
12127          not compatible with the type that results after application of
12128          the default argument promotions, the behavior is undefined."
12129       */
12130       else if (DECL_REGISTER (arg))
12131         warning (0, "undefined behaviour when second parameter of "
12132                  "%<va_start%> is declared with %<register%> storage");
12133
12134       /* We want to verify the second parameter just once before the tree
12135          optimizers are run and then avoid keeping it in the tree,
12136          as otherwise we could warn even for correct code like:
12137          void foo (int i, ...)
12138          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
12139       if (va_start_p)
12140         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12141       else
12142         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
12143     }
12144   return false;
12145 }
12146
12147
12148 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12149    ORIG may be null if this is a 2-argument call.  We don't attempt to
12150    simplify calls with more than 3 arguments.
12151
12152    Return NULL_TREE if no simplification was possible, otherwise return the
12153    simplified form of the call as a tree.  If IGNORED is true, it means that
12154    the caller does not use the returned value of the function.  */
12155
12156 static tree
12157 fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12158                       tree orig, int ignored)
12159 {
12160   tree call, retval;
12161   const char *fmt_str = NULL;
12162
12163   /* Verify the required arguments in the original call.  We deal with two
12164      types of sprintf() calls: 'sprintf (str, fmt)' and
12165      'sprintf (dest, "%s", orig)'.  */
12166   if (!validate_arg (dest, POINTER_TYPE)
12167       || !validate_arg (fmt, POINTER_TYPE))
12168     return NULL_TREE;
12169   if (orig && !validate_arg (orig, POINTER_TYPE))
12170     return NULL_TREE;
12171
12172   /* Check whether the format is a literal string constant.  */
12173   fmt_str = c_getstr (fmt);
12174   if (fmt_str == NULL)
12175     return NULL_TREE;
12176
12177   call = NULL_TREE;
12178   retval = NULL_TREE;
12179
12180   if (!init_target_chars ())
12181     return NULL_TREE;
12182
12183   /* If the format doesn't contain % args or %%, use strcpy.  */
12184   if (strchr (fmt_str, target_percent) == NULL)
12185     {
12186       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12187
12188       if (!fn)
12189         return NULL_TREE;
12190
12191       /* Don't optimize sprintf (buf, "abc", ptr++).  */
12192       if (orig)
12193         return NULL_TREE;
12194
12195       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12196          'format' is known to contain no % formats.  */
12197       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12198       if (!ignored)
12199         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12200     }
12201
12202   /* If the format is "%s", use strcpy if the result isn't used.  */
12203   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12204     {
12205       tree fn;
12206       fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12207
12208       if (!fn)
12209         return NULL_TREE;
12210
12211       /* Don't crash on sprintf (str1, "%s").  */
12212       if (!orig)
12213         return NULL_TREE;
12214
12215       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
12216       if (!ignored)
12217         {
12218           retval = c_strlen (orig, 1);
12219           if (!retval || TREE_CODE (retval) != INTEGER_CST)
12220             return NULL_TREE;
12221         }
12222       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12223     }
12224
12225   if (call && retval)
12226     {
12227       retval = fold_convert_loc
12228         (loc, TREE_TYPE (TREE_TYPE (builtin_decl_implicit (BUILT_IN_SPRINTF))),
12229          retval);
12230       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12231     }
12232   else
12233     return call;
12234 }
12235
12236 /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
12237    FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
12238    attempt to simplify calls with more than 4 arguments.
12239
12240    Return NULL_TREE if no simplification was possible, otherwise return the
12241    simplified form of the call as a tree.  If IGNORED is true, it means that
12242    the caller does not use the returned value of the function.  */
12243
12244 static tree
12245 fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
12246                        tree orig, int ignored)
12247 {
12248   tree call, retval;
12249   const char *fmt_str = NULL;
12250   unsigned HOST_WIDE_INT destlen;
12251
12252   /* Verify the required arguments in the original call.  We deal with two
12253      types of snprintf() calls: 'snprintf (str, cst, fmt)' and
12254      'snprintf (dest, cst, "%s", orig)'.  */
12255   if (!validate_arg (dest, POINTER_TYPE)
12256       || !validate_arg (destsize, INTEGER_TYPE)
12257       || !validate_arg (fmt, POINTER_TYPE))
12258     return NULL_TREE;
12259   if (orig && !validate_arg (orig, POINTER_TYPE))
12260     return NULL_TREE;
12261
12262   if (!host_integerp (destsize, 1))
12263     return NULL_TREE;
12264
12265   /* Check whether the format is a literal string constant.  */
12266   fmt_str = c_getstr (fmt);
12267   if (fmt_str == NULL)
12268     return NULL_TREE;
12269
12270   call = NULL_TREE;
12271   retval = NULL_TREE;
12272
12273   if (!init_target_chars ())
12274     return NULL_TREE;
12275
12276   destlen = tree_low_cst (destsize, 1);
12277
12278   /* If the format doesn't contain % args or %%, use strcpy.  */
12279   if (strchr (fmt_str, target_percent) == NULL)
12280     {
12281       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12282       size_t len = strlen (fmt_str);
12283
12284       /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
12285       if (orig)
12286         return NULL_TREE;
12287
12288       /* We could expand this as
12289          memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
12290          or to
12291          memcpy (str, fmt_with_nul_at_cstm1, cst);
12292          but in the former case that might increase code size
12293          and in the latter case grow .rodata section too much.
12294          So punt for now.  */
12295       if (len >= destlen)
12296         return NULL_TREE;
12297
12298       if (!fn)
12299         return NULL_TREE;
12300
12301       /* Convert snprintf (str, cst, fmt) into strcpy (str, fmt) when
12302          'format' is known to contain no % formats and
12303          strlen (fmt) < cst.  */
12304       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12305
12306       if (!ignored)
12307         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12308     }
12309
12310   /* If the format is "%s", use strcpy if the result isn't used.  */
12311   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12312     {
12313       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12314       unsigned HOST_WIDE_INT origlen;
12315
12316       /* Don't crash on snprintf (str1, cst, "%s").  */
12317       if (!orig)
12318         return NULL_TREE;
12319
12320       retval = c_strlen (orig, 1);
12321       if (!retval || !host_integerp (retval, 1))  
12322         return NULL_TREE;
12323
12324       origlen = tree_low_cst (retval, 1);
12325       /* We could expand this as
12326          memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
12327          or to
12328          memcpy (str1, str2_with_nul_at_cstm1, cst);
12329          but in the former case that might increase code size
12330          and in the latter case grow .rodata section too much.
12331          So punt for now.  */
12332       if (origlen >= destlen)
12333         return NULL_TREE;
12334
12335       /* Convert snprintf (str1, cst, "%s", str2) into
12336          strcpy (str1, str2) if strlen (str2) < cst.  */
12337       if (!fn)
12338         return NULL_TREE;
12339
12340       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12341
12342       if (ignored)
12343         retval = NULL_TREE;
12344     }
12345
12346   if (call && retval)
12347     {
12348       tree fn = builtin_decl_explicit (BUILT_IN_SNPRINTF);
12349       retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
12350       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12351     }
12352   else
12353     return call;
12354 }
12355
12356 /* Expand a call EXP to __builtin_object_size.  */
12357
12358 rtx
12359 expand_builtin_object_size (tree exp)
12360 {
12361   tree ost;
12362   int object_size_type;
12363   tree fndecl = get_callee_fndecl (exp);
12364
12365   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
12366     {
12367       error ("%Kfirst argument of %D must be a pointer, second integer constant",
12368              exp, fndecl);
12369       expand_builtin_trap ();
12370       return const0_rtx;
12371     }
12372
12373   ost = CALL_EXPR_ARG (exp, 1);
12374   STRIP_NOPS (ost);
12375
12376   if (TREE_CODE (ost) != INTEGER_CST
12377       || tree_int_cst_sgn (ost) < 0
12378       || compare_tree_int (ost, 3) > 0)
12379     {
12380       error ("%Klast argument of %D is not integer constant between 0 and 3",
12381              exp, fndecl);
12382       expand_builtin_trap ();
12383       return const0_rtx;
12384     }
12385
12386   object_size_type = tree_low_cst (ost, 0);
12387
12388   return object_size_type < 2 ? constm1_rtx : const0_rtx;
12389 }
12390
12391 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12392    FCODE is the BUILT_IN_* to use.
12393    Return NULL_RTX if we failed; the caller should emit a normal call,
12394    otherwise try to get the result in TARGET, if convenient (and in
12395    mode MODE if that's convenient).  */
12396
12397 static rtx
12398 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12399                            enum built_in_function fcode)
12400 {
12401   tree dest, src, len, size;
12402
12403   if (!validate_arglist (exp,
12404                          POINTER_TYPE,
12405                          fcode == BUILT_IN_MEMSET_CHK
12406                          ? INTEGER_TYPE : POINTER_TYPE,
12407                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
12408     return NULL_RTX;
12409
12410   dest = CALL_EXPR_ARG (exp, 0);
12411   src = CALL_EXPR_ARG (exp, 1);
12412   len = CALL_EXPR_ARG (exp, 2);
12413   size = CALL_EXPR_ARG (exp, 3);
12414
12415   if (! host_integerp (size, 1))
12416     return NULL_RTX;
12417
12418   if (host_integerp (len, 1) || integer_all_onesp (size))
12419     {
12420       tree fn;
12421
12422       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12423         {
12424           warning_at (tree_nonartificial_location (exp),
12425                       0, "%Kcall to %D will always overflow destination buffer",
12426                       exp, get_callee_fndecl (exp));
12427           return NULL_RTX;
12428         }
12429
12430       fn = NULL_TREE;
12431       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12432          mem{cpy,pcpy,move,set} is available.  */
12433       switch (fcode)
12434         {
12435         case BUILT_IN_MEMCPY_CHK:
12436           fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12437           break;
12438         case BUILT_IN_MEMPCPY_CHK:
12439           fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12440           break;
12441         case BUILT_IN_MEMMOVE_CHK:
12442           fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12443           break;
12444         case BUILT_IN_MEMSET_CHK:
12445           fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12446           break;
12447         default:
12448           break;
12449         }
12450
12451       if (! fn)
12452         return NULL_RTX;
12453
12454       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len);
12455       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12456       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12457       return expand_expr (fn, target, mode, EXPAND_NORMAL);
12458     }
12459   else if (fcode == BUILT_IN_MEMSET_CHK)
12460     return NULL_RTX;
12461   else
12462     {
12463       unsigned int dest_align = get_pointer_alignment (dest);
12464
12465       /* If DEST is not a pointer type, call the normal function.  */
12466       if (dest_align == 0)
12467         return NULL_RTX;
12468
12469       /* If SRC and DEST are the same (and not volatile), do nothing.  */
12470       if (operand_equal_p (src, dest, 0))
12471         {
12472           tree expr;
12473
12474           if (fcode != BUILT_IN_MEMPCPY_CHK)
12475             {
12476               /* Evaluate and ignore LEN in case it has side-effects.  */
12477               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12478               return expand_expr (dest, target, mode, EXPAND_NORMAL);
12479             }
12480
12481           expr = fold_build_pointer_plus (dest, len);
12482           return expand_expr (expr, target, mode, EXPAND_NORMAL);
12483         }
12484
12485       /* __memmove_chk special case.  */
12486       if (fcode == BUILT_IN_MEMMOVE_CHK)
12487         {
12488           unsigned int src_align = get_pointer_alignment (src);
12489
12490           if (src_align == 0)
12491             return NULL_RTX;
12492
12493           /* If src is categorized for a readonly section we can use
12494              normal __memcpy_chk.  */
12495           if (readonly_data_expr (src))
12496             {
12497               tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12498               if (!fn)
12499                 return NULL_RTX;
12500               fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
12501                                           dest, src, len, size);
12502               gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12503               CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12504               return expand_expr (fn, target, mode, EXPAND_NORMAL);
12505             }
12506         }
12507       return NULL_RTX;
12508     }
12509 }
12510
12511 /* Emit warning if a buffer overflow is detected at compile time.  */
12512
12513 static void
12514 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12515 {
12516   int is_strlen = 0;
12517   tree len, size;
12518   location_t loc = tree_nonartificial_location (exp);
12519
12520   switch (fcode)
12521     {
12522     case BUILT_IN_STRCPY_CHK:
12523     case BUILT_IN_STPCPY_CHK:
12524     /* For __strcat_chk the warning will be emitted only if overflowing
12525        by at least strlen (dest) + 1 bytes.  */
12526     case BUILT_IN_STRCAT_CHK:
12527       len = CALL_EXPR_ARG (exp, 1);
12528       size = CALL_EXPR_ARG (exp, 2);
12529       is_strlen = 1;
12530       break;
12531     case BUILT_IN_STRNCAT_CHK:
12532     case BUILT_IN_STRNCPY_CHK:
12533     case BUILT_IN_STPNCPY_CHK:
12534       len = CALL_EXPR_ARG (exp, 2);
12535       size = CALL_EXPR_ARG (exp, 3);
12536       break;
12537     case BUILT_IN_SNPRINTF_CHK:
12538     case BUILT_IN_VSNPRINTF_CHK:
12539       len = CALL_EXPR_ARG (exp, 1);
12540       size = CALL_EXPR_ARG (exp, 3);
12541       break;
12542     default:
12543       gcc_unreachable ();
12544     }
12545
12546   if (!len || !size)
12547     return;
12548
12549   if (! host_integerp (size, 1) || integer_all_onesp (size))
12550     return;
12551
12552   if (is_strlen)
12553     {
12554       len = c_strlen (len, 1);
12555       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12556         return;
12557     }
12558   else if (fcode == BUILT_IN_STRNCAT_CHK)
12559     {
12560       tree src = CALL_EXPR_ARG (exp, 1);
12561       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12562         return;
12563       src = c_strlen (src, 1);
12564       if (! src || ! host_integerp (src, 1))
12565         {
12566           warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12567                       exp, get_callee_fndecl (exp));
12568           return;
12569         }
12570       else if (tree_int_cst_lt (src, size))
12571         return;
12572     }
12573   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12574     return;
12575
12576   warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12577               exp, get_callee_fndecl (exp));
12578 }
12579
12580 /* Emit warning if a buffer overflow is detected at compile time
12581    in __sprintf_chk/__vsprintf_chk calls.  */
12582
12583 static void
12584 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12585 {
12586   tree size, len, fmt;
12587   const char *fmt_str;
12588   int nargs = call_expr_nargs (exp);
12589
12590   /* Verify the required arguments in the original call.  */
12591
12592   if (nargs < 4)
12593     return;
12594   size = CALL_EXPR_ARG (exp, 2);
12595   fmt = CALL_EXPR_ARG (exp, 3);
12596
12597   if (! host_integerp (size, 1) || integer_all_onesp (size))
12598     return;
12599
12600   /* Check whether the format is a literal string constant.  */
12601   fmt_str = c_getstr (fmt);
12602   if (fmt_str == NULL)
12603     return;
12604
12605   if (!init_target_chars ())
12606     return;
12607
12608   /* If the format doesn't contain % args or %%, we know its size.  */
12609   if (strchr (fmt_str, target_percent) == 0)
12610     len = build_int_cstu (size_type_node, strlen (fmt_str));
12611   /* If the format is "%s" and first ... argument is a string literal,
12612      we know it too.  */
12613   else if (fcode == BUILT_IN_SPRINTF_CHK
12614            && strcmp (fmt_str, target_percent_s) == 0)
12615     {
12616       tree arg;
12617
12618       if (nargs < 5)
12619         return;
12620       arg = CALL_EXPR_ARG (exp, 4);
12621       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12622         return;
12623
12624       len = c_strlen (arg, 1);
12625       if (!len || ! host_integerp (len, 1))
12626         return;
12627     }
12628   else
12629     return;
12630
12631   if (! tree_int_cst_lt (len, size))
12632     warning_at (tree_nonartificial_location (exp),
12633                 0, "%Kcall to %D will always overflow destination buffer",
12634                 exp, get_callee_fndecl (exp));
12635 }
12636
12637 /* Emit warning if a free is called with address of a variable.  */
12638
12639 static void
12640 maybe_emit_free_warning (tree exp)
12641 {
12642   tree arg = CALL_EXPR_ARG (exp, 0);
12643
12644   STRIP_NOPS (arg);
12645   if (TREE_CODE (arg) != ADDR_EXPR)
12646     return;
12647
12648   arg = get_base_address (TREE_OPERAND (arg, 0));
12649   if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF)
12650     return;
12651
12652   if (SSA_VAR_P (arg))
12653     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12654                 "%Kattempt to free a non-heap object %qD", exp, arg);
12655   else
12656     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12657                 "%Kattempt to free a non-heap object", exp);
12658 }
12659
12660 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12661    if possible.  */
12662
12663 tree
12664 fold_builtin_object_size (tree ptr, tree ost)
12665 {
12666   unsigned HOST_WIDE_INT bytes;
12667   int object_size_type;
12668
12669   if (!validate_arg (ptr, POINTER_TYPE)
12670       || !validate_arg (ost, INTEGER_TYPE))
12671     return NULL_TREE;
12672
12673   STRIP_NOPS (ost);
12674
12675   if (TREE_CODE (ost) != INTEGER_CST
12676       || tree_int_cst_sgn (ost) < 0
12677       || compare_tree_int (ost, 3) > 0)
12678     return NULL_TREE;
12679
12680   object_size_type = tree_low_cst (ost, 0);
12681
12682   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12683      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12684      and (size_t) 0 for types 2 and 3.  */
12685   if (TREE_SIDE_EFFECTS (ptr))
12686     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12687
12688   if (TREE_CODE (ptr) == ADDR_EXPR)
12689     {
12690       bytes = compute_builtin_object_size (ptr, object_size_type);
12691       if (double_int_fits_to_tree_p (size_type_node,
12692                                      uhwi_to_double_int (bytes)))
12693         return build_int_cstu (size_type_node, bytes);
12694     }
12695   else if (TREE_CODE (ptr) == SSA_NAME)
12696     {
12697       /* If object size is not known yet, delay folding until
12698        later.  Maybe subsequent passes will help determining
12699        it.  */
12700       bytes = compute_builtin_object_size (ptr, object_size_type);
12701       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
12702           && double_int_fits_to_tree_p (size_type_node,
12703                                         uhwi_to_double_int (bytes)))
12704         return build_int_cstu (size_type_node, bytes);
12705     }
12706
12707   return NULL_TREE;
12708 }
12709
12710 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12711    DEST, SRC, LEN, and SIZE are the arguments to the call.
12712    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12713    code of the builtin.  If MAXLEN is not NULL, it is maximum length
12714    passed as third argument.  */
12715
12716 tree
12717 fold_builtin_memory_chk (location_t loc, tree fndecl,
12718                          tree dest, tree src, tree len, tree size,
12719                          tree maxlen, bool ignore,
12720                          enum built_in_function fcode)
12721 {
12722   tree fn;
12723
12724   if (!validate_arg (dest, POINTER_TYPE)
12725       || !validate_arg (src,
12726                         (fcode == BUILT_IN_MEMSET_CHK
12727                          ? INTEGER_TYPE : POINTER_TYPE))
12728       || !validate_arg (len, INTEGER_TYPE)
12729       || !validate_arg (size, INTEGER_TYPE))
12730     return NULL_TREE;
12731
12732   /* If SRC and DEST are the same (and not volatile), return DEST
12733      (resp. DEST+LEN for __mempcpy_chk).  */
12734   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12735     {
12736       if (fcode != BUILT_IN_MEMPCPY_CHK)
12737         return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12738                                  dest, len);
12739       else
12740         {
12741           tree temp = fold_build_pointer_plus_loc (loc, dest, len);
12742           return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12743         }
12744     }
12745
12746   if (! host_integerp (size, 1))
12747     return NULL_TREE;
12748
12749   if (! integer_all_onesp (size))
12750     {
12751       if (! host_integerp (len, 1))
12752         {
12753           /* If LEN is not constant, try MAXLEN too.
12754              For MAXLEN only allow optimizing into non-_ocs function
12755              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12756           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12757             {
12758               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12759                 {
12760                   /* (void) __mempcpy_chk () can be optimized into
12761                      (void) __memcpy_chk ().  */
12762                   fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12763                   if (!fn)
12764                     return NULL_TREE;
12765
12766                   return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12767                 }
12768               return NULL_TREE;
12769             }
12770         }
12771       else
12772         maxlen = len;
12773
12774       if (tree_int_cst_lt (size, maxlen))
12775         return NULL_TREE;
12776     }
12777
12778   fn = NULL_TREE;
12779   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12780      mem{cpy,pcpy,move,set} is available.  */
12781   switch (fcode)
12782     {
12783     case BUILT_IN_MEMCPY_CHK:
12784       fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12785       break;
12786     case BUILT_IN_MEMPCPY_CHK:
12787       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12788       break;
12789     case BUILT_IN_MEMMOVE_CHK:
12790       fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12791       break;
12792     case BUILT_IN_MEMSET_CHK:
12793       fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12794       break;
12795     default:
12796       break;
12797     }
12798
12799   if (!fn)
12800     return NULL_TREE;
12801
12802   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12803 }
12804
12805 /* Fold a call to the __st[rp]cpy_chk builtin.
12806    DEST, SRC, and SIZE are the arguments to the call.
12807    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12808    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12809    strings passed as second argument.  */
12810
12811 tree
12812 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12813                          tree src, tree size,
12814                          tree maxlen, bool ignore,
12815                          enum built_in_function fcode)
12816 {
12817   tree len, fn;
12818
12819   if (!validate_arg (dest, POINTER_TYPE)
12820       || !validate_arg (src, POINTER_TYPE)
12821       || !validate_arg (size, INTEGER_TYPE))
12822     return NULL_TREE;
12823
12824   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12825   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12826     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12827
12828   if (! host_integerp (size, 1))
12829     return NULL_TREE;
12830
12831   if (! integer_all_onesp (size))
12832     {
12833       len = c_strlen (src, 1);
12834       if (! len || ! host_integerp (len, 1))
12835         {
12836           /* If LEN is not constant, try MAXLEN too.
12837              For MAXLEN only allow optimizing into non-_ocs function
12838              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12839           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12840             {
12841               if (fcode == BUILT_IN_STPCPY_CHK)
12842                 {
12843                   if (! ignore)
12844                     return NULL_TREE;
12845
12846                   /* If return value of __stpcpy_chk is ignored,
12847                      optimize into __strcpy_chk.  */
12848                   fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
12849                   if (!fn)
12850                     return NULL_TREE;
12851
12852                   return build_call_expr_loc (loc, fn, 3, dest, src, size);
12853                 }
12854
12855               if (! len || TREE_SIDE_EFFECTS (len))
12856                 return NULL_TREE;
12857
12858               /* If c_strlen returned something, but not a constant,
12859                  transform __strcpy_chk into __memcpy_chk.  */
12860               fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12861               if (!fn)
12862                 return NULL_TREE;
12863
12864               len = fold_convert_loc (loc, size_type_node, len);
12865               len = size_binop_loc (loc, PLUS_EXPR, len,
12866                                     build_int_cst (size_type_node, 1));
12867               return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12868                                        build_call_expr_loc (loc, fn, 4,
12869                                                         dest, src, len, size));
12870             }
12871         }
12872       else
12873         maxlen = len;
12874
12875       if (! tree_int_cst_lt (maxlen, size))
12876         return NULL_TREE;
12877     }
12878
12879   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12880   fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
12881                               ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
12882   if (!fn)
12883     return NULL_TREE;
12884
12885   return build_call_expr_loc (loc, fn, 2, dest, src);
12886 }
12887
12888 /* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12889    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12890    length passed as third argument. IGNORE is true if return value can be
12891    ignored. FCODE is the BUILT_IN_* code of the builtin. */
12892
12893 tree
12894 fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
12895                           tree len, tree size, tree maxlen, bool ignore,
12896                           enum built_in_function fcode)
12897 {
12898   tree fn;
12899
12900   if (!validate_arg (dest, POINTER_TYPE)
12901       || !validate_arg (src, POINTER_TYPE)
12902       || !validate_arg (len, INTEGER_TYPE)
12903       || !validate_arg (size, INTEGER_TYPE))
12904     return NULL_TREE;
12905
12906   if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
12907     {
12908        /* If return value of __stpncpy_chk is ignored,
12909           optimize into __strncpy_chk.  */
12910        fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
12911        if (fn)
12912          return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12913     }
12914
12915   if (! host_integerp (size, 1))
12916     return NULL_TREE;
12917
12918   if (! integer_all_onesp (size))
12919     {
12920       if (! host_integerp (len, 1))
12921         {
12922           /* If LEN is not constant, try MAXLEN too.
12923              For MAXLEN only allow optimizing into non-_ocs function
12924              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12925           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12926             return NULL_TREE;
12927         }
12928       else
12929         maxlen = len;
12930
12931       if (tree_int_cst_lt (size, maxlen))
12932         return NULL_TREE;
12933     }
12934
12935   /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
12936   fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
12937                               ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
12938   if (!fn)
12939     return NULL_TREE;
12940
12941   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12942 }
12943
12944 /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
12945    are the arguments to the call.  */
12946
12947 static tree
12948 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12949                          tree src, tree size)
12950 {
12951   tree fn;
12952   const char *p;
12953
12954   if (!validate_arg (dest, POINTER_TYPE)
12955       || !validate_arg (src, POINTER_TYPE)
12956       || !validate_arg (size, INTEGER_TYPE))
12957     return NULL_TREE;
12958
12959   p = c_getstr (src);
12960   /* If the SRC parameter is "", return DEST.  */
12961   if (p && *p == '\0')
12962     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12963
12964   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12965     return NULL_TREE;
12966
12967   /* If __builtin_strcat_chk is used, assume strcat is available.  */
12968   fn = builtin_decl_explicit (BUILT_IN_STRCAT);
12969   if (!fn)
12970     return NULL_TREE;
12971
12972   return build_call_expr_loc (loc, fn, 2, dest, src);
12973 }
12974
12975 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12976    LEN, and SIZE.  */
12977
12978 static tree
12979 fold_builtin_strncat_chk (location_t loc, tree fndecl,
12980                           tree dest, tree src, tree len, tree size)
12981 {
12982   tree fn;
12983   const char *p;
12984
12985   if (!validate_arg (dest, POINTER_TYPE)
12986       || !validate_arg (src, POINTER_TYPE)
12987       || !validate_arg (size, INTEGER_TYPE)
12988       || !validate_arg (size, INTEGER_TYPE))
12989     return NULL_TREE;
12990
12991   p = c_getstr (src);
12992   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
12993   if (p && *p == '\0')
12994     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12995   else if (integer_zerop (len))
12996     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12997
12998   if (! host_integerp (size, 1))
12999     return NULL_TREE;
13000
13001   if (! integer_all_onesp (size))
13002     {
13003       tree src_len = c_strlen (src, 1);
13004       if (src_len
13005           && host_integerp (src_len, 1)
13006           && host_integerp (len, 1)
13007           && ! tree_int_cst_lt (len, src_len))
13008         {
13009           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
13010           fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
13011           if (!fn)
13012             return NULL_TREE;
13013
13014           return build_call_expr_loc (loc, fn, 3, dest, src, size);
13015         }
13016       return NULL_TREE;
13017     }
13018
13019   /* If __builtin_strncat_chk is used, assume strncat is available.  */
13020   fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
13021   if (!fn)
13022     return NULL_TREE;
13023
13024   return build_call_expr_loc (loc, fn, 3, dest, src, len);
13025 }
13026
13027 /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
13028    Return NULL_TREE if a normal call should be emitted rather than
13029    expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
13030    or BUILT_IN_VSPRINTF_CHK.  */
13031
13032 static tree
13033 fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
13034                             enum built_in_function fcode)
13035 {
13036   tree dest, size, len, fn, fmt, flag;
13037   const char *fmt_str;
13038
13039   /* Verify the required arguments in the original call.  */
13040   if (nargs < 4)
13041     return NULL_TREE;
13042   dest = args[0];
13043   if (!validate_arg (dest, POINTER_TYPE))
13044     return NULL_TREE;
13045   flag = args[1];
13046   if (!validate_arg (flag, INTEGER_TYPE))
13047     return NULL_TREE;
13048   size = args[2];
13049   if (!validate_arg (size, INTEGER_TYPE))
13050     return NULL_TREE;
13051   fmt = args[3];
13052   if (!validate_arg (fmt, POINTER_TYPE))
13053     return NULL_TREE;
13054
13055   if (! host_integerp (size, 1))
13056     return NULL_TREE;
13057
13058   len = NULL_TREE;
13059
13060   if (!init_target_chars ())
13061     return NULL_TREE;
13062
13063   /* Check whether the format is a literal string constant.  */
13064   fmt_str = c_getstr (fmt);
13065   if (fmt_str != NULL)
13066     {
13067       /* If the format doesn't contain % args or %%, we know the size.  */
13068       if (strchr (fmt_str, target_percent) == 0)
13069         {
13070           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13071             len = build_int_cstu (size_type_node, strlen (fmt_str));
13072         }
13073       /* If the format is "%s" and first ... argument is a string literal,
13074          we know the size too.  */
13075       else if (fcode == BUILT_IN_SPRINTF_CHK
13076                && strcmp (fmt_str, target_percent_s) == 0)
13077         {
13078           tree arg;
13079
13080           if (nargs == 5)
13081             {
13082               arg = args[4];
13083               if (validate_arg (arg, POINTER_TYPE))
13084                 {
13085                   len = c_strlen (arg, 1);
13086                   if (! len || ! host_integerp (len, 1))
13087                     len = NULL_TREE;
13088                 }
13089             }
13090         }
13091     }
13092
13093   if (! integer_all_onesp (size))
13094     {
13095       if (! len || ! tree_int_cst_lt (len, size))
13096         return NULL_TREE;
13097     }
13098
13099   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13100      or if format doesn't contain % chars or is "%s".  */
13101   if (! integer_zerop (flag))
13102     {
13103       if (fmt_str == NULL)
13104         return NULL_TREE;
13105       if (strchr (fmt_str, target_percent) != NULL
13106           && strcmp (fmt_str, target_percent_s))
13107         return NULL_TREE;
13108     }
13109
13110   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13111   fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
13112                               ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
13113   if (!fn)
13114     return NULL_TREE;
13115
13116   return rewrite_call_expr_array (loc, nargs, args, 4, fn, 2, dest, fmt);
13117 }
13118
13119 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
13120    a normal call should be emitted rather than expanding the function
13121    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13122
13123 static tree
13124 fold_builtin_sprintf_chk (location_t loc, tree exp,
13125                           enum built_in_function fcode)
13126 {
13127   return fold_builtin_sprintf_chk_1 (loc, call_expr_nargs (exp),
13128                                      CALL_EXPR_ARGP (exp), fcode);
13129 }
13130
13131 /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
13132    NULL_TREE if a normal call should be emitted rather than expanding
13133    the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13134    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13135    passed as second argument.  */
13136
13137 static tree
13138 fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
13139                              tree maxlen, enum built_in_function fcode)
13140 {
13141   tree dest, size, len, fn, fmt, flag;
13142   const char *fmt_str;
13143
13144   /* Verify the required arguments in the original call.  */
13145   if (nargs < 5)
13146     return NULL_TREE;
13147   dest = args[0];
13148   if (!validate_arg (dest, POINTER_TYPE))
13149     return NULL_TREE;
13150   len = args[1];
13151   if (!validate_arg (len, INTEGER_TYPE))
13152     return NULL_TREE;
13153   flag = args[2];
13154   if (!validate_arg (flag, INTEGER_TYPE))
13155     return NULL_TREE;
13156   size = args[3];
13157   if (!validate_arg (size, INTEGER_TYPE))
13158     return NULL_TREE;
13159   fmt = args[4];
13160   if (!validate_arg (fmt, POINTER_TYPE))
13161     return NULL_TREE;
13162
13163   if (! host_integerp (size, 1))
13164     return NULL_TREE;
13165
13166   if (! integer_all_onesp (size))
13167     {
13168       if (! host_integerp (len, 1))
13169         {
13170           /* If LEN is not constant, try MAXLEN too.
13171              For MAXLEN only allow optimizing into non-_ocs function
13172              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13173           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13174             return NULL_TREE;
13175         }
13176       else
13177         maxlen = len;
13178
13179       if (tree_int_cst_lt (size, maxlen))
13180         return NULL_TREE;
13181     }
13182
13183   if (!init_target_chars ())
13184     return NULL_TREE;
13185
13186   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13187      or if format doesn't contain % chars or is "%s".  */
13188   if (! integer_zerop (flag))
13189     {
13190       fmt_str = c_getstr (fmt);
13191       if (fmt_str == NULL)
13192         return NULL_TREE;
13193       if (strchr (fmt_str, target_percent) != NULL
13194           && strcmp (fmt_str, target_percent_s))
13195         return NULL_TREE;
13196     }
13197
13198   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13199      available.  */
13200   fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
13201                               ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
13202   if (!fn)
13203     return NULL_TREE;
13204
13205   return rewrite_call_expr_array (loc, nargs, args, 5, fn, 3, dest, len, fmt);
13206 }
13207
13208 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
13209    a normal call should be emitted rather than expanding the function
13210    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13211    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13212    passed as second argument.  */
13213
13214 tree
13215 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
13216                            enum built_in_function fcode)
13217 {
13218   return fold_builtin_snprintf_chk_1 (loc, call_expr_nargs (exp),
13219                                       CALL_EXPR_ARGP (exp), maxlen, fcode);
13220 }
13221
13222 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
13223    FMT and ARG are the arguments to the call; we don't fold cases with
13224    more than 2 arguments, and ARG may be null if this is a 1-argument case.
13225
13226    Return NULL_TREE if no simplification was possible, otherwise return the
13227    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13228    code of the function to be simplified.  */
13229
13230 static tree
13231 fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13232                      tree arg, bool ignore,
13233                      enum built_in_function fcode)
13234 {
13235   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
13236   const char *fmt_str = NULL;
13237
13238   /* If the return value is used, don't do the transformation.  */
13239   if (! ignore)
13240     return NULL_TREE;
13241
13242   /* Verify the required arguments in the original call.  */
13243   if (!validate_arg (fmt, POINTER_TYPE))
13244     return NULL_TREE;
13245
13246   /* Check whether the format is a literal string constant.  */
13247   fmt_str = c_getstr (fmt);
13248   if (fmt_str == NULL)
13249     return NULL_TREE;
13250
13251   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13252     {
13253       /* If we're using an unlocked function, assume the other
13254          unlocked functions exist explicitly.  */
13255       fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
13256       fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
13257     }
13258   else
13259     {
13260       fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
13261       fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
13262     }
13263
13264   if (!init_target_chars ())
13265     return NULL_TREE;
13266
13267   if (strcmp (fmt_str, target_percent_s) == 0
13268       || strchr (fmt_str, target_percent) == NULL)
13269     {
13270       const char *str;
13271
13272       if (strcmp (fmt_str, target_percent_s) == 0)
13273         {
13274           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13275             return NULL_TREE;
13276
13277           if (!arg || !validate_arg (arg, POINTER_TYPE))
13278             return NULL_TREE;
13279
13280           str = c_getstr (arg);
13281           if (str == NULL)
13282             return NULL_TREE;
13283         }
13284       else
13285         {
13286           /* The format specifier doesn't contain any '%' characters.  */
13287           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
13288               && arg)
13289             return NULL_TREE;
13290           str = fmt_str;
13291         }
13292
13293       /* If the string was "", printf does nothing.  */
13294       if (str[0] == '\0')
13295         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13296
13297       /* If the string has length of 1, call putchar.  */
13298       if (str[1] == '\0')
13299         {
13300           /* Given printf("c"), (where c is any one character,)
13301              convert "c"[0] to an int and pass that to the replacement
13302              function.  */
13303           newarg = build_int_cst (integer_type_node, str[0]);
13304           if (fn_putchar)
13305             call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
13306         }
13307       else
13308         {
13309           /* If the string was "string\n", call puts("string").  */
13310           size_t len = strlen (str);
13311           if ((unsigned char)str[len - 1] == target_newline
13312               && (size_t) (int) len == len
13313               && (int) len > 0)
13314             {
13315               char *newstr;
13316               tree offset_node, string_cst;
13317
13318               /* Create a NUL-terminated string that's one char shorter
13319                  than the original, stripping off the trailing '\n'.  */
13320               newarg = build_string_literal (len, str);
13321               string_cst = string_constant (newarg, &offset_node);
13322               gcc_checking_assert (string_cst
13323                                    && (TREE_STRING_LENGTH (string_cst)
13324                                        == (int) len)
13325                                    && integer_zerop (offset_node)
13326                                    && (unsigned char)
13327                                       TREE_STRING_POINTER (string_cst)[len - 1]
13328                                       == target_newline);
13329               /* build_string_literal creates a new STRING_CST,
13330                  modify it in place to avoid double copying.  */
13331               newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst));
13332               newstr[len - 1] = '\0';
13333               if (fn_puts)
13334                 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
13335             }
13336           else
13337             /* We'd like to arrange to call fputs(string,stdout) here,
13338                but we need stdout and don't have a way to get it yet.  */
13339             return NULL_TREE;
13340         }
13341     }
13342
13343   /* The other optimizations can be done only on the non-va_list variants.  */
13344   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13345     return NULL_TREE;
13346
13347   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
13348   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
13349     {
13350       if (!arg || !validate_arg (arg, POINTER_TYPE))
13351         return NULL_TREE;
13352       if (fn_puts)
13353         call = build_call_expr_loc (loc, fn_puts, 1, arg);
13354     }
13355
13356   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
13357   else if (strcmp (fmt_str, target_percent_c) == 0)
13358     {
13359       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13360         return NULL_TREE;
13361       if (fn_putchar)
13362         call = build_call_expr_loc (loc, fn_putchar, 1, arg);
13363     }
13364
13365   if (!call)
13366     return NULL_TREE;
13367
13368   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13369 }
13370
13371 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
13372    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
13373    more than 3 arguments, and ARG may be null in the 2-argument case.
13374
13375    Return NULL_TREE if no simplification was possible, otherwise return the
13376    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13377    code of the function to be simplified.  */
13378
13379 static tree
13380 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13381                       tree fmt, tree arg, bool ignore,
13382                       enum built_in_function fcode)
13383 {
13384   tree fn_fputc, fn_fputs, call = NULL_TREE;
13385   const char *fmt_str = NULL;
13386
13387   /* If the return value is used, don't do the transformation.  */
13388   if (! ignore)
13389     return NULL_TREE;
13390
13391   /* Verify the required arguments in the original call.  */
13392   if (!validate_arg (fp, POINTER_TYPE))
13393     return NULL_TREE;
13394   if (!validate_arg (fmt, POINTER_TYPE))
13395     return NULL_TREE;
13396
13397   /* Check whether the format is a literal string constant.  */
13398   fmt_str = c_getstr (fmt);
13399   if (fmt_str == NULL)
13400     return NULL_TREE;
13401
13402   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13403     {
13404       /* If we're using an unlocked function, assume the other
13405          unlocked functions exist explicitly.  */
13406       fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
13407       fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
13408     }
13409   else
13410     {
13411       fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
13412       fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
13413     }
13414
13415   if (!init_target_chars ())
13416     return NULL_TREE;
13417
13418   /* If the format doesn't contain % args or %%, use strcpy.  */
13419   if (strchr (fmt_str, target_percent) == NULL)
13420     {
13421       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
13422           && arg)
13423         return NULL_TREE;
13424
13425       /* If the format specifier was "", fprintf does nothing.  */
13426       if (fmt_str[0] == '\0')
13427         {
13428           /* If FP has side-effects, just wait until gimplification is
13429              done.  */
13430           if (TREE_SIDE_EFFECTS (fp))
13431             return NULL_TREE;
13432
13433           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13434         }
13435
13436       /* When "string" doesn't contain %, replace all cases of
13437          fprintf (fp, string) with fputs (string, fp).  The fputs
13438          builtin will take care of special cases like length == 1.  */
13439       if (fn_fputs)
13440         call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
13441     }
13442
13443   /* The other optimizations can be done only on the non-va_list variants.  */
13444   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
13445     return NULL_TREE;
13446
13447   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
13448   else if (strcmp (fmt_str, target_percent_s) == 0)
13449     {
13450       if (!arg || !validate_arg (arg, POINTER_TYPE))
13451         return NULL_TREE;
13452       if (fn_fputs)
13453         call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
13454     }
13455
13456   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
13457   else if (strcmp (fmt_str, target_percent_c) == 0)
13458     {
13459       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13460         return NULL_TREE;
13461       if (fn_fputc)
13462         call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
13463     }
13464
13465   if (!call)
13466     return NULL_TREE;
13467   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13468 }
13469
13470 /* Initialize format string characters in the target charset.  */
13471
13472 static bool
13473 init_target_chars (void)
13474 {
13475   static bool init;
13476   if (!init)
13477     {
13478       target_newline = lang_hooks.to_target_charset ('\n');
13479       target_percent = lang_hooks.to_target_charset ('%');
13480       target_c = lang_hooks.to_target_charset ('c');
13481       target_s = lang_hooks.to_target_charset ('s');
13482       if (target_newline == 0 || target_percent == 0 || target_c == 0
13483           || target_s == 0)
13484         return false;
13485
13486       target_percent_c[0] = target_percent;
13487       target_percent_c[1] = target_c;
13488       target_percent_c[2] = '\0';
13489
13490       target_percent_s[0] = target_percent;
13491       target_percent_s[1] = target_s;
13492       target_percent_s[2] = '\0';
13493
13494       target_percent_s_newline[0] = target_percent;
13495       target_percent_s_newline[1] = target_s;
13496       target_percent_s_newline[2] = target_newline;
13497       target_percent_s_newline[3] = '\0';
13498
13499       init = true;
13500     }
13501   return true;
13502 }
13503
13504 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13505    and no overflow/underflow occurred.  INEXACT is true if M was not
13506    exactly calculated.  TYPE is the tree type for the result.  This
13507    function assumes that you cleared the MPFR flags and then
13508    calculated M to see if anything subsequently set a flag prior to
13509    entering this function.  Return NULL_TREE if any checks fail.  */
13510
13511 static tree
13512 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13513 {
13514   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13515      overflow/underflow occurred.  If -frounding-math, proceed iff the
13516      result of calling FUNC was exact.  */
13517   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13518       && (!flag_rounding_math || !inexact))
13519     {
13520       REAL_VALUE_TYPE rr;
13521
13522       real_from_mpfr (&rr, m, type, GMP_RNDN);
13523       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13524          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13525          but the mpft_t is not, then we underflowed in the
13526          conversion.  */
13527       if (real_isfinite (&rr)
13528           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13529         {
13530           REAL_VALUE_TYPE rmode;
13531
13532           real_convert (&rmode, TYPE_MODE (type), &rr);
13533           /* Proceed iff the specified mode can hold the value.  */
13534           if (real_identical (&rmode, &rr))
13535             return build_real (type, rmode);
13536         }
13537     }
13538   return NULL_TREE;
13539 }
13540
13541 /* Helper function for do_mpc_arg*().  Ensure M is a normal complex
13542    number and no overflow/underflow occurred.  INEXACT is true if M
13543    was not exactly calculated.  TYPE is the tree type for the result.
13544    This function assumes that you cleared the MPFR flags and then
13545    calculated M to see if anything subsequently set a flag prior to
13546    entering this function.  Return NULL_TREE if any checks fail, if
13547    FORCE_CONVERT is true, then bypass the checks.  */
13548
13549 static tree
13550 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13551 {
13552   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13553      overflow/underflow occurred.  If -frounding-math, proceed iff the
13554      result of calling FUNC was exact.  */
13555   if (force_convert
13556       || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13557           && !mpfr_overflow_p () && !mpfr_underflow_p ()
13558           && (!flag_rounding_math || !inexact)))
13559     {
13560       REAL_VALUE_TYPE re, im;
13561
13562       real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN);
13563       real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN);
13564       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13565          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13566          but the mpft_t is not, then we underflowed in the
13567          conversion.  */
13568       if (force_convert
13569           || (real_isfinite (&re) && real_isfinite (&im)
13570               && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13571               && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13572         {
13573           REAL_VALUE_TYPE re_mode, im_mode;
13574
13575           real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13576           real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13577           /* Proceed iff the specified mode can hold the value.  */
13578           if (force_convert
13579               || (real_identical (&re_mode, &re)
13580                   && real_identical (&im_mode, &im)))
13581             return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13582                                   build_real (TREE_TYPE (type), im_mode));
13583         }
13584     }
13585   return NULL_TREE;
13586 }
13587
13588 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13589    FUNC on it and return the resulting value as a tree with type TYPE.
13590    If MIN and/or MAX are not NULL, then the supplied ARG must be
13591    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13592    acceptable values, otherwise they are not.  The mpfr precision is
13593    set to the precision of TYPE.  We assume that function FUNC returns
13594    zero if the result could be calculated exactly within the requested
13595    precision.  */
13596
13597 static tree
13598 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13599               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13600               bool inclusive)
13601 {
13602   tree result = NULL_TREE;
13603
13604   STRIP_NOPS (arg);
13605
13606   /* To proceed, MPFR must exactly represent the target floating point
13607      format, which only happens when the target base equals two.  */
13608   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13609       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13610     {
13611       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13612
13613       if (real_isfinite (ra)
13614           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13615           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13616         {
13617           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13618           const int prec = fmt->p;
13619           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13620           int inexact;
13621           mpfr_t m;
13622
13623           mpfr_init2 (m, prec);
13624           mpfr_from_real (m, ra, GMP_RNDN);
13625           mpfr_clear_flags ();
13626           inexact = func (m, m, rnd);
13627           result = do_mpfr_ckconv (m, type, inexact);
13628           mpfr_clear (m);
13629         }
13630     }
13631
13632   return result;
13633 }
13634
13635 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13636    FUNC on it and return the resulting value as a tree with type TYPE.
13637    The mpfr precision is set to the precision of TYPE.  We assume that
13638    function FUNC returns zero if the result could be calculated
13639    exactly within the requested precision.  */
13640
13641 static tree
13642 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13643               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13644 {
13645   tree result = NULL_TREE;
13646
13647   STRIP_NOPS (arg1);
13648   STRIP_NOPS (arg2);
13649
13650   /* To proceed, MPFR must exactly represent the target floating point
13651      format, which only happens when the target base equals two.  */
13652   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13653       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13654       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13655     {
13656       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13657       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13658
13659       if (real_isfinite (ra1) && real_isfinite (ra2))
13660         {
13661           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13662           const int prec = fmt->p;
13663           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13664           int inexact;
13665           mpfr_t m1, m2;
13666
13667           mpfr_inits2 (prec, m1, m2, NULL);
13668           mpfr_from_real (m1, ra1, GMP_RNDN);
13669           mpfr_from_real (m2, ra2, GMP_RNDN);
13670           mpfr_clear_flags ();
13671           inexact = func (m1, m1, m2, rnd);
13672           result = do_mpfr_ckconv (m1, type, inexact);
13673           mpfr_clears (m1, m2, NULL);
13674         }
13675     }
13676
13677   return result;
13678 }
13679
13680 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13681    FUNC on it and return the resulting value as a tree with type TYPE.
13682    The mpfr precision is set to the precision of TYPE.  We assume that
13683    function FUNC returns zero if the result could be calculated
13684    exactly within the requested precision.  */
13685
13686 static tree
13687 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13688               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13689 {
13690   tree result = NULL_TREE;
13691
13692   STRIP_NOPS (arg1);
13693   STRIP_NOPS (arg2);
13694   STRIP_NOPS (arg3);
13695
13696   /* To proceed, MPFR must exactly represent the target floating point
13697      format, which only happens when the target base equals two.  */
13698   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13699       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13700       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13701       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13702     {
13703       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13704       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13705       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13706
13707       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13708         {
13709           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13710           const int prec = fmt->p;
13711           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13712           int inexact;
13713           mpfr_t m1, m2, m3;
13714
13715           mpfr_inits2 (prec, m1, m2, m3, NULL);
13716           mpfr_from_real (m1, ra1, GMP_RNDN);
13717           mpfr_from_real (m2, ra2, GMP_RNDN);
13718           mpfr_from_real (m3, ra3, GMP_RNDN);
13719           mpfr_clear_flags ();
13720           inexact = func (m1, m1, m2, m3, rnd);
13721           result = do_mpfr_ckconv (m1, type, inexact);
13722           mpfr_clears (m1, m2, m3, NULL);
13723         }
13724     }
13725
13726   return result;
13727 }
13728
13729 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13730    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13731    If ARG_SINP and ARG_COSP are NULL then the result is returned
13732    as a complex value.
13733    The type is taken from the type of ARG and is used for setting the
13734    precision of the calculation and results.  */
13735
13736 static tree
13737 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13738 {
13739   tree const type = TREE_TYPE (arg);
13740   tree result = NULL_TREE;
13741
13742   STRIP_NOPS (arg);
13743
13744   /* To proceed, MPFR must exactly represent the target floating point
13745      format, which only happens when the target base equals two.  */
13746   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13747       && TREE_CODE (arg) == REAL_CST
13748       && !TREE_OVERFLOW (arg))
13749     {
13750       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13751
13752       if (real_isfinite (ra))
13753         {
13754           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13755           const int prec = fmt->p;
13756           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13757           tree result_s, result_c;
13758           int inexact;
13759           mpfr_t m, ms, mc;
13760
13761           mpfr_inits2 (prec, m, ms, mc, NULL);
13762           mpfr_from_real (m, ra, GMP_RNDN);
13763           mpfr_clear_flags ();
13764           inexact = mpfr_sin_cos (ms, mc, m, rnd);
13765           result_s = do_mpfr_ckconv (ms, type, inexact);
13766           result_c = do_mpfr_ckconv (mc, type, inexact);
13767           mpfr_clears (m, ms, mc, NULL);
13768           if (result_s && result_c)
13769             {
13770               /* If we are to return in a complex value do so.  */
13771               if (!arg_sinp && !arg_cosp)
13772                 return build_complex (build_complex_type (type),
13773                                       result_c, result_s);
13774
13775               /* Dereference the sin/cos pointer arguments.  */
13776               arg_sinp = build_fold_indirect_ref (arg_sinp);
13777               arg_cosp = build_fold_indirect_ref (arg_cosp);
13778               /* Proceed if valid pointer type were passed in.  */
13779               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13780                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13781                 {
13782                   /* Set the values. */
13783                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13784                                           result_s);
13785                   TREE_SIDE_EFFECTS (result_s) = 1;
13786                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13787                                           result_c);
13788                   TREE_SIDE_EFFECTS (result_c) = 1;
13789                   /* Combine the assignments into a compound expr.  */
13790                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13791                                                     result_s, result_c));
13792                 }
13793             }
13794         }
13795     }
13796   return result;
13797 }
13798
13799 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13800    two-argument mpfr order N Bessel function FUNC on them and return
13801    the resulting value as a tree with type TYPE.  The mpfr precision
13802    is set to the precision of TYPE.  We assume that function FUNC
13803    returns zero if the result could be calculated exactly within the
13804    requested precision.  */
13805 static tree
13806 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13807                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13808                   const REAL_VALUE_TYPE *min, bool inclusive)
13809 {
13810   tree result = NULL_TREE;
13811
13812   STRIP_NOPS (arg1);
13813   STRIP_NOPS (arg2);
13814
13815   /* To proceed, MPFR must exactly represent the target floating point
13816      format, which only happens when the target base equals two.  */
13817   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13818       && host_integerp (arg1, 0)
13819       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13820     {
13821       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13822       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13823
13824       if (n == (long)n
13825           && real_isfinite (ra)
13826           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13827         {
13828           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13829           const int prec = fmt->p;
13830           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13831           int inexact;
13832           mpfr_t m;
13833
13834           mpfr_init2 (m, prec);
13835           mpfr_from_real (m, ra, GMP_RNDN);
13836           mpfr_clear_flags ();
13837           inexact = func (m, n, m, rnd);
13838           result = do_mpfr_ckconv (m, type, inexact);
13839           mpfr_clear (m);
13840         }
13841     }
13842
13843   return result;
13844 }
13845
13846 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13847    the pointer *(ARG_QUO) and return the result.  The type is taken
13848    from the type of ARG0 and is used for setting the precision of the
13849    calculation and results.  */
13850
13851 static tree
13852 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13853 {
13854   tree const type = TREE_TYPE (arg0);
13855   tree result = NULL_TREE;
13856
13857   STRIP_NOPS (arg0);
13858   STRIP_NOPS (arg1);
13859
13860   /* To proceed, MPFR must exactly represent the target floating point
13861      format, which only happens when the target base equals two.  */
13862   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13863       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13864       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13865     {
13866       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13867       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13868
13869       if (real_isfinite (ra0) && real_isfinite (ra1))
13870         {
13871           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13872           const int prec = fmt->p;
13873           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13874           tree result_rem;
13875           long integer_quo;
13876           mpfr_t m0, m1;
13877
13878           mpfr_inits2 (prec, m0, m1, NULL);
13879           mpfr_from_real (m0, ra0, GMP_RNDN);
13880           mpfr_from_real (m1, ra1, GMP_RNDN);
13881           mpfr_clear_flags ();
13882           mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13883           /* Remquo is independent of the rounding mode, so pass
13884              inexact=0 to do_mpfr_ckconv().  */
13885           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13886           mpfr_clears (m0, m1, NULL);
13887           if (result_rem)
13888             {
13889               /* MPFR calculates quo in the host's long so it may
13890                  return more bits in quo than the target int can hold
13891                  if sizeof(host long) > sizeof(target int).  This can
13892                  happen even for native compilers in LP64 mode.  In
13893                  these cases, modulo the quo value with the largest
13894                  number that the target int can hold while leaving one
13895                  bit for the sign.  */
13896               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13897                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13898
13899               /* Dereference the quo pointer argument.  */
13900               arg_quo = build_fold_indirect_ref (arg_quo);
13901               /* Proceed iff a valid pointer type was passed in.  */
13902               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13903                 {
13904                   /* Set the value. */
13905                   tree result_quo
13906                     = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo,
13907                                    build_int_cst (TREE_TYPE (arg_quo),
13908                                                   integer_quo));
13909                   TREE_SIDE_EFFECTS (result_quo) = 1;
13910                   /* Combine the quo assignment with the rem.  */
13911                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13912                                                     result_quo, result_rem));
13913                 }
13914             }
13915         }
13916     }
13917   return result;
13918 }
13919
13920 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13921    resulting value as a tree with type TYPE.  The mpfr precision is
13922    set to the precision of TYPE.  We assume that this mpfr function
13923    returns zero if the result could be calculated exactly within the
13924    requested precision.  In addition, the integer pointer represented
13925    by ARG_SG will be dereferenced and set to the appropriate signgam
13926    (-1,1) value.  */
13927
13928 static tree
13929 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13930 {
13931   tree result = NULL_TREE;
13932
13933   STRIP_NOPS (arg);
13934
13935   /* To proceed, MPFR must exactly represent the target floating point
13936      format, which only happens when the target base equals two.  Also
13937      verify ARG is a constant and that ARG_SG is an int pointer.  */
13938   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13939       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13940       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13941       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13942     {
13943       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13944
13945       /* In addition to NaN and Inf, the argument cannot be zero or a
13946          negative integer.  */
13947       if (real_isfinite (ra)
13948           && ra->cl != rvc_zero
13949           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13950         {
13951           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13952           const int prec = fmt->p;
13953           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13954           int inexact, sg;
13955           mpfr_t m;
13956           tree result_lg;
13957
13958           mpfr_init2 (m, prec);
13959           mpfr_from_real (m, ra, GMP_RNDN);
13960           mpfr_clear_flags ();
13961           inexact = mpfr_lgamma (m, &sg, m, rnd);
13962           result_lg = do_mpfr_ckconv (m, type, inexact);
13963           mpfr_clear (m);
13964           if (result_lg)
13965             {
13966               tree result_sg;
13967
13968               /* Dereference the arg_sg pointer argument.  */
13969               arg_sg = build_fold_indirect_ref (arg_sg);
13970               /* Assign the signgam value into *arg_sg. */
13971               result_sg = fold_build2 (MODIFY_EXPR,
13972                                        TREE_TYPE (arg_sg), arg_sg,
13973                                        build_int_cst (TREE_TYPE (arg_sg), sg));
13974               TREE_SIDE_EFFECTS (result_sg) = 1;
13975               /* Combine the signgam assignment with the lgamma result.  */
13976               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13977                                                 result_sg, result_lg));
13978             }
13979         }
13980     }
13981
13982   return result;
13983 }
13984
13985 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13986    function FUNC on it and return the resulting value as a tree with
13987    type TYPE.  The mpfr precision is set to the precision of TYPE.  We
13988    assume that function FUNC returns zero if the result could be
13989    calculated exactly within the requested precision.  */
13990
13991 static tree
13992 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13993 {
13994   tree result = NULL_TREE;
13995
13996   STRIP_NOPS (arg);
13997
13998   /* To proceed, MPFR must exactly represent the target floating point
13999      format, which only happens when the target base equals two.  */
14000   if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
14001       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
14002       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
14003     {
14004       const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
14005       const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
14006
14007       if (real_isfinite (re) && real_isfinite (im))
14008         {
14009           const struct real_format *const fmt =
14010             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14011           const int prec = fmt->p;
14012           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14013           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14014           int inexact;
14015           mpc_t m;
14016
14017           mpc_init2 (m, prec);
14018           mpfr_from_real (mpc_realref(m), re, rnd);
14019           mpfr_from_real (mpc_imagref(m), im, rnd);
14020           mpfr_clear_flags ();
14021           inexact = func (m, m, crnd);
14022           result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
14023           mpc_clear (m);
14024         }
14025     }
14026
14027   return result;
14028 }
14029
14030 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
14031    mpc function FUNC on it and return the resulting value as a tree
14032    with type TYPE.  The mpfr precision is set to the precision of
14033    TYPE.  We assume that function FUNC returns zero if the result
14034    could be calculated exactly within the requested precision.  If
14035    DO_NONFINITE is true, then fold expressions containing Inf or NaN
14036    in the arguments and/or results.  */
14037
14038 tree
14039 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
14040              int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
14041 {
14042   tree result = NULL_TREE;
14043
14044   STRIP_NOPS (arg0);
14045   STRIP_NOPS (arg1);
14046
14047   /* To proceed, MPFR must exactly represent the target floating point
14048      format, which only happens when the target base equals two.  */
14049   if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
14050       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
14051       && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
14052       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
14053       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
14054     {
14055       const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
14056       const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
14057       const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
14058       const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
14059
14060       if (do_nonfinite
14061           || (real_isfinite (re0) && real_isfinite (im0)
14062               && real_isfinite (re1) && real_isfinite (im1)))
14063         {
14064           const struct real_format *const fmt =
14065             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14066           const int prec = fmt->p;
14067           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14068           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14069           int inexact;
14070           mpc_t m0, m1;
14071
14072           mpc_init2 (m0, prec);
14073           mpc_init2 (m1, prec);
14074           mpfr_from_real (mpc_realref(m0), re0, rnd);
14075           mpfr_from_real (mpc_imagref(m0), im0, rnd);
14076           mpfr_from_real (mpc_realref(m1), re1, rnd);
14077           mpfr_from_real (mpc_imagref(m1), im1, rnd);
14078           mpfr_clear_flags ();
14079           inexact = func (m0, m0, m1, crnd);
14080           result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
14081           mpc_clear (m0);
14082           mpc_clear (m1);
14083         }
14084     }
14085
14086   return result;
14087 }
14088
14089 /* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
14090    a normal call should be emitted rather than expanding the function
14091    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
14092
14093 static tree
14094 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
14095 {
14096   int nargs = gimple_call_num_args (stmt);
14097
14098   return fold_builtin_sprintf_chk_1 (gimple_location (stmt), nargs,
14099                                      (nargs > 0
14100                                       ? gimple_call_arg_ptr (stmt, 0)
14101                                       : &error_mark_node), fcode);
14102 }
14103
14104 /* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
14105    a normal call should be emitted rather than expanding the function
14106    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
14107    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
14108    passed as second argument.  */
14109
14110 tree
14111 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14112                                   enum built_in_function fcode)
14113 {
14114   int nargs = gimple_call_num_args (stmt);
14115
14116   return fold_builtin_snprintf_chk_1 (gimple_location (stmt), nargs,
14117                                       (nargs > 0
14118                                        ? gimple_call_arg_ptr (stmt, 0)
14119                                        : &error_mark_node), maxlen, fcode);
14120 }
14121
14122 /* Builtins with folding operations that operate on "..." arguments
14123    need special handling; we need to store the arguments in a convenient
14124    data structure before attempting any folding.  Fortunately there are
14125    only a few builtins that fall into this category.  FNDECL is the
14126    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14127    result of the function call is ignored.  */
14128
14129 static tree
14130 gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14131                              bool ignore ATTRIBUTE_UNUSED)
14132 {
14133   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14134   tree ret = NULL_TREE;
14135
14136   switch (fcode)
14137     {
14138     case BUILT_IN_SPRINTF_CHK:
14139     case BUILT_IN_VSPRINTF_CHK:
14140       ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14141       break;
14142
14143     case BUILT_IN_SNPRINTF_CHK:
14144     case BUILT_IN_VSNPRINTF_CHK:
14145       ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14146
14147     default:
14148       break;
14149     }
14150   if (ret)
14151     {
14152       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14153       TREE_NO_WARNING (ret) = 1;
14154       return ret;
14155     }
14156   return NULL_TREE;
14157 }
14158
14159 /* A wrapper function for builtin folding that prevents warnings for
14160    "statement without effect" and the like, caused by removing the
14161    call node earlier than the warning is generated.  */
14162
14163 tree
14164 fold_call_stmt (gimple stmt, bool ignore)
14165 {
14166   tree ret = NULL_TREE;
14167   tree fndecl = gimple_call_fndecl (stmt);
14168   location_t loc = gimple_location (stmt);
14169   if (fndecl
14170       && TREE_CODE (fndecl) == FUNCTION_DECL
14171       && DECL_BUILT_IN (fndecl)
14172       && !gimple_call_va_arg_pack_p (stmt))
14173     {
14174       int nargs = gimple_call_num_args (stmt);
14175       tree *args = (nargs > 0
14176                     ? gimple_call_arg_ptr (stmt, 0)
14177                     : &error_mark_node);
14178
14179       if (avoid_folding_inline_builtin (fndecl))
14180         return NULL_TREE;
14181       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14182         {
14183           return targetm.fold_builtin (fndecl, nargs, args, ignore);
14184         }
14185       else
14186         {
14187           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14188             ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
14189           if (!ret)
14190             ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14191           if (ret)
14192             {
14193               /* Propagate location information from original call to
14194                  expansion of builtin.  Otherwise things like
14195                  maybe_emit_chk_warning, that operate on the expansion
14196                  of a builtin, will use the wrong location information.  */
14197               if (gimple_has_location (stmt))
14198                 {
14199                   tree realret = ret;
14200                   if (TREE_CODE (ret) == NOP_EXPR)
14201                     realret = TREE_OPERAND (ret, 0);
14202                   if (CAN_HAVE_LOCATION_P (realret)
14203                       && !EXPR_HAS_LOCATION (realret))
14204                     SET_EXPR_LOCATION (realret, loc);
14205                   return realret;
14206                 }
14207               return ret;
14208             }
14209         }
14210     }
14211   return NULL_TREE;
14212 }
14213
14214 /* Look up the function in builtin_decl that corresponds to DECL
14215    and set ASMSPEC as its user assembler name.  DECL must be a
14216    function decl that declares a builtin.  */
14217
14218 void
14219 set_builtin_user_assembler_name (tree decl, const char *asmspec)
14220 {
14221   tree builtin;
14222   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
14223               && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
14224               && asmspec != 0);
14225
14226   builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
14227   set_user_assembler_name (builtin, asmspec);
14228   switch (DECL_FUNCTION_CODE (decl))
14229     {
14230     case BUILT_IN_MEMCPY:
14231       init_block_move_fn (asmspec);
14232       memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
14233       break;
14234     case BUILT_IN_MEMSET:
14235       init_block_clear_fn (asmspec);
14236       memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
14237       break;
14238     case BUILT_IN_MEMMOVE:
14239       memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
14240       break;
14241     case BUILT_IN_MEMCMP:
14242       memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
14243       break;
14244     case BUILT_IN_ABORT:
14245       abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
14246       break;
14247     case BUILT_IN_FFS:
14248       if (INT_TYPE_SIZE < BITS_PER_WORD)
14249         {
14250           set_user_assembler_libfunc ("ffs", asmspec);
14251           set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
14252                                                        MODE_INT, 0), "ffs");
14253         }
14254       break;
14255     default:
14256       break;
14257     }
14258 }
14259
14260 /* Return true if DECL is a builtin that expands to a constant or similarly
14261    simple code.  */
14262 bool
14263 is_simple_builtin (tree decl)
14264 {
14265   if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14266     switch (DECL_FUNCTION_CODE (decl))
14267       {
14268         /* Builtins that expand to constants.  */
14269       case BUILT_IN_CONSTANT_P:
14270       case BUILT_IN_EXPECT:
14271       case BUILT_IN_OBJECT_SIZE:
14272       case BUILT_IN_UNREACHABLE:
14273         /* Simple register moves or loads from stack.  */
14274       case BUILT_IN_ASSUME_ALIGNED:
14275       case BUILT_IN_RETURN_ADDRESS:
14276       case BUILT_IN_EXTRACT_RETURN_ADDR:
14277       case BUILT_IN_FROB_RETURN_ADDR:
14278       case BUILT_IN_RETURN:
14279       case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
14280       case BUILT_IN_FRAME_ADDRESS:
14281       case BUILT_IN_VA_END:
14282       case BUILT_IN_STACK_SAVE:
14283       case BUILT_IN_STACK_RESTORE:
14284         /* Exception state returns or moves registers around.  */
14285       case BUILT_IN_EH_FILTER:
14286       case BUILT_IN_EH_POINTER:
14287       case BUILT_IN_EH_COPY_VALUES:
14288         return true;
14289
14290       default:
14291         return false;
14292       }
14293
14294   return false;
14295 }
14296
14297 /* Return true if DECL is a builtin that is not expensive, i.e., they are
14298    most probably expanded inline into reasonably simple code.  This is a
14299    superset of is_simple_builtin.  */
14300 bool
14301 is_inexpensive_builtin (tree decl)
14302 {
14303   if (!decl)
14304     return false;
14305   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
14306     return true;
14307   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14308     switch (DECL_FUNCTION_CODE (decl))
14309       {
14310       case BUILT_IN_ABS:
14311       case BUILT_IN_ALLOCA:
14312       case BUILT_IN_ALLOCA_WITH_ALIGN:
14313       case BUILT_IN_BSWAP32:
14314       case BUILT_IN_BSWAP64:
14315       case BUILT_IN_CLZ:
14316       case BUILT_IN_CLZIMAX:
14317       case BUILT_IN_CLZL:
14318       case BUILT_IN_CLZLL:
14319       case BUILT_IN_CTZ:
14320       case BUILT_IN_CTZIMAX:
14321       case BUILT_IN_CTZL:
14322       case BUILT_IN_CTZLL:
14323       case BUILT_IN_FFS:
14324       case BUILT_IN_FFSIMAX:
14325       case BUILT_IN_FFSL:
14326       case BUILT_IN_FFSLL:
14327       case BUILT_IN_IMAXABS:
14328       case BUILT_IN_FINITE:
14329       case BUILT_IN_FINITEF:
14330       case BUILT_IN_FINITEL:
14331       case BUILT_IN_FINITED32:
14332       case BUILT_IN_FINITED64:
14333       case BUILT_IN_FINITED128:
14334       case BUILT_IN_FPCLASSIFY:
14335       case BUILT_IN_ISFINITE:
14336       case BUILT_IN_ISINF_SIGN:
14337       case BUILT_IN_ISINF:
14338       case BUILT_IN_ISINFF:
14339       case BUILT_IN_ISINFL:
14340       case BUILT_IN_ISINFD32:
14341       case BUILT_IN_ISINFD64:
14342       case BUILT_IN_ISINFD128:
14343       case BUILT_IN_ISNAN:
14344       case BUILT_IN_ISNANF:
14345       case BUILT_IN_ISNANL:
14346       case BUILT_IN_ISNAND32:
14347       case BUILT_IN_ISNAND64:
14348       case BUILT_IN_ISNAND128:
14349       case BUILT_IN_ISNORMAL:
14350       case BUILT_IN_ISGREATER:
14351       case BUILT_IN_ISGREATEREQUAL:
14352       case BUILT_IN_ISLESS:
14353       case BUILT_IN_ISLESSEQUAL:
14354       case BUILT_IN_ISLESSGREATER:
14355       case BUILT_IN_ISUNORDERED:
14356       case BUILT_IN_VA_ARG_PACK:
14357       case BUILT_IN_VA_ARG_PACK_LEN:
14358       case BUILT_IN_VA_COPY:
14359       case BUILT_IN_TRAP:
14360       case BUILT_IN_SAVEREGS:
14361       case BUILT_IN_POPCOUNTL:
14362       case BUILT_IN_POPCOUNTLL:
14363       case BUILT_IN_POPCOUNTIMAX:
14364       case BUILT_IN_POPCOUNT:
14365       case BUILT_IN_PARITYL:
14366       case BUILT_IN_PARITYLL:
14367       case BUILT_IN_PARITYIMAX:
14368       case BUILT_IN_PARITY:
14369       case BUILT_IN_LABS:
14370       case BUILT_IN_LLABS:
14371       case BUILT_IN_PREFETCH:
14372         return true;
14373
14374       default:
14375         return is_simple_builtin (decl);
14376       }
14377
14378   return false;
14379 }