re PR middle-end/55030 (gcc.c-torture/execute/builtins/memcpy-chk.c execution, ...
[platform/upstream/gcc.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988-2013 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "machmode.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "realmpfr.h"
28 #include "gimple.h"
29 #include "flags.h"
30 #include "regs.h"
31 #include "hard-reg-set.h"
32 #include "except.h"
33 #include "function.h"
34 #include "insn-config.h"
35 #include "expr.h"
36 #include "optabs.h"
37 #include "libfuncs.h"
38 #include "recog.h"
39 #include "output.h"
40 #include "typeclass.h"
41 #include "predict.h"
42 #include "tm_p.h"
43 #include "target.h"
44 #include "langhooks.h"
45 #include "basic-block.h"
46 #include "tree-mudflap.h"
47 #include "tree-flow.h"
48 #include "value-prof.h"
49 #include "diagnostic-core.h"
50 #include "builtins.h"
51
52
53 #ifndef PAD_VARARGS_DOWN
54 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
55 #endif
56 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
57
58 struct target_builtins default_target_builtins;
59 #if SWITCHABLE_TARGET
60 struct target_builtins *this_target_builtins = &default_target_builtins;
61 #endif
62
63 /* Define the names of the builtin function types and codes.  */
64 const char *const built_in_class_names[4]
65   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
66
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
68 const char * built_in_names[(int) END_BUILTINS] =
69 {
70 #include "builtins.def"
71 };
72 #undef DEF_BUILTIN
73
74 /* Setup an array of _DECL trees, make sure each element is
75    initialized to NULL_TREE.  */
76 builtin_info_type builtin_info;
77
78 /* Non-zero if __builtin_constant_p should be folded right away.  */
79 bool force_folding_builtin_constant_p;
80
81 static const char *c_getstr (tree);
82 static rtx c_readstr (const char *, enum machine_mode);
83 static int target_char_cast (tree, char *);
84 static rtx get_memory_rtx (tree, tree);
85 static int apply_args_size (void);
86 static int apply_result_size (void);
87 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
88 static rtx result_vector (int, rtx);
89 #endif
90 static void expand_builtin_update_setjmp_buf (rtx);
91 static void expand_builtin_prefetch (tree);
92 static rtx expand_builtin_apply_args (void);
93 static rtx expand_builtin_apply_args_1 (void);
94 static rtx expand_builtin_apply (rtx, rtx, rtx);
95 static void expand_builtin_return (rtx);
96 static enum type_class type_to_class (tree);
97 static rtx expand_builtin_classify_type (tree);
98 static void expand_errno_check (tree, rtx);
99 static rtx expand_builtin_mathfn (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
101 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
102 static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
103 static rtx expand_builtin_interclass_mathfn (tree, rtx);
104 static rtx expand_builtin_sincos (tree);
105 static rtx expand_builtin_cexpi (tree, rtx);
106 static rtx expand_builtin_int_roundingfn (tree, rtx);
107 static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
108 static rtx expand_builtin_next_arg (void);
109 static rtx expand_builtin_va_start (tree);
110 static rtx expand_builtin_va_end (tree);
111 static rtx expand_builtin_va_copy (tree);
112 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strcmp (tree, rtx);
114 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
115 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
116 static rtx expand_builtin_memcpy (tree, rtx);
117 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
119                                         enum machine_mode, int);
120 static rtx expand_builtin_strcpy (tree, rtx);
121 static rtx expand_builtin_strcpy_args (tree, tree, rtx);
122 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
123 static rtx expand_builtin_strncpy (tree, rtx);
124 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
125 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
127 static rtx expand_builtin_bzero (tree);
128 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_alloca (tree, bool);
130 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
131 static rtx expand_builtin_frame_address (tree, tree);
132 static tree stabilize_va_list_loc (location_t, tree, int);
133 static rtx expand_builtin_expect (tree, rtx);
134 static tree fold_builtin_constant_p (tree);
135 static tree fold_builtin_expect (location_t, tree, tree);
136 static tree fold_builtin_classify_type (tree);
137 static tree fold_builtin_strlen (location_t, tree, tree);
138 static tree fold_builtin_inf (location_t, tree, int);
139 static tree fold_builtin_nan (tree, tree, int);
140 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
141 static bool validate_arg (const_tree, enum tree_code code);
142 static bool integer_valued_real_p (tree);
143 static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
144 static bool readonly_data_expr (tree);
145 static rtx expand_builtin_fabs (tree, rtx, rtx);
146 static rtx expand_builtin_signbit (tree, rtx);
147 static tree fold_builtin_sqrt (location_t, tree, tree);
148 static tree fold_builtin_cbrt (location_t, tree, tree);
149 static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
150 static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
151 static tree fold_builtin_cos (location_t, tree, tree, tree);
152 static tree fold_builtin_cosh (location_t, tree, tree, tree);
153 static tree fold_builtin_tan (tree, tree);
154 static tree fold_builtin_trunc (location_t, tree, tree);
155 static tree fold_builtin_floor (location_t, tree, tree);
156 static tree fold_builtin_ceil (location_t, tree, tree);
157 static tree fold_builtin_round (location_t, tree, tree);
158 static tree fold_builtin_int_roundingfn (location_t, tree, tree);
159 static tree fold_builtin_bitop (tree, tree);
160 static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
161 static tree fold_builtin_strchr (location_t, tree, tree, tree);
162 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
163 static tree fold_builtin_memcmp (location_t, tree, tree, tree);
164 static tree fold_builtin_strcmp (location_t, tree, tree);
165 static tree fold_builtin_strncmp (location_t, tree, tree, tree);
166 static tree fold_builtin_signbit (location_t, tree, tree);
167 static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
168 static tree fold_builtin_isascii (location_t, tree);
169 static tree fold_builtin_toascii (location_t, tree);
170 static tree fold_builtin_isdigit (location_t, tree);
171 static tree fold_builtin_fabs (location_t, tree, tree);
172 static tree fold_builtin_abs (location_t, tree, tree);
173 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
174                                         enum tree_code);
175 static tree fold_builtin_n (location_t, tree, tree *, int, bool);
176 static tree fold_builtin_0 (location_t, tree, bool);
177 static tree fold_builtin_1 (location_t, tree, tree, bool);
178 static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
179 static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
180 static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
181 static tree fold_builtin_varargs (location_t, tree, tree, bool);
182
183 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
184 static tree fold_builtin_strstr (location_t, tree, tree, tree);
185 static tree fold_builtin_strrchr (location_t, tree, tree, tree);
186 static tree fold_builtin_strcat (location_t, tree, tree);
187 static tree fold_builtin_strncat (location_t, tree, tree, tree);
188 static tree fold_builtin_strspn (location_t, tree, tree);
189 static tree fold_builtin_strcspn (location_t, tree, tree);
190 static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
191 static tree fold_builtin_snprintf (location_t, tree, tree, tree, tree, int);
192
193 static rtx expand_builtin_object_size (tree);
194 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
195                                       enum built_in_function);
196 static void maybe_emit_chk_warning (tree, enum built_in_function);
197 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
198 static void maybe_emit_free_warning (tree);
199 static tree fold_builtin_object_size (tree, tree);
200 static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
201 static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
202 static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
203 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
204 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
205                                   enum built_in_function);
206 static bool init_target_chars (void);
207
208 static unsigned HOST_WIDE_INT target_newline;
209 static unsigned HOST_WIDE_INT target_percent;
210 static unsigned HOST_WIDE_INT target_c;
211 static unsigned HOST_WIDE_INT target_s;
212 static char target_percent_c[3];
213 static char target_percent_s[3];
214 static char target_percent_s_newline[4];
215 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
216                           const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
217 static tree do_mpfr_arg2 (tree, tree, tree,
218                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
219 static tree do_mpfr_arg3 (tree, tree, tree, tree,
220                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
221 static tree do_mpfr_sincos (tree, tree, tree);
222 static tree do_mpfr_bessel_n (tree, tree, tree,
223                               int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
224                               const REAL_VALUE_TYPE *, bool);
225 static tree do_mpfr_remquo (tree, tree, tree);
226 static tree do_mpfr_lgamma_r (tree, tree, tree);
227 static void expand_builtin_sync_synchronize (void);
228
229 /* Return true if NAME starts with __builtin_ or __sync_.  */
230
231 static bool
232 is_builtin_name (const char *name)
233 {
234   if (strncmp (name, "__builtin_", 10) == 0)
235     return true;
236   if (strncmp (name, "__sync_", 7) == 0)
237     return true;
238   if (strncmp (name, "__atomic_", 9) == 0)
239     return true;
240   return false;
241 }
242
243
244 /* Return true if DECL is a function symbol representing a built-in.  */
245
246 bool
247 is_builtin_fn (tree decl)
248 {
249   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
250 }
251
252
253 /* Return true if NODE should be considered for inline expansion regardless
254    of the optimization level.  This means whenever a function is invoked with
255    its "internal" name, which normally contains the prefix "__builtin".  */
256
257 static bool
258 called_as_built_in (tree node)
259 {
260   /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
261      we want the name used to call the function, not the name it
262      will have. */
263   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
264   return is_builtin_name (name);
265 }
266
267 /* Compute values M and N such that M divides (address of EXP - N) and such
268    that N < M.  If these numbers can be determined, store M in alignp and N in
269    *BITPOSP and return true.  Otherwise return false and store BITS_PER_UNIT to
270    *alignp and any bit-offset to *bitposp.
271
272    Note that the address (and thus the alignment) computed here is based
273    on the address to which a symbol resolves, whereas DECL_ALIGN is based
274    on the address at which an object is actually located.  These two
275    addresses are not always the same.  For example, on ARM targets,
276    the address &foo of a Thumb function foo() has the lowest bit set,
277    whereas foo() itself starts on an even address.
278
279    If ADDR_P is true we are taking the address of the memory reference EXP
280    and thus cannot rely on the access taking place.  */
281
282 static bool
283 get_object_alignment_2 (tree exp, unsigned int *alignp,
284                         unsigned HOST_WIDE_INT *bitposp, bool addr_p)
285 {
286   HOST_WIDE_INT bitsize, bitpos;
287   tree offset;
288   enum machine_mode mode;
289   int unsignedp, volatilep;
290   unsigned int inner, align = BITS_PER_UNIT;
291   bool known_alignment = false;
292
293   /* Get the innermost object and the constant (bitpos) and possibly
294      variable (offset) offset of the access.  */
295   exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
296                              &mode, &unsignedp, &volatilep, true);
297
298   /* Extract alignment information from the innermost object and
299      possibly adjust bitpos and offset.  */
300   if (TREE_CODE (exp) == FUNCTION_DECL)
301     {
302       /* Function addresses can encode extra information besides their
303          alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
304          allows the low bit to be used as a virtual bit, we know
305          that the address itself must be at least 2-byte aligned.  */
306       if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
307         align = 2 * BITS_PER_UNIT;
308     }
309   else if (TREE_CODE (exp) == LABEL_DECL)
310     ;
311   else if (TREE_CODE (exp) == CONST_DECL)
312     {
313       /* The alignment of a CONST_DECL is determined by its initializer.  */
314       exp = DECL_INITIAL (exp);
315       align = TYPE_ALIGN (TREE_TYPE (exp));
316 #ifdef CONSTANT_ALIGNMENT
317       if (CONSTANT_CLASS_P (exp))
318         align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
319 #endif
320       known_alignment = true;
321     }
322   else if (DECL_P (exp))
323     {
324       align = DECL_ALIGN (exp);
325       known_alignment = true;
326     }
327   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
328     {
329       align = TYPE_ALIGN (TREE_TYPE (exp));
330     }
331   else if (TREE_CODE (exp) == INDIRECT_REF
332            || TREE_CODE (exp) == MEM_REF
333            || TREE_CODE (exp) == TARGET_MEM_REF)
334     {
335       tree addr = TREE_OPERAND (exp, 0);
336       unsigned ptr_align;
337       unsigned HOST_WIDE_INT ptr_bitpos;
338
339       if (TREE_CODE (addr) == BIT_AND_EXPR
340           && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
341         {
342           align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
343                     & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
344           align *= BITS_PER_UNIT;
345           addr = TREE_OPERAND (addr, 0);
346         }
347
348       known_alignment
349         = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos);
350       align = MAX (ptr_align, align);
351
352       /* The alignment of the pointer operand in a TARGET_MEM_REF
353          has to take the variable offset parts into account.  */
354       if (TREE_CODE (exp) == TARGET_MEM_REF)
355         {
356           if (TMR_INDEX (exp))
357             {
358               unsigned HOST_WIDE_INT step = 1;
359               if (TMR_STEP (exp))
360                 step = TREE_INT_CST_LOW (TMR_STEP (exp));
361               align = MIN (align, (step & -step) * BITS_PER_UNIT);
362             }
363           if (TMR_INDEX2 (exp))
364             align = BITS_PER_UNIT;
365           known_alignment = false;
366         }
367
368       /* When EXP is an actual memory reference then we can use
369          TYPE_ALIGN of a pointer indirection to derive alignment.
370          Do so only if get_pointer_alignment_1 did not reveal absolute
371          alignment knowledge and if using that alignment would
372          improve the situation.  */
373       if (!addr_p && !known_alignment
374           && TYPE_ALIGN (TREE_TYPE (exp)) > align)
375         align = TYPE_ALIGN (TREE_TYPE (exp));
376       else
377         {
378           /* Else adjust bitpos accordingly.  */
379           bitpos += ptr_bitpos;
380           if (TREE_CODE (exp) == MEM_REF
381               || TREE_CODE (exp) == TARGET_MEM_REF)
382             bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
383         }
384     }
385   else if (TREE_CODE (exp) == STRING_CST)
386     {
387       /* STRING_CST are the only constant objects we allow to be not
388          wrapped inside a CONST_DECL.  */
389       align = TYPE_ALIGN (TREE_TYPE (exp));
390 #ifdef CONSTANT_ALIGNMENT
391       if (CONSTANT_CLASS_P (exp))
392         align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
393 #endif
394       known_alignment = true;
395     }
396
397   /* If there is a non-constant offset part extract the maximum
398      alignment that can prevail.  */
399   inner = ~0U;
400   while (offset)
401     {
402       tree next_offset;
403
404       if (TREE_CODE (offset) == PLUS_EXPR)
405         {
406           next_offset = TREE_OPERAND (offset, 0);
407           offset = TREE_OPERAND (offset, 1);
408         }
409       else
410         next_offset = NULL;
411       if (host_integerp (offset, 1))
412         {
413           /* Any overflow in calculating offset_bits won't change
414              the alignment.  */
415           unsigned offset_bits
416             = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
417
418           if (offset_bits)
419             inner = MIN (inner, (offset_bits & -offset_bits));
420         }
421       else if (TREE_CODE (offset) == MULT_EXPR
422                && host_integerp (TREE_OPERAND (offset, 1), 1))
423         {
424           /* Any overflow in calculating offset_factor won't change
425              the alignment.  */
426           unsigned offset_factor
427             = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
428                * BITS_PER_UNIT);
429
430           if (offset_factor)
431             inner = MIN (inner, (offset_factor & -offset_factor));
432         }
433       else
434         {
435           inner = MIN (inner, BITS_PER_UNIT);
436           break;
437         }
438       offset = next_offset;
439     }
440   /* Alignment is innermost object alignment adjusted by the constant
441      and non-constant offset parts.  */
442   align = MIN (align, inner);
443
444   *alignp = align;
445   *bitposp = bitpos & (*alignp - 1);
446   return known_alignment;
447 }
448
449 /* For a memory reference expression EXP compute values M and N such that M
450    divides (&EXP - N) and such that N < M.  If these numbers can be determined,
451    store M in alignp and N in *BITPOSP and return true.  Otherwise return false
452    and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp.  */
453
454 bool
455 get_object_alignment_1 (tree exp, unsigned int *alignp,
456                         unsigned HOST_WIDE_INT *bitposp)
457 {
458   return get_object_alignment_2 (exp, alignp, bitposp, false);
459 }
460
461 /* Return the alignment in bits of EXP, an object.  */
462
463 unsigned int
464 get_object_alignment (tree exp)
465 {
466   unsigned HOST_WIDE_INT bitpos = 0;
467   unsigned int align;
468
469   get_object_alignment_1 (exp, &align, &bitpos);
470
471   /* align and bitpos now specify known low bits of the pointer.
472      ptr & (align - 1) == bitpos.  */
473
474   if (bitpos != 0)
475     align = (bitpos & -bitpos);
476   return align;
477 }
478
479 /* For a pointer valued expression EXP compute values M and N such that M
480    divides (EXP - N) and such that N < M.  If these numbers can be determined,
481    store M in alignp and N in *BITPOSP and return true.  Return false if
482    the results are just a conservative approximation.
483
484    If EXP is not a pointer, false is returned too.  */
485
486 bool
487 get_pointer_alignment_1 (tree exp, unsigned int *alignp,
488                          unsigned HOST_WIDE_INT *bitposp)
489 {
490   STRIP_NOPS (exp);
491
492   if (TREE_CODE (exp) == ADDR_EXPR)
493     return get_object_alignment_2 (TREE_OPERAND (exp, 0),
494                                    alignp, bitposp, true);
495   else if (TREE_CODE (exp) == SSA_NAME
496            && POINTER_TYPE_P (TREE_TYPE (exp)))
497     {
498       unsigned int ptr_align, ptr_misalign;
499       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
500
501       if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
502         {
503           *bitposp = ptr_misalign * BITS_PER_UNIT;
504           *alignp = ptr_align * BITS_PER_UNIT;
505           /* We cannot really tell whether this result is an approximation.  */
506           return true;
507         }
508       else
509         {
510           *bitposp = 0;
511           *alignp = BITS_PER_UNIT;
512           return false;
513         }
514     }
515   else if (TREE_CODE (exp) == INTEGER_CST)
516     {
517       *alignp = BIGGEST_ALIGNMENT;
518       *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
519                   & (BIGGEST_ALIGNMENT - 1));
520       return true;
521     }
522
523   *bitposp = 0;
524   *alignp = BITS_PER_UNIT;
525   return false;
526 }
527
528 /* Return the alignment in bits of EXP, a pointer valued expression.
529    The alignment returned is, by default, the alignment of the thing that
530    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
531
532    Otherwise, look at the expression to see if we can do better, i.e., if the
533    expression is actually pointing at an object whose alignment is tighter.  */
534
535 unsigned int
536 get_pointer_alignment (tree exp)
537 {
538   unsigned HOST_WIDE_INT bitpos = 0;
539   unsigned int align;
540
541   get_pointer_alignment_1 (exp, &align, &bitpos);
542
543   /* align and bitpos now specify known low bits of the pointer.
544      ptr & (align - 1) == bitpos.  */
545
546   if (bitpos != 0)
547     align = (bitpos & -bitpos);
548
549   return align;
550 }
551
552 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
553    way, because it could contain a zero byte in the middle.
554    TREE_STRING_LENGTH is the size of the character array, not the string.
555
556    ONLY_VALUE should be nonzero if the result is not going to be emitted
557    into the instruction stream and zero if it is going to be expanded.
558    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
559    is returned, otherwise NULL, since
560    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
561    evaluate the side-effects.
562
563    The value returned is of type `ssizetype'.
564
565    Unfortunately, string_constant can't access the values of const char
566    arrays with initializers, so neither can we do so here.  */
567
568 tree
569 c_strlen (tree src, int only_value)
570 {
571   tree offset_node;
572   HOST_WIDE_INT offset;
573   int max;
574   const char *ptr;
575   location_t loc;
576
577   STRIP_NOPS (src);
578   if (TREE_CODE (src) == COND_EXPR
579       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
580     {
581       tree len1, len2;
582
583       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
584       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
585       if (tree_int_cst_equal (len1, len2))
586         return len1;
587     }
588
589   if (TREE_CODE (src) == COMPOUND_EXPR
590       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
591     return c_strlen (TREE_OPERAND (src, 1), only_value);
592
593   loc = EXPR_LOC_OR_HERE (src);
594
595   src = string_constant (src, &offset_node);
596   if (src == 0)
597     return NULL_TREE;
598
599   max = TREE_STRING_LENGTH (src) - 1;
600   ptr = TREE_STRING_POINTER (src);
601
602   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
603     {
604       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
605          compute the offset to the following null if we don't know where to
606          start searching for it.  */
607       int i;
608
609       for (i = 0; i < max; i++)
610         if (ptr[i] == 0)
611           return NULL_TREE;
612
613       /* We don't know the starting offset, but we do know that the string
614          has no internal zero bytes.  We can assume that the offset falls
615          within the bounds of the string; otherwise, the programmer deserves
616          what he gets.  Subtract the offset from the length of the string,
617          and return that.  This would perhaps not be valid if we were dealing
618          with named arrays in addition to literal string constants.  */
619
620       return size_diffop_loc (loc, size_int (max), offset_node);
621     }
622
623   /* We have a known offset into the string.  Start searching there for
624      a null character if we can represent it as a single HOST_WIDE_INT.  */
625   if (offset_node == 0)
626     offset = 0;
627   else if (! host_integerp (offset_node, 0))
628     offset = -1;
629   else
630     offset = tree_low_cst (offset_node, 0);
631
632   /* If the offset is known to be out of bounds, warn, and call strlen at
633      runtime.  */
634   if (offset < 0 || offset > max)
635     {
636      /* Suppress multiple warnings for propagated constant strings.  */
637       if (! TREE_NO_WARNING (src))
638         {
639           warning_at (loc, 0, "offset outside bounds of constant string");
640           TREE_NO_WARNING (src) = 1;
641         }
642       return NULL_TREE;
643     }
644
645   /* Use strlen to search for the first zero byte.  Since any strings
646      constructed with build_string will have nulls appended, we win even
647      if we get handed something like (char[4])"abcd".
648
649      Since OFFSET is our starting index into the string, no further
650      calculation is needed.  */
651   return ssize_int (strlen (ptr + offset));
652 }
653
654 /* Return a char pointer for a C string if it is a string constant
655    or sum of string constant and integer constant.  */
656
657 static const char *
658 c_getstr (tree src)
659 {
660   tree offset_node;
661
662   src = string_constant (src, &offset_node);
663   if (src == 0)
664     return 0;
665
666   if (offset_node == 0)
667     return TREE_STRING_POINTER (src);
668   else if (!host_integerp (offset_node, 1)
669            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
670     return 0;
671
672   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
673 }
674
675 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
676    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
677
678 static rtx
679 c_readstr (const char *str, enum machine_mode mode)
680 {
681   HOST_WIDE_INT c[2];
682   HOST_WIDE_INT ch;
683   unsigned int i, j;
684
685   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
686
687   c[0] = 0;
688   c[1] = 0;
689   ch = 1;
690   for (i = 0; i < GET_MODE_SIZE (mode); i++)
691     {
692       j = i;
693       if (WORDS_BIG_ENDIAN)
694         j = GET_MODE_SIZE (mode) - i - 1;
695       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
696           && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
697         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
698       j *= BITS_PER_UNIT;
699       gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
700
701       if (ch)
702         ch = (unsigned char) str[i];
703       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
704     }
705   return immed_double_const (c[0], c[1], mode);
706 }
707
708 /* Cast a target constant CST to target CHAR and if that value fits into
709    host char type, return zero and put that value into variable pointed to by
710    P.  */
711
712 static int
713 target_char_cast (tree cst, char *p)
714 {
715   unsigned HOST_WIDE_INT val, hostval;
716
717   if (TREE_CODE (cst) != INTEGER_CST
718       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
719     return 1;
720
721   val = TREE_INT_CST_LOW (cst);
722   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
723     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
724
725   hostval = val;
726   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
727     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
728
729   if (val != hostval)
730     return 1;
731
732   *p = hostval;
733   return 0;
734 }
735
736 /* Similar to save_expr, but assumes that arbitrary code is not executed
737    in between the multiple evaluations.  In particular, we assume that a
738    non-addressable local variable will not be modified.  */
739
740 static tree
741 builtin_save_expr (tree exp)
742 {
743   if (TREE_CODE (exp) == SSA_NAME
744       || (TREE_ADDRESSABLE (exp) == 0
745           && (TREE_CODE (exp) == PARM_DECL
746               || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))))
747     return exp;
748
749   return save_expr (exp);
750 }
751
752 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
753    times to get the address of either a higher stack frame, or a return
754    address located within it (depending on FNDECL_CODE).  */
755
756 static rtx
757 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
758 {
759   int i;
760
761 #ifdef INITIAL_FRAME_ADDRESS_RTX
762   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
763 #else
764   rtx tem;
765
766   /* For a zero count with __builtin_return_address, we don't care what
767      frame address we return, because target-specific definitions will
768      override us.  Therefore frame pointer elimination is OK, and using
769      the soft frame pointer is OK.
770
771      For a nonzero count, or a zero count with __builtin_frame_address,
772      we require a stable offset from the current frame pointer to the
773      previous one, so we must use the hard frame pointer, and
774      we must disable frame pointer elimination.  */
775   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
776     tem = frame_pointer_rtx;
777   else
778     {
779       tem = hard_frame_pointer_rtx;
780
781       /* Tell reload not to eliminate the frame pointer.  */
782       crtl->accesses_prior_frames = 1;
783     }
784 #endif
785
786   /* Some machines need special handling before we can access
787      arbitrary frames.  For example, on the SPARC, we must first flush
788      all register windows to the stack.  */
789 #ifdef SETUP_FRAME_ADDRESSES
790   if (count > 0)
791     SETUP_FRAME_ADDRESSES ();
792 #endif
793
794   /* On the SPARC, the return address is not in the frame, it is in a
795      register.  There is no way to access it off of the current frame
796      pointer, but it can be accessed off the previous frame pointer by
797      reading the value from the register window save area.  */
798 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
799   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
800     count--;
801 #endif
802
803   /* Scan back COUNT frames to the specified frame.  */
804   for (i = 0; i < count; i++)
805     {
806       /* Assume the dynamic chain pointer is in the word that the
807          frame address points to, unless otherwise specified.  */
808 #ifdef DYNAMIC_CHAIN_ADDRESS
809       tem = DYNAMIC_CHAIN_ADDRESS (tem);
810 #endif
811       tem = memory_address (Pmode, tem);
812       tem = gen_frame_mem (Pmode, tem);
813       tem = copy_to_reg (tem);
814     }
815
816   /* For __builtin_frame_address, return what we've got.  But, on
817      the SPARC for example, we may have to add a bias.  */
818   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
819 #ifdef FRAME_ADDR_RTX
820     return FRAME_ADDR_RTX (tem);
821 #else
822     return tem;
823 #endif
824
825   /* For __builtin_return_address, get the return address from that frame.  */
826 #ifdef RETURN_ADDR_RTX
827   tem = RETURN_ADDR_RTX (count, tem);
828 #else
829   tem = memory_address (Pmode,
830                         plus_constant (Pmode, tem, GET_MODE_SIZE (Pmode)));
831   tem = gen_frame_mem (Pmode, tem);
832 #endif
833   return tem;
834 }
835
836 /* Alias set used for setjmp buffer.  */
837 static alias_set_type setjmp_alias_set = -1;
838
839 /* Construct the leading half of a __builtin_setjmp call.  Control will
840    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
841    exception handling code.  */
842
843 void
844 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
845 {
846   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
847   rtx stack_save;
848   rtx mem;
849
850   if (setjmp_alias_set == -1)
851     setjmp_alias_set = new_alias_set ();
852
853   buf_addr = convert_memory_address (Pmode, buf_addr);
854
855   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
856
857   /* We store the frame pointer and the address of receiver_label in
858      the buffer and use the rest of it for the stack save area, which
859      is machine-dependent.  */
860
861   mem = gen_rtx_MEM (Pmode, buf_addr);
862   set_mem_alias_set (mem, setjmp_alias_set);
863   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
864
865   mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
866                                            GET_MODE_SIZE (Pmode))),
867   set_mem_alias_set (mem, setjmp_alias_set);
868
869   emit_move_insn (validize_mem (mem),
870                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
871
872   stack_save = gen_rtx_MEM (sa_mode,
873                             plus_constant (Pmode, buf_addr,
874                                            2 * GET_MODE_SIZE (Pmode)));
875   set_mem_alias_set (stack_save, setjmp_alias_set);
876   emit_stack_save (SAVE_NONLOCAL, &stack_save);
877
878   /* If there is further processing to do, do it.  */
879 #ifdef HAVE_builtin_setjmp_setup
880   if (HAVE_builtin_setjmp_setup)
881     emit_insn (gen_builtin_setjmp_setup (buf_addr));
882 #endif
883
884   /* We have a nonlocal label.   */
885   cfun->has_nonlocal_label = 1;
886 }
887
888 /* Construct the trailing part of a __builtin_setjmp call.  This is
889    also called directly by the SJLJ exception handling code.
890    If RECEIVER_LABEL is NULL, instead contruct a nonlocal goto handler.  */
891
892 void
893 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
894 {
895   rtx chain;
896
897   /* Mark the FP as used when we get here, so we have to make sure it's
898      marked as used by this function.  */
899   emit_use (hard_frame_pointer_rtx);
900
901   /* Mark the static chain as clobbered here so life information
902      doesn't get messed up for it.  */
903   chain = targetm.calls.static_chain (current_function_decl, true);
904   if (chain && REG_P (chain))
905     emit_clobber (chain);
906
907   /* Now put in the code to restore the frame pointer, and argument
908      pointer, if needed.  */
909 #ifdef HAVE_nonlocal_goto
910   if (! HAVE_nonlocal_goto)
911 #endif
912     /* First adjust our frame pointer to its actual value.  It was
913        previously set to the start of the virtual area corresponding to
914        the stacked variables when we branched here and now needs to be
915        adjusted to the actual hardware fp value.
916
917        Assignments to virtual registers are converted by
918        instantiate_virtual_regs into the corresponding assignment
919        to the underlying register (fp in this case) that makes
920        the original assignment true.
921        So the following insn will actually be decrementing fp by
922        STARTING_FRAME_OFFSET.  */
923     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
924
925 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
926   if (fixed_regs[ARG_POINTER_REGNUM])
927     {
928 #ifdef ELIMINABLE_REGS
929       /* If the argument pointer can be eliminated in favor of the
930          frame pointer, we don't need to restore it.  We assume here
931          that if such an elimination is present, it can always be used.
932          This is the case on all known machines; if we don't make this
933          assumption, we do unnecessary saving on many machines.  */
934       size_t i;
935       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
936
937       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
938         if (elim_regs[i].from == ARG_POINTER_REGNUM
939             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
940           break;
941
942       if (i == ARRAY_SIZE (elim_regs))
943 #endif
944         {
945           /* Now restore our arg pointer from the address at which it
946              was saved in our stack frame.  */
947           emit_move_insn (crtl->args.internal_arg_pointer,
948                           copy_to_reg (get_arg_pointer_save_area ()));
949         }
950     }
951 #endif
952
953 #ifdef HAVE_builtin_setjmp_receiver
954   if (receiver_label != NULL && HAVE_builtin_setjmp_receiver)
955     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
956   else
957 #endif
958 #ifdef HAVE_nonlocal_goto_receiver
959     if (HAVE_nonlocal_goto_receiver)
960       emit_insn (gen_nonlocal_goto_receiver ());
961     else
962 #endif
963       { /* Nothing */ }
964
965   /* We must not allow the code we just generated to be reordered by
966      scheduling.  Specifically, the update of the frame pointer must
967      happen immediately, not later.  Similarly, we must block
968      (frame-related) register values to be used across this code.  */
969   emit_insn (gen_blockage ());
970 }
971
972 /* __builtin_longjmp is passed a pointer to an array of five words (not
973    all will be used on all machines).  It operates similarly to the C
974    library function of the same name, but is more efficient.  Much of
975    the code below is copied from the handling of non-local gotos.  */
976
977 static void
978 expand_builtin_longjmp (rtx buf_addr, rtx value)
979 {
980   rtx fp, lab, stack, insn, last;
981   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
982
983   /* DRAP is needed for stack realign if longjmp is expanded to current
984      function  */
985   if (SUPPORTS_STACK_ALIGNMENT)
986     crtl->need_drap = true;
987
988   if (setjmp_alias_set == -1)
989     setjmp_alias_set = new_alias_set ();
990
991   buf_addr = convert_memory_address (Pmode, buf_addr);
992
993   buf_addr = force_reg (Pmode, buf_addr);
994
995   /* We require that the user must pass a second argument of 1, because
996      that is what builtin_setjmp will return.  */
997   gcc_assert (value == const1_rtx);
998
999   last = get_last_insn ();
1000 #ifdef HAVE_builtin_longjmp
1001   if (HAVE_builtin_longjmp)
1002     emit_insn (gen_builtin_longjmp (buf_addr));
1003   else
1004 #endif
1005     {
1006       fp = gen_rtx_MEM (Pmode, buf_addr);
1007       lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
1008                                                GET_MODE_SIZE (Pmode)));
1009
1010       stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, buf_addr,
1011                                                    2 * GET_MODE_SIZE (Pmode)));
1012       set_mem_alias_set (fp, setjmp_alias_set);
1013       set_mem_alias_set (lab, setjmp_alias_set);
1014       set_mem_alias_set (stack, setjmp_alias_set);
1015
1016       /* Pick up FP, label, and SP from the block and jump.  This code is
1017          from expand_goto in stmt.c; see there for detailed comments.  */
1018 #ifdef HAVE_nonlocal_goto
1019       if (HAVE_nonlocal_goto)
1020         /* We have to pass a value to the nonlocal_goto pattern that will
1021            get copied into the static_chain pointer, but it does not matter
1022            what that value is, because builtin_setjmp does not use it.  */
1023         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
1024       else
1025 #endif
1026         {
1027           lab = copy_to_reg (lab);
1028
1029           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1030           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1031
1032           emit_move_insn (hard_frame_pointer_rtx, fp);
1033           emit_stack_restore (SAVE_NONLOCAL, stack);
1034
1035           emit_use (hard_frame_pointer_rtx);
1036           emit_use (stack_pointer_rtx);
1037           emit_indirect_jump (lab);
1038         }
1039     }
1040
1041   /* Search backwards and mark the jump insn as a non-local goto.
1042      Note that this precludes the use of __builtin_longjmp to a
1043      __builtin_setjmp target in the same function.  However, we've
1044      already cautioned the user that these functions are for
1045      internal exception handling use only.  */
1046   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1047     {
1048       gcc_assert (insn != last);
1049
1050       if (JUMP_P (insn))
1051         {
1052           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1053           break;
1054         }
1055       else if (CALL_P (insn))
1056         break;
1057     }
1058 }
1059
1060 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
1061    and the address of the save area.  */
1062
1063 static rtx
1064 expand_builtin_nonlocal_goto (tree exp)
1065 {
1066   tree t_label, t_save_area;
1067   rtx r_label, r_save_area, r_fp, r_sp, insn;
1068
1069   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1070     return NULL_RTX;
1071
1072   t_label = CALL_EXPR_ARG (exp, 0);
1073   t_save_area = CALL_EXPR_ARG (exp, 1);
1074
1075   r_label = expand_normal (t_label);
1076   r_label = convert_memory_address (Pmode, r_label);
1077   r_save_area = expand_normal (t_save_area);
1078   r_save_area = convert_memory_address (Pmode, r_save_area);
1079   /* Copy the address of the save location to a register just in case it was
1080      based on the frame pointer.   */
1081   r_save_area = copy_to_reg (r_save_area);
1082   r_fp = gen_rtx_MEM (Pmode, r_save_area);
1083   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
1084                       plus_constant (Pmode, r_save_area,
1085                                      GET_MODE_SIZE (Pmode)));
1086
1087   crtl->has_nonlocal_goto = 1;
1088
1089 #ifdef HAVE_nonlocal_goto
1090   /* ??? We no longer need to pass the static chain value, afaik.  */
1091   if (HAVE_nonlocal_goto)
1092     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
1093   else
1094 #endif
1095     {
1096       r_label = copy_to_reg (r_label);
1097
1098       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1099       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1100
1101       /* Restore frame pointer for containing function.  */
1102       emit_move_insn (hard_frame_pointer_rtx, r_fp);
1103       emit_stack_restore (SAVE_NONLOCAL, r_sp);
1104
1105       /* USE of hard_frame_pointer_rtx added for consistency;
1106          not clear if really needed.  */
1107       emit_use (hard_frame_pointer_rtx);
1108       emit_use (stack_pointer_rtx);
1109
1110       /* If the architecture is using a GP register, we must
1111          conservatively assume that the target function makes use of it.
1112          The prologue of functions with nonlocal gotos must therefore
1113          initialize the GP register to the appropriate value, and we
1114          must then make sure that this value is live at the point
1115          of the jump.  (Note that this doesn't necessarily apply
1116          to targets with a nonlocal_goto pattern; they are free
1117          to implement it in their own way.  Note also that this is
1118          a no-op if the GP register is a global invariant.)  */
1119       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
1120           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
1121         emit_use (pic_offset_table_rtx);
1122
1123       emit_indirect_jump (r_label);
1124     }
1125
1126   /* Search backwards to the jump insn and mark it as a
1127      non-local goto.  */
1128   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1129     {
1130       if (JUMP_P (insn))
1131         {
1132           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1133           break;
1134         }
1135       else if (CALL_P (insn))
1136         break;
1137     }
1138
1139   return const0_rtx;
1140 }
1141
1142 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
1143    (not all will be used on all machines) that was passed to __builtin_setjmp.
1144    It updates the stack pointer in that block to correspond to the current
1145    stack pointer.  */
1146
1147 static void
1148 expand_builtin_update_setjmp_buf (rtx buf_addr)
1149 {
1150   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1151   rtx stack_save
1152     = gen_rtx_MEM (sa_mode,
1153                    memory_address
1154                    (sa_mode,
1155                     plus_constant (Pmode, buf_addr,
1156                                    2 * GET_MODE_SIZE (Pmode))));
1157
1158   emit_stack_save (SAVE_NONLOCAL, &stack_save);
1159 }
1160
1161 /* Expand a call to __builtin_prefetch.  For a target that does not support
1162    data prefetch, evaluate the memory address argument in case it has side
1163    effects.  */
1164
1165 static void
1166 expand_builtin_prefetch (tree exp)
1167 {
1168   tree arg0, arg1, arg2;
1169   int nargs;
1170   rtx op0, op1, op2;
1171
1172   if (!validate_arglist (exp, POINTER_TYPE, 0))
1173     return;
1174
1175   arg0 = CALL_EXPR_ARG (exp, 0);
1176
1177   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1178      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1179      locality).  */
1180   nargs = call_expr_nargs (exp);
1181   if (nargs > 1)
1182     arg1 = CALL_EXPR_ARG (exp, 1);
1183   else
1184     arg1 = integer_zero_node;
1185   if (nargs > 2)
1186     arg2 = CALL_EXPR_ARG (exp, 2);
1187   else
1188     arg2 = integer_three_node;
1189
1190   /* Argument 0 is an address.  */
1191   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1192
1193   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1194   if (TREE_CODE (arg1) != INTEGER_CST)
1195     {
1196       error ("second argument to %<__builtin_prefetch%> must be a constant");
1197       arg1 = integer_zero_node;
1198     }
1199   op1 = expand_normal (arg1);
1200   /* Argument 1 must be either zero or one.  */
1201   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1202     {
1203       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1204                " using zero");
1205       op1 = const0_rtx;
1206     }
1207
1208   /* Argument 2 (locality) must be a compile-time constant int.  */
1209   if (TREE_CODE (arg2) != INTEGER_CST)
1210     {
1211       error ("third argument to %<__builtin_prefetch%> must be a constant");
1212       arg2 = integer_zero_node;
1213     }
1214   op2 = expand_normal (arg2);
1215   /* Argument 2 must be 0, 1, 2, or 3.  */
1216   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1217     {
1218       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1219       op2 = const0_rtx;
1220     }
1221
1222 #ifdef HAVE_prefetch
1223   if (HAVE_prefetch)
1224     {
1225       struct expand_operand ops[3];
1226
1227       create_address_operand (&ops[0], op0);
1228       create_integer_operand (&ops[1], INTVAL (op1));
1229       create_integer_operand (&ops[2], INTVAL (op2));
1230       if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops))
1231         return;
1232     }
1233 #endif
1234
1235   /* Don't do anything with direct references to volatile memory, but
1236      generate code to handle other side effects.  */
1237   if (!MEM_P (op0) && side_effects_p (op0))
1238     emit_insn (op0);
1239 }
1240
1241 /* Get a MEM rtx for expression EXP which is the address of an operand
1242    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1243    the maximum length of the block of memory that might be accessed or
1244    NULL if unknown.  */
1245
1246 static rtx
1247 get_memory_rtx (tree exp, tree len)
1248 {
1249   tree orig_exp = exp;
1250   rtx addr, mem;
1251
1252   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1253      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1254   if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1255     exp = TREE_OPERAND (exp, 0);
1256
1257   addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1258   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1259
1260   /* Get an expression we can use to find the attributes to assign to MEM.
1261      First remove any nops.  */
1262   while (CONVERT_EXPR_P (exp)
1263          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1264     exp = TREE_OPERAND (exp, 0);
1265
1266   /* Build a MEM_REF representing the whole accessed area as a byte blob,
1267      (as builtin stringops may alias with anything).  */
1268   exp = fold_build2 (MEM_REF,
1269                      build_array_type (char_type_node,
1270                                        build_range_type (sizetype,
1271                                                          size_one_node, len)),
1272                      exp, build_int_cst (ptr_type_node, 0));
1273
1274   /* If the MEM_REF has no acceptable address, try to get the base object
1275      from the original address we got, and build an all-aliasing
1276      unknown-sized access to that one.  */
1277   if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0)))
1278     set_mem_attributes (mem, exp, 0);
1279   else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1280            && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0),
1281                                                      0))))
1282     {
1283       exp = build_fold_addr_expr (exp);
1284       exp = fold_build2 (MEM_REF,
1285                          build_array_type (char_type_node,
1286                                            build_range_type (sizetype,
1287                                                              size_zero_node,
1288                                                              NULL)),
1289                          exp, build_int_cst (ptr_type_node, 0));
1290       set_mem_attributes (mem, exp, 0);
1291     }
1292   set_mem_alias_set (mem, 0);
1293   return mem;
1294 }
1295 \f
1296 /* Built-in functions to perform an untyped call and return.  */
1297
1298 #define apply_args_mode \
1299   (this_target_builtins->x_apply_args_mode)
1300 #define apply_result_mode \
1301   (this_target_builtins->x_apply_result_mode)
1302
1303 /* Return the size required for the block returned by __builtin_apply_args,
1304    and initialize apply_args_mode.  */
1305
1306 static int
1307 apply_args_size (void)
1308 {
1309   static int size = -1;
1310   int align;
1311   unsigned int regno;
1312   enum machine_mode mode;
1313
1314   /* The values computed by this function never change.  */
1315   if (size < 0)
1316     {
1317       /* The first value is the incoming arg-pointer.  */
1318       size = GET_MODE_SIZE (Pmode);
1319
1320       /* The second value is the structure value address unless this is
1321          passed as an "invisible" first argument.  */
1322       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1323         size += GET_MODE_SIZE (Pmode);
1324
1325       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1326         if (FUNCTION_ARG_REGNO_P (regno))
1327           {
1328             mode = targetm.calls.get_raw_arg_mode (regno);
1329
1330             gcc_assert (mode != VOIDmode);
1331
1332             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1333             if (size % align != 0)
1334               size = CEIL (size, align) * align;
1335             size += GET_MODE_SIZE (mode);
1336             apply_args_mode[regno] = mode;
1337           }
1338         else
1339           {
1340             apply_args_mode[regno] = VOIDmode;
1341           }
1342     }
1343   return size;
1344 }
1345
1346 /* Return the size required for the block returned by __builtin_apply,
1347    and initialize apply_result_mode.  */
1348
1349 static int
1350 apply_result_size (void)
1351 {
1352   static int size = -1;
1353   int align, regno;
1354   enum machine_mode mode;
1355
1356   /* The values computed by this function never change.  */
1357   if (size < 0)
1358     {
1359       size = 0;
1360
1361       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1362         if (targetm.calls.function_value_regno_p (regno))
1363           {
1364             mode = targetm.calls.get_raw_result_mode (regno);
1365
1366             gcc_assert (mode != VOIDmode);
1367
1368             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1369             if (size % align != 0)
1370               size = CEIL (size, align) * align;
1371             size += GET_MODE_SIZE (mode);
1372             apply_result_mode[regno] = mode;
1373           }
1374         else
1375           apply_result_mode[regno] = VOIDmode;
1376
1377       /* Allow targets that use untyped_call and untyped_return to override
1378          the size so that machine-specific information can be stored here.  */
1379 #ifdef APPLY_RESULT_SIZE
1380       size = APPLY_RESULT_SIZE;
1381 #endif
1382     }
1383   return size;
1384 }
1385
1386 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1387 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1388    the result block is used to save the values; otherwise it is used to
1389    restore the values.  */
1390
1391 static rtx
1392 result_vector (int savep, rtx result)
1393 {
1394   int regno, size, align, nelts;
1395   enum machine_mode mode;
1396   rtx reg, mem;
1397   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1398
1399   size = nelts = 0;
1400   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1401     if ((mode = apply_result_mode[regno]) != VOIDmode)
1402       {
1403         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1404         if (size % align != 0)
1405           size = CEIL (size, align) * align;
1406         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1407         mem = adjust_address (result, mode, size);
1408         savevec[nelts++] = (savep
1409                             ? gen_rtx_SET (VOIDmode, mem, reg)
1410                             : gen_rtx_SET (VOIDmode, reg, mem));
1411         size += GET_MODE_SIZE (mode);
1412       }
1413   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1414 }
1415 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1416
1417 /* Save the state required to perform an untyped call with the same
1418    arguments as were passed to the current function.  */
1419
1420 static rtx
1421 expand_builtin_apply_args_1 (void)
1422 {
1423   rtx registers, tem;
1424   int size, align, regno;
1425   enum machine_mode mode;
1426   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1427
1428   /* Create a block where the arg-pointer, structure value address,
1429      and argument registers can be saved.  */
1430   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1431
1432   /* Walk past the arg-pointer and structure value address.  */
1433   size = GET_MODE_SIZE (Pmode);
1434   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1435     size += GET_MODE_SIZE (Pmode);
1436
1437   /* Save each register used in calling a function to the block.  */
1438   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1439     if ((mode = apply_args_mode[regno]) != VOIDmode)
1440       {
1441         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1442         if (size % align != 0)
1443           size = CEIL (size, align) * align;
1444
1445         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1446
1447         emit_move_insn (adjust_address (registers, mode, size), tem);
1448         size += GET_MODE_SIZE (mode);
1449       }
1450
1451   /* Save the arg pointer to the block.  */
1452   tem = copy_to_reg (crtl->args.internal_arg_pointer);
1453 #ifdef STACK_GROWS_DOWNWARD
1454   /* We need the pointer as the caller actually passed them to us, not
1455      as we might have pretended they were passed.  Make sure it's a valid
1456      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1457   tem
1458     = force_operand (plus_constant (Pmode, tem, crtl->args.pretend_args_size),
1459                      NULL_RTX);
1460 #endif
1461   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1462
1463   size = GET_MODE_SIZE (Pmode);
1464
1465   /* Save the structure value address unless this is passed as an
1466      "invisible" first argument.  */
1467   if (struct_incoming_value)
1468     {
1469       emit_move_insn (adjust_address (registers, Pmode, size),
1470                       copy_to_reg (struct_incoming_value));
1471       size += GET_MODE_SIZE (Pmode);
1472     }
1473
1474   /* Return the address of the block.  */
1475   return copy_addr_to_reg (XEXP (registers, 0));
1476 }
1477
1478 /* __builtin_apply_args returns block of memory allocated on
1479    the stack into which is stored the arg pointer, structure
1480    value address, static chain, and all the registers that might
1481    possibly be used in performing a function call.  The code is
1482    moved to the start of the function so the incoming values are
1483    saved.  */
1484
1485 static rtx
1486 expand_builtin_apply_args (void)
1487 {
1488   /* Don't do __builtin_apply_args more than once in a function.
1489      Save the result of the first call and reuse it.  */
1490   if (apply_args_value != 0)
1491     return apply_args_value;
1492   {
1493     /* When this function is called, it means that registers must be
1494        saved on entry to this function.  So we migrate the
1495        call to the first insn of this function.  */
1496     rtx temp;
1497     rtx seq;
1498
1499     start_sequence ();
1500     temp = expand_builtin_apply_args_1 ();
1501     seq = get_insns ();
1502     end_sequence ();
1503
1504     apply_args_value = temp;
1505
1506     /* Put the insns after the NOTE that starts the function.
1507        If this is inside a start_sequence, make the outer-level insn
1508        chain current, so the code is placed at the start of the
1509        function.  If internal_arg_pointer is a non-virtual pseudo,
1510        it needs to be placed after the function that initializes
1511        that pseudo.  */
1512     push_topmost_sequence ();
1513     if (REG_P (crtl->args.internal_arg_pointer)
1514         && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1515       emit_insn_before (seq, parm_birth_insn);
1516     else
1517       emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1518     pop_topmost_sequence ();
1519     return temp;
1520   }
1521 }
1522
1523 /* Perform an untyped call and save the state required to perform an
1524    untyped return of whatever value was returned by the given function.  */
1525
1526 static rtx
1527 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1528 {
1529   int size, align, regno;
1530   enum machine_mode mode;
1531   rtx incoming_args, result, reg, dest, src, call_insn;
1532   rtx old_stack_level = 0;
1533   rtx call_fusage = 0;
1534   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1535
1536   arguments = convert_memory_address (Pmode, arguments);
1537
1538   /* Create a block where the return registers can be saved.  */
1539   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1540
1541   /* Fetch the arg pointer from the ARGUMENTS block.  */
1542   incoming_args = gen_reg_rtx (Pmode);
1543   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1544 #ifndef STACK_GROWS_DOWNWARD
1545   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1546                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1547 #endif
1548
1549   /* Push a new argument block and copy the arguments.  Do not allow
1550      the (potential) memcpy call below to interfere with our stack
1551      manipulations.  */
1552   do_pending_stack_adjust ();
1553   NO_DEFER_POP;
1554
1555   /* Save the stack with nonlocal if available.  */
1556 #ifdef HAVE_save_stack_nonlocal
1557   if (HAVE_save_stack_nonlocal)
1558     emit_stack_save (SAVE_NONLOCAL, &old_stack_level);
1559   else
1560 #endif
1561     emit_stack_save (SAVE_BLOCK, &old_stack_level);
1562
1563   /* Allocate a block of memory onto the stack and copy the memory
1564      arguments to the outgoing arguments address.  We can pass TRUE
1565      as the 4th argument because we just saved the stack pointer
1566      and will restore it right after the call.  */
1567   allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true);
1568
1569   /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1570      may have already set current_function_calls_alloca to true.
1571      current_function_calls_alloca won't be set if argsize is zero,
1572      so we have to guarantee need_drap is true here.  */
1573   if (SUPPORTS_STACK_ALIGNMENT)
1574     crtl->need_drap = true;
1575
1576   dest = virtual_outgoing_args_rtx;
1577 #ifndef STACK_GROWS_DOWNWARD
1578   if (CONST_INT_P (argsize))
1579     dest = plus_constant (Pmode, dest, -INTVAL (argsize));
1580   else
1581     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1582 #endif
1583   dest = gen_rtx_MEM (BLKmode, dest);
1584   set_mem_align (dest, PARM_BOUNDARY);
1585   src = gen_rtx_MEM (BLKmode, incoming_args);
1586   set_mem_align (src, PARM_BOUNDARY);
1587   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1588
1589   /* Refer to the argument block.  */
1590   apply_args_size ();
1591   arguments = gen_rtx_MEM (BLKmode, arguments);
1592   set_mem_align (arguments, PARM_BOUNDARY);
1593
1594   /* Walk past the arg-pointer and structure value address.  */
1595   size = GET_MODE_SIZE (Pmode);
1596   if (struct_value)
1597     size += GET_MODE_SIZE (Pmode);
1598
1599   /* Restore each of the registers previously saved.  Make USE insns
1600      for each of these registers for use in making the call.  */
1601   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1602     if ((mode = apply_args_mode[regno]) != VOIDmode)
1603       {
1604         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1605         if (size % align != 0)
1606           size = CEIL (size, align) * align;
1607         reg = gen_rtx_REG (mode, regno);
1608         emit_move_insn (reg, adjust_address (arguments, mode, size));
1609         use_reg (&call_fusage, reg);
1610         size += GET_MODE_SIZE (mode);
1611       }
1612
1613   /* Restore the structure value address unless this is passed as an
1614      "invisible" first argument.  */
1615   size = GET_MODE_SIZE (Pmode);
1616   if (struct_value)
1617     {
1618       rtx value = gen_reg_rtx (Pmode);
1619       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1620       emit_move_insn (struct_value, value);
1621       if (REG_P (struct_value))
1622         use_reg (&call_fusage, struct_value);
1623       size += GET_MODE_SIZE (Pmode);
1624     }
1625
1626   /* All arguments and registers used for the call are set up by now!  */
1627   function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1628
1629   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1630      and we don't want to load it into a register as an optimization,
1631      because prepare_call_address already did it if it should be done.  */
1632   if (GET_CODE (function) != SYMBOL_REF)
1633     function = memory_address (FUNCTION_MODE, function);
1634
1635   /* Generate the actual call instruction and save the return value.  */
1636 #ifdef HAVE_untyped_call
1637   if (HAVE_untyped_call)
1638     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1639                                       result, result_vector (1, result)));
1640   else
1641 #endif
1642 #ifdef HAVE_call_value
1643   if (HAVE_call_value)
1644     {
1645       rtx valreg = 0;
1646
1647       /* Locate the unique return register.  It is not possible to
1648          express a call that sets more than one return register using
1649          call_value; use untyped_call for that.  In fact, untyped_call
1650          only needs to save the return registers in the given block.  */
1651       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1652         if ((mode = apply_result_mode[regno]) != VOIDmode)
1653           {
1654             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1655
1656             valreg = gen_rtx_REG (mode, regno);
1657           }
1658
1659       emit_call_insn (GEN_CALL_VALUE (valreg,
1660                                       gen_rtx_MEM (FUNCTION_MODE, function),
1661                                       const0_rtx, NULL_RTX, const0_rtx));
1662
1663       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1664     }
1665   else
1666 #endif
1667     gcc_unreachable ();
1668
1669   /* Find the CALL insn we just emitted, and attach the register usage
1670      information.  */
1671   call_insn = last_call_insn ();
1672   add_function_usage_to (call_insn, call_fusage);
1673
1674   /* Restore the stack.  */
1675 #ifdef HAVE_save_stack_nonlocal
1676   if (HAVE_save_stack_nonlocal)
1677     emit_stack_restore (SAVE_NONLOCAL, old_stack_level);
1678   else
1679 #endif
1680     emit_stack_restore (SAVE_BLOCK, old_stack_level);
1681   fixup_args_size_notes (call_insn, get_last_insn(), 0);
1682
1683   OK_DEFER_POP;
1684
1685   /* Return the address of the result block.  */
1686   result = copy_addr_to_reg (XEXP (result, 0));
1687   return convert_memory_address (ptr_mode, result);
1688 }
1689
1690 /* Perform an untyped return.  */
1691
1692 static void
1693 expand_builtin_return (rtx result)
1694 {
1695   int size, align, regno;
1696   enum machine_mode mode;
1697   rtx reg;
1698   rtx call_fusage = 0;
1699
1700   result = convert_memory_address (Pmode, result);
1701
1702   apply_result_size ();
1703   result = gen_rtx_MEM (BLKmode, result);
1704
1705 #ifdef HAVE_untyped_return
1706   if (HAVE_untyped_return)
1707     {
1708       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1709       emit_barrier ();
1710       return;
1711     }
1712 #endif
1713
1714   /* Restore the return value and note that each value is used.  */
1715   size = 0;
1716   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1717     if ((mode = apply_result_mode[regno]) != VOIDmode)
1718       {
1719         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1720         if (size % align != 0)
1721           size = CEIL (size, align) * align;
1722         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1723         emit_move_insn (reg, adjust_address (result, mode, size));
1724
1725         push_to_sequence (call_fusage);
1726         emit_use (reg);
1727         call_fusage = get_insns ();
1728         end_sequence ();
1729         size += GET_MODE_SIZE (mode);
1730       }
1731
1732   /* Put the USE insns before the return.  */
1733   emit_insn (call_fusage);
1734
1735   /* Return whatever values was restored by jumping directly to the end
1736      of the function.  */
1737   expand_naked_return ();
1738 }
1739
1740 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1741
1742 static enum type_class
1743 type_to_class (tree type)
1744 {
1745   switch (TREE_CODE (type))
1746     {
1747     case VOID_TYPE:        return void_type_class;
1748     case INTEGER_TYPE:     return integer_type_class;
1749     case ENUMERAL_TYPE:    return enumeral_type_class;
1750     case BOOLEAN_TYPE:     return boolean_type_class;
1751     case POINTER_TYPE:     return pointer_type_class;
1752     case REFERENCE_TYPE:   return reference_type_class;
1753     case OFFSET_TYPE:      return offset_type_class;
1754     case REAL_TYPE:        return real_type_class;
1755     case COMPLEX_TYPE:     return complex_type_class;
1756     case FUNCTION_TYPE:    return function_type_class;
1757     case METHOD_TYPE:      return method_type_class;
1758     case RECORD_TYPE:      return record_type_class;
1759     case UNION_TYPE:
1760     case QUAL_UNION_TYPE:  return union_type_class;
1761     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1762                                    ? string_type_class : array_type_class);
1763     case LANG_TYPE:        return lang_type_class;
1764     default:               return no_type_class;
1765     }
1766 }
1767
1768 /* Expand a call EXP to __builtin_classify_type.  */
1769
1770 static rtx
1771 expand_builtin_classify_type (tree exp)
1772 {
1773   if (call_expr_nargs (exp))
1774     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1775   return GEN_INT (no_type_class);
1776 }
1777
1778 /* This helper macro, meant to be used in mathfn_built_in below,
1779    determines which among a set of three builtin math functions is
1780    appropriate for a given type mode.  The `F' and `L' cases are
1781    automatically generated from the `double' case.  */
1782 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1783   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1784   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1785   fcodel = BUILT_IN_MATHFN##L ; break;
1786 /* Similar to above, but appends _R after any F/L suffix.  */
1787 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1788   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1789   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1790   fcodel = BUILT_IN_MATHFN##L_R ; break;
1791
1792 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1793    if available.  If IMPLICIT is true use the implicit builtin declaration,
1794    otherwise use the explicit declaration.  If we can't do the conversion,
1795    return zero.  */
1796
1797 static tree
1798 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p)
1799 {
1800   enum built_in_function fcode, fcodef, fcodel, fcode2;
1801
1802   switch (fn)
1803     {
1804       CASE_MATHFN (BUILT_IN_ACOS)
1805       CASE_MATHFN (BUILT_IN_ACOSH)
1806       CASE_MATHFN (BUILT_IN_ASIN)
1807       CASE_MATHFN (BUILT_IN_ASINH)
1808       CASE_MATHFN (BUILT_IN_ATAN)
1809       CASE_MATHFN (BUILT_IN_ATAN2)
1810       CASE_MATHFN (BUILT_IN_ATANH)
1811       CASE_MATHFN (BUILT_IN_CBRT)
1812       CASE_MATHFN (BUILT_IN_CEIL)
1813       CASE_MATHFN (BUILT_IN_CEXPI)
1814       CASE_MATHFN (BUILT_IN_COPYSIGN)
1815       CASE_MATHFN (BUILT_IN_COS)
1816       CASE_MATHFN (BUILT_IN_COSH)
1817       CASE_MATHFN (BUILT_IN_DREM)
1818       CASE_MATHFN (BUILT_IN_ERF)
1819       CASE_MATHFN (BUILT_IN_ERFC)
1820       CASE_MATHFN (BUILT_IN_EXP)
1821       CASE_MATHFN (BUILT_IN_EXP10)
1822       CASE_MATHFN (BUILT_IN_EXP2)
1823       CASE_MATHFN (BUILT_IN_EXPM1)
1824       CASE_MATHFN (BUILT_IN_FABS)
1825       CASE_MATHFN (BUILT_IN_FDIM)
1826       CASE_MATHFN (BUILT_IN_FLOOR)
1827       CASE_MATHFN (BUILT_IN_FMA)
1828       CASE_MATHFN (BUILT_IN_FMAX)
1829       CASE_MATHFN (BUILT_IN_FMIN)
1830       CASE_MATHFN (BUILT_IN_FMOD)
1831       CASE_MATHFN (BUILT_IN_FREXP)
1832       CASE_MATHFN (BUILT_IN_GAMMA)
1833       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1834       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1835       CASE_MATHFN (BUILT_IN_HYPOT)
1836       CASE_MATHFN (BUILT_IN_ILOGB)
1837       CASE_MATHFN (BUILT_IN_ICEIL)
1838       CASE_MATHFN (BUILT_IN_IFLOOR)
1839       CASE_MATHFN (BUILT_IN_INF)
1840       CASE_MATHFN (BUILT_IN_IRINT)
1841       CASE_MATHFN (BUILT_IN_IROUND)
1842       CASE_MATHFN (BUILT_IN_ISINF)
1843       CASE_MATHFN (BUILT_IN_J0)
1844       CASE_MATHFN (BUILT_IN_J1)
1845       CASE_MATHFN (BUILT_IN_JN)
1846       CASE_MATHFN (BUILT_IN_LCEIL)
1847       CASE_MATHFN (BUILT_IN_LDEXP)
1848       CASE_MATHFN (BUILT_IN_LFLOOR)
1849       CASE_MATHFN (BUILT_IN_LGAMMA)
1850       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1851       CASE_MATHFN (BUILT_IN_LLCEIL)
1852       CASE_MATHFN (BUILT_IN_LLFLOOR)
1853       CASE_MATHFN (BUILT_IN_LLRINT)
1854       CASE_MATHFN (BUILT_IN_LLROUND)
1855       CASE_MATHFN (BUILT_IN_LOG)
1856       CASE_MATHFN (BUILT_IN_LOG10)
1857       CASE_MATHFN (BUILT_IN_LOG1P)
1858       CASE_MATHFN (BUILT_IN_LOG2)
1859       CASE_MATHFN (BUILT_IN_LOGB)
1860       CASE_MATHFN (BUILT_IN_LRINT)
1861       CASE_MATHFN (BUILT_IN_LROUND)
1862       CASE_MATHFN (BUILT_IN_MODF)
1863       CASE_MATHFN (BUILT_IN_NAN)
1864       CASE_MATHFN (BUILT_IN_NANS)
1865       CASE_MATHFN (BUILT_IN_NEARBYINT)
1866       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1867       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1868       CASE_MATHFN (BUILT_IN_POW)
1869       CASE_MATHFN (BUILT_IN_POWI)
1870       CASE_MATHFN (BUILT_IN_POW10)
1871       CASE_MATHFN (BUILT_IN_REMAINDER)
1872       CASE_MATHFN (BUILT_IN_REMQUO)
1873       CASE_MATHFN (BUILT_IN_RINT)
1874       CASE_MATHFN (BUILT_IN_ROUND)
1875       CASE_MATHFN (BUILT_IN_SCALB)
1876       CASE_MATHFN (BUILT_IN_SCALBLN)
1877       CASE_MATHFN (BUILT_IN_SCALBN)
1878       CASE_MATHFN (BUILT_IN_SIGNBIT)
1879       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1880       CASE_MATHFN (BUILT_IN_SIN)
1881       CASE_MATHFN (BUILT_IN_SINCOS)
1882       CASE_MATHFN (BUILT_IN_SINH)
1883       CASE_MATHFN (BUILT_IN_SQRT)
1884       CASE_MATHFN (BUILT_IN_TAN)
1885       CASE_MATHFN (BUILT_IN_TANH)
1886       CASE_MATHFN (BUILT_IN_TGAMMA)
1887       CASE_MATHFN (BUILT_IN_TRUNC)
1888       CASE_MATHFN (BUILT_IN_Y0)
1889       CASE_MATHFN (BUILT_IN_Y1)
1890       CASE_MATHFN (BUILT_IN_YN)
1891
1892       default:
1893         return NULL_TREE;
1894       }
1895
1896   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1897     fcode2 = fcode;
1898   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1899     fcode2 = fcodef;
1900   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1901     fcode2 = fcodel;
1902   else
1903     return NULL_TREE;
1904
1905   if (implicit_p && !builtin_decl_implicit_p (fcode2))
1906     return NULL_TREE;
1907
1908   return builtin_decl_explicit (fcode2);
1909 }
1910
1911 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1912
1913 tree
1914 mathfn_built_in (tree type, enum built_in_function fn)
1915 {
1916   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1917 }
1918
1919 /* If errno must be maintained, expand the RTL to check if the result,
1920    TARGET, of a built-in function call, EXP, is NaN, and if so set
1921    errno to EDOM.  */
1922
1923 static void
1924 expand_errno_check (tree exp, rtx target)
1925 {
1926   rtx lab = gen_label_rtx ();
1927
1928   /* Test the result; if it is NaN, set errno=EDOM because
1929      the argument was not in the domain.  */
1930   do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1931                            NULL_RTX, NULL_RTX, lab,
1932                            /* The jump is very likely.  */
1933                            REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1));
1934
1935 #ifdef TARGET_EDOM
1936   /* If this built-in doesn't throw an exception, set errno directly.  */
1937   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1938     {
1939 #ifdef GEN_ERRNO_RTX
1940       rtx errno_rtx = GEN_ERRNO_RTX;
1941 #else
1942       rtx errno_rtx
1943           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1944 #endif
1945       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1946       emit_label (lab);
1947       return;
1948     }
1949 #endif
1950
1951   /* Make sure the library call isn't expanded as a tail call.  */
1952   CALL_EXPR_TAILCALL (exp) = 0;
1953
1954   /* We can't set errno=EDOM directly; let the library call do it.
1955      Pop the arguments right away in case the call gets deleted.  */
1956   NO_DEFER_POP;
1957   expand_call (exp, target, 0);
1958   OK_DEFER_POP;
1959   emit_label (lab);
1960 }
1961
1962 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1963    Return NULL_RTX if a normal call should be emitted rather than expanding
1964    the function in-line.  EXP is the expression that is a call to the builtin
1965    function; if convenient, the result should be placed in TARGET.
1966    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1967
1968 static rtx
1969 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1970 {
1971   optab builtin_optab;
1972   rtx op0, insns;
1973   tree fndecl = get_callee_fndecl (exp);
1974   enum machine_mode mode;
1975   bool errno_set = false;
1976   bool try_widening = false;
1977   tree arg;
1978
1979   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1980     return NULL_RTX;
1981
1982   arg = CALL_EXPR_ARG (exp, 0);
1983
1984   switch (DECL_FUNCTION_CODE (fndecl))
1985     {
1986     CASE_FLT_FN (BUILT_IN_SQRT):
1987       errno_set = ! tree_expr_nonnegative_p (arg);
1988       try_widening = true;
1989       builtin_optab = sqrt_optab;
1990       break;
1991     CASE_FLT_FN (BUILT_IN_EXP):
1992       errno_set = true; builtin_optab = exp_optab; break;
1993     CASE_FLT_FN (BUILT_IN_EXP10):
1994     CASE_FLT_FN (BUILT_IN_POW10):
1995       errno_set = true; builtin_optab = exp10_optab; break;
1996     CASE_FLT_FN (BUILT_IN_EXP2):
1997       errno_set = true; builtin_optab = exp2_optab; break;
1998     CASE_FLT_FN (BUILT_IN_EXPM1):
1999       errno_set = true; builtin_optab = expm1_optab; break;
2000     CASE_FLT_FN (BUILT_IN_LOGB):
2001       errno_set = true; builtin_optab = logb_optab; break;
2002     CASE_FLT_FN (BUILT_IN_LOG):
2003       errno_set = true; builtin_optab = log_optab; break;
2004     CASE_FLT_FN (BUILT_IN_LOG10):
2005       errno_set = true; builtin_optab = log10_optab; break;
2006     CASE_FLT_FN (BUILT_IN_LOG2):
2007       errno_set = true; builtin_optab = log2_optab; break;
2008     CASE_FLT_FN (BUILT_IN_LOG1P):
2009       errno_set = true; builtin_optab = log1p_optab; break;
2010     CASE_FLT_FN (BUILT_IN_ASIN):
2011       builtin_optab = asin_optab; break;
2012     CASE_FLT_FN (BUILT_IN_ACOS):
2013       builtin_optab = acos_optab; break;
2014     CASE_FLT_FN (BUILT_IN_TAN):
2015       builtin_optab = tan_optab; break;
2016     CASE_FLT_FN (BUILT_IN_ATAN):
2017       builtin_optab = atan_optab; break;
2018     CASE_FLT_FN (BUILT_IN_FLOOR):
2019       builtin_optab = floor_optab; break;
2020     CASE_FLT_FN (BUILT_IN_CEIL):
2021       builtin_optab = ceil_optab; break;
2022     CASE_FLT_FN (BUILT_IN_TRUNC):
2023       builtin_optab = btrunc_optab; break;
2024     CASE_FLT_FN (BUILT_IN_ROUND):
2025       builtin_optab = round_optab; break;
2026     CASE_FLT_FN (BUILT_IN_NEARBYINT):
2027       builtin_optab = nearbyint_optab;
2028       if (flag_trapping_math)
2029         break;
2030       /* Else fallthrough and expand as rint.  */
2031     CASE_FLT_FN (BUILT_IN_RINT):
2032       builtin_optab = rint_optab; break;
2033     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
2034       builtin_optab = significand_optab; break;
2035     default:
2036       gcc_unreachable ();
2037     }
2038
2039   /* Make a suitable register to place result in.  */
2040   mode = TYPE_MODE (TREE_TYPE (exp));
2041
2042   if (! flag_errno_math || ! HONOR_NANS (mode))
2043     errno_set = false;
2044
2045   /* Before working hard, check whether the instruction is available, but try
2046      to widen the mode for specific operations.  */
2047   if ((optab_handler (builtin_optab, mode) != CODE_FOR_nothing
2048        || (try_widening && !excess_precision_type (TREE_TYPE (exp))))
2049       && (!errno_set || !optimize_insn_for_size_p ()))
2050     {
2051       rtx result = gen_reg_rtx (mode);
2052
2053       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2054          need to expand the argument again.  This way, we will not perform
2055          side-effects more the once.  */
2056       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2057
2058       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2059
2060       start_sequence ();
2061
2062       /* Compute into RESULT.
2063          Set RESULT to wherever the result comes back.  */
2064       result = expand_unop (mode, builtin_optab, op0, result, 0);
2065
2066       if (result != 0)
2067         {
2068           if (errno_set)
2069             expand_errno_check (exp, result);
2070
2071           /* Output the entire sequence.  */
2072           insns = get_insns ();
2073           end_sequence ();
2074           emit_insn (insns);
2075           return result;
2076         }
2077
2078       /* If we were unable to expand via the builtin, stop the sequence
2079          (without outputting the insns) and call to the library function
2080          with the stabilized argument list.  */
2081       end_sequence ();
2082     }
2083
2084   return expand_call (exp, target, target == const0_rtx);
2085 }
2086
2087 /* Expand a call to the builtin binary math functions (pow and atan2).
2088    Return NULL_RTX if a normal call should be emitted rather than expanding the
2089    function in-line.  EXP is the expression that is a call to the builtin
2090    function; if convenient, the result should be placed in TARGET.
2091    SUBTARGET may be used as the target for computing one of EXP's
2092    operands.  */
2093
2094 static rtx
2095 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2096 {
2097   optab builtin_optab;
2098   rtx op0, op1, insns, result;
2099   int op1_type = REAL_TYPE;
2100   tree fndecl = get_callee_fndecl (exp);
2101   tree arg0, arg1;
2102   enum machine_mode mode;
2103   bool errno_set = true;
2104
2105   switch (DECL_FUNCTION_CODE (fndecl))
2106     {
2107     CASE_FLT_FN (BUILT_IN_SCALBN):
2108     CASE_FLT_FN (BUILT_IN_SCALBLN):
2109     CASE_FLT_FN (BUILT_IN_LDEXP):
2110       op1_type = INTEGER_TYPE;
2111     default:
2112       break;
2113     }
2114
2115   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2116     return NULL_RTX;
2117
2118   arg0 = CALL_EXPR_ARG (exp, 0);
2119   arg1 = CALL_EXPR_ARG (exp, 1);
2120
2121   switch (DECL_FUNCTION_CODE (fndecl))
2122     {
2123     CASE_FLT_FN (BUILT_IN_POW):
2124       builtin_optab = pow_optab; break;
2125     CASE_FLT_FN (BUILT_IN_ATAN2):
2126       builtin_optab = atan2_optab; break;
2127     CASE_FLT_FN (BUILT_IN_SCALB):
2128       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2129         return 0;
2130       builtin_optab = scalb_optab; break;
2131     CASE_FLT_FN (BUILT_IN_SCALBN):
2132     CASE_FLT_FN (BUILT_IN_SCALBLN):
2133       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2134         return 0;
2135     /* Fall through... */
2136     CASE_FLT_FN (BUILT_IN_LDEXP):
2137       builtin_optab = ldexp_optab; break;
2138     CASE_FLT_FN (BUILT_IN_FMOD):
2139       builtin_optab = fmod_optab; break;
2140     CASE_FLT_FN (BUILT_IN_REMAINDER):
2141     CASE_FLT_FN (BUILT_IN_DREM):
2142       builtin_optab = remainder_optab; break;
2143     default:
2144       gcc_unreachable ();
2145     }
2146
2147   /* Make a suitable register to place result in.  */
2148   mode = TYPE_MODE (TREE_TYPE (exp));
2149
2150   /* Before working hard, check whether the instruction is available.  */
2151   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2152     return NULL_RTX;
2153
2154   result = gen_reg_rtx (mode);
2155
2156   if (! flag_errno_math || ! HONOR_NANS (mode))
2157     errno_set = false;
2158
2159   if (errno_set && optimize_insn_for_size_p ())
2160     return 0;
2161
2162   /* Always stabilize the argument list.  */
2163   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2164   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2165
2166   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2167   op1 = expand_normal (arg1);
2168
2169   start_sequence ();
2170
2171   /* Compute into RESULT.
2172      Set RESULT to wherever the result comes back.  */
2173   result = expand_binop (mode, builtin_optab, op0, op1,
2174                          result, 0, OPTAB_DIRECT);
2175
2176   /* If we were unable to expand via the builtin, stop the sequence
2177      (without outputting the insns) and call to the library function
2178      with the stabilized argument list.  */
2179   if (result == 0)
2180     {
2181       end_sequence ();
2182       return expand_call (exp, target, target == const0_rtx);
2183     }
2184
2185   if (errno_set)
2186     expand_errno_check (exp, result);
2187
2188   /* Output the entire sequence.  */
2189   insns = get_insns ();
2190   end_sequence ();
2191   emit_insn (insns);
2192
2193   return result;
2194 }
2195
2196 /* Expand a call to the builtin trinary math functions (fma).
2197    Return NULL_RTX if a normal call should be emitted rather than expanding the
2198    function in-line.  EXP is the expression that is a call to the builtin
2199    function; if convenient, the result should be placed in TARGET.
2200    SUBTARGET may be used as the target for computing one of EXP's
2201    operands.  */
2202
2203 static rtx
2204 expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
2205 {
2206   optab builtin_optab;
2207   rtx op0, op1, op2, insns, result;
2208   tree fndecl = get_callee_fndecl (exp);
2209   tree arg0, arg1, arg2;
2210   enum machine_mode mode;
2211
2212   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2213     return NULL_RTX;
2214
2215   arg0 = CALL_EXPR_ARG (exp, 0);
2216   arg1 = CALL_EXPR_ARG (exp, 1);
2217   arg2 = CALL_EXPR_ARG (exp, 2);
2218
2219   switch (DECL_FUNCTION_CODE (fndecl))
2220     {
2221     CASE_FLT_FN (BUILT_IN_FMA):
2222       builtin_optab = fma_optab; break;
2223     default:
2224       gcc_unreachable ();
2225     }
2226
2227   /* Make a suitable register to place result in.  */
2228   mode = TYPE_MODE (TREE_TYPE (exp));
2229
2230   /* Before working hard, check whether the instruction is available.  */
2231   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2232     return NULL_RTX;
2233
2234   result = gen_reg_rtx (mode);
2235
2236   /* Always stabilize the argument list.  */
2237   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2238   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2239   CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2);
2240
2241   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2242   op1 = expand_normal (arg1);
2243   op2 = expand_normal (arg2);
2244
2245   start_sequence ();
2246
2247   /* Compute into RESULT.
2248      Set RESULT to wherever the result comes back.  */
2249   result = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
2250                               result, 0);
2251
2252   /* If we were unable to expand via the builtin, stop the sequence
2253      (without outputting the insns) and call to the library function
2254      with the stabilized argument list.  */
2255   if (result == 0)
2256     {
2257       end_sequence ();
2258       return expand_call (exp, target, target == const0_rtx);
2259     }
2260
2261   /* Output the entire sequence.  */
2262   insns = get_insns ();
2263   end_sequence ();
2264   emit_insn (insns);
2265
2266   return result;
2267 }
2268
2269 /* Expand a call to the builtin sin and cos math functions.
2270    Return NULL_RTX if a normal call should be emitted rather than expanding the
2271    function in-line.  EXP is the expression that is a call to the builtin
2272    function; if convenient, the result should be placed in TARGET.
2273    SUBTARGET may be used as the target for computing one of EXP's
2274    operands.  */
2275
2276 static rtx
2277 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2278 {
2279   optab builtin_optab;
2280   rtx op0, insns;
2281   tree fndecl = get_callee_fndecl (exp);
2282   enum machine_mode mode;
2283   tree arg;
2284
2285   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2286     return NULL_RTX;
2287
2288   arg = CALL_EXPR_ARG (exp, 0);
2289
2290   switch (DECL_FUNCTION_CODE (fndecl))
2291     {
2292     CASE_FLT_FN (BUILT_IN_SIN):
2293     CASE_FLT_FN (BUILT_IN_COS):
2294       builtin_optab = sincos_optab; break;
2295     default:
2296       gcc_unreachable ();
2297     }
2298
2299   /* Make a suitable register to place result in.  */
2300   mode = TYPE_MODE (TREE_TYPE (exp));
2301
2302   /* Check if sincos insn is available, otherwise fallback
2303      to sin or cos insn.  */
2304   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2305     switch (DECL_FUNCTION_CODE (fndecl))
2306       {
2307       CASE_FLT_FN (BUILT_IN_SIN):
2308         builtin_optab = sin_optab; break;
2309       CASE_FLT_FN (BUILT_IN_COS):
2310         builtin_optab = cos_optab; break;
2311       default:
2312         gcc_unreachable ();
2313       }
2314
2315   /* Before working hard, check whether the instruction is available.  */
2316   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
2317     {
2318       rtx result = gen_reg_rtx (mode);
2319
2320       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2321          need to expand the argument again.  This way, we will not perform
2322          side-effects more the once.  */
2323       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2324
2325       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2326
2327       start_sequence ();
2328
2329       /* Compute into RESULT.
2330          Set RESULT to wherever the result comes back.  */
2331       if (builtin_optab == sincos_optab)
2332         {
2333           int ok;
2334
2335           switch (DECL_FUNCTION_CODE (fndecl))
2336             {
2337             CASE_FLT_FN (BUILT_IN_SIN):
2338               ok = expand_twoval_unop (builtin_optab, op0, 0, result, 0);
2339               break;
2340             CASE_FLT_FN (BUILT_IN_COS):
2341               ok = expand_twoval_unop (builtin_optab, op0, result, 0, 0);
2342               break;
2343             default:
2344               gcc_unreachable ();
2345             }
2346           gcc_assert (ok);
2347         }
2348       else
2349         result = expand_unop (mode, builtin_optab, op0, result, 0);
2350
2351       if (result != 0)
2352         {
2353           /* Output the entire sequence.  */
2354           insns = get_insns ();
2355           end_sequence ();
2356           emit_insn (insns);
2357           return result;
2358         }
2359
2360       /* If we were unable to expand via the builtin, stop the sequence
2361          (without outputting the insns) and call to the library function
2362          with the stabilized argument list.  */
2363       end_sequence ();
2364     }
2365
2366   return expand_call (exp, target, target == const0_rtx);
2367 }
2368
2369 /* Given an interclass math builtin decl FNDECL and it's argument ARG
2370    return an RTL instruction code that implements the functionality.
2371    If that isn't possible or available return CODE_FOR_nothing.  */
2372
2373 static enum insn_code
2374 interclass_mathfn_icode (tree arg, tree fndecl)
2375 {
2376   bool errno_set = false;
2377   optab builtin_optab = unknown_optab;
2378   enum machine_mode mode;
2379
2380   switch (DECL_FUNCTION_CODE (fndecl))
2381     {
2382     CASE_FLT_FN (BUILT_IN_ILOGB):
2383       errno_set = true; builtin_optab = ilogb_optab; break;
2384     CASE_FLT_FN (BUILT_IN_ISINF):
2385       builtin_optab = isinf_optab; break;
2386     case BUILT_IN_ISNORMAL:
2387     case BUILT_IN_ISFINITE:
2388     CASE_FLT_FN (BUILT_IN_FINITE):
2389     case BUILT_IN_FINITED32:
2390     case BUILT_IN_FINITED64:
2391     case BUILT_IN_FINITED128:
2392     case BUILT_IN_ISINFD32:
2393     case BUILT_IN_ISINFD64:
2394     case BUILT_IN_ISINFD128:
2395       /* These builtins have no optabs (yet).  */
2396       break;
2397     default:
2398       gcc_unreachable ();
2399     }
2400
2401   /* There's no easy way to detect the case we need to set EDOM.  */
2402   if (flag_errno_math && errno_set)
2403     return CODE_FOR_nothing;
2404
2405   /* Optab mode depends on the mode of the input argument.  */
2406   mode = TYPE_MODE (TREE_TYPE (arg));
2407
2408   if (builtin_optab)
2409     return optab_handler (builtin_optab, mode);
2410   return CODE_FOR_nothing;
2411 }
2412
2413 /* Expand a call to one of the builtin math functions that operate on
2414    floating point argument and output an integer result (ilogb, isinf,
2415    isnan, etc).
2416    Return 0 if a normal call should be emitted rather than expanding the
2417    function in-line.  EXP is the expression that is a call to the builtin
2418    function; if convenient, the result should be placed in TARGET.  */
2419
2420 static rtx
2421 expand_builtin_interclass_mathfn (tree exp, rtx target)
2422 {
2423   enum insn_code icode = CODE_FOR_nothing;
2424   rtx op0;
2425   tree fndecl = get_callee_fndecl (exp);
2426   enum machine_mode mode;
2427   tree arg;
2428
2429   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2430     return NULL_RTX;
2431
2432   arg = CALL_EXPR_ARG (exp, 0);
2433   icode = interclass_mathfn_icode (arg, fndecl);
2434   mode = TYPE_MODE (TREE_TYPE (arg));
2435
2436   if (icode != CODE_FOR_nothing)
2437     {
2438       struct expand_operand ops[1];
2439       rtx last = get_last_insn ();
2440       tree orig_arg = arg;
2441
2442       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2443          need to expand the argument again.  This way, we will not perform
2444          side-effects more the once.  */
2445       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2446
2447       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2448
2449       if (mode != GET_MODE (op0))
2450         op0 = convert_to_mode (mode, op0, 0);
2451
2452       create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
2453       if (maybe_legitimize_operands (icode, 0, 1, ops)
2454           && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN))
2455         return ops[0].value;
2456
2457       delete_insns_since (last);
2458       CALL_EXPR_ARG (exp, 0) = orig_arg;
2459     }
2460
2461   return NULL_RTX;
2462 }
2463
2464 /* Expand a call to the builtin sincos math function.
2465    Return NULL_RTX if a normal call should be emitted rather than expanding the
2466    function in-line.  EXP is the expression that is a call to the builtin
2467    function.  */
2468
2469 static rtx
2470 expand_builtin_sincos (tree exp)
2471 {
2472   rtx op0, op1, op2, target1, target2;
2473   enum machine_mode mode;
2474   tree arg, sinp, cosp;
2475   int result;
2476   location_t loc = EXPR_LOCATION (exp);
2477   tree alias_type, alias_off;
2478
2479   if (!validate_arglist (exp, REAL_TYPE,
2480                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2481     return NULL_RTX;
2482
2483   arg = CALL_EXPR_ARG (exp, 0);
2484   sinp = CALL_EXPR_ARG (exp, 1);
2485   cosp = CALL_EXPR_ARG (exp, 2);
2486
2487   /* Make a suitable register to place result in.  */
2488   mode = TYPE_MODE (TREE_TYPE (arg));
2489
2490   /* Check if sincos insn is available, otherwise emit the call.  */
2491   if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing)
2492     return NULL_RTX;
2493
2494   target1 = gen_reg_rtx (mode);
2495   target2 = gen_reg_rtx (mode);
2496
2497   op0 = expand_normal (arg);
2498   alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true);
2499   alias_off = build_int_cst (alias_type, 0);
2500   op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2501                                         sinp, alias_off));
2502   op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2503                                         cosp, alias_off));
2504
2505   /* Compute into target1 and target2.
2506      Set TARGET to wherever the result comes back.  */
2507   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2508   gcc_assert (result);
2509
2510   /* Move target1 and target2 to the memory locations indicated
2511      by op1 and op2.  */
2512   emit_move_insn (op1, target1);
2513   emit_move_insn (op2, target2);
2514
2515   return const0_rtx;
2516 }
2517
2518 /* Expand a call to the internal cexpi builtin to the sincos math function.
2519    EXP is the expression that is a call to the builtin function; if convenient,
2520    the result should be placed in TARGET.  */
2521
2522 static rtx
2523 expand_builtin_cexpi (tree exp, rtx target)
2524 {
2525   tree fndecl = get_callee_fndecl (exp);
2526   tree arg, type;
2527   enum machine_mode mode;
2528   rtx op0, op1, op2;
2529   location_t loc = EXPR_LOCATION (exp);
2530
2531   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2532     return NULL_RTX;
2533
2534   arg = CALL_EXPR_ARG (exp, 0);
2535   type = TREE_TYPE (arg);
2536   mode = TYPE_MODE (TREE_TYPE (arg));
2537
2538   /* Try expanding via a sincos optab, fall back to emitting a libcall
2539      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2540      is only generated from sincos, cexp or if we have either of them.  */
2541   if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing)
2542     {
2543       op1 = gen_reg_rtx (mode);
2544       op2 = gen_reg_rtx (mode);
2545
2546       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2547
2548       /* Compute into op1 and op2.  */
2549       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2550     }
2551   else if (TARGET_HAS_SINCOS)
2552     {
2553       tree call, fn = NULL_TREE;
2554       tree top1, top2;
2555       rtx op1a, op2a;
2556
2557       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2558         fn = builtin_decl_explicit (BUILT_IN_SINCOSF);
2559       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2560         fn = builtin_decl_explicit (BUILT_IN_SINCOS);
2561       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2562         fn = builtin_decl_explicit (BUILT_IN_SINCOSL);
2563       else
2564         gcc_unreachable ();
2565
2566       op1 = assign_temp (TREE_TYPE (arg), 1, 1);
2567       op2 = assign_temp (TREE_TYPE (arg), 1, 1);
2568       op1a = copy_addr_to_reg (XEXP (op1, 0));
2569       op2a = copy_addr_to_reg (XEXP (op2, 0));
2570       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2571       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2572
2573       /* Make sure not to fold the sincos call again.  */
2574       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2575       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2576                                       call, 3, arg, top1, top2));
2577     }
2578   else
2579     {
2580       tree call, fn = NULL_TREE, narg;
2581       tree ctype = build_complex_type (type);
2582
2583       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2584         fn = builtin_decl_explicit (BUILT_IN_CEXPF);
2585       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2586         fn = builtin_decl_explicit (BUILT_IN_CEXP);
2587       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2588         fn = builtin_decl_explicit (BUILT_IN_CEXPL);
2589       else
2590         gcc_unreachable ();
2591
2592       /* If we don't have a decl for cexp create one.  This is the
2593          friendliest fallback if the user calls __builtin_cexpi
2594          without full target C99 function support.  */
2595       if (fn == NULL_TREE)
2596         {
2597           tree fntype;
2598           const char *name = NULL;
2599
2600           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2601             name = "cexpf";
2602           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2603             name = "cexp";
2604           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2605             name = "cexpl";
2606
2607           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2608           fn = build_fn_decl (name, fntype);
2609         }
2610
2611       narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2612                           build_real (type, dconst0), arg);
2613
2614       /* Make sure not to fold the cexp call again.  */
2615       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2616       return expand_expr (build_call_nary (ctype, call, 1, narg),
2617                           target, VOIDmode, EXPAND_NORMAL);
2618     }
2619
2620   /* Now build the proper return type.  */
2621   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2622                               make_tree (TREE_TYPE (arg), op2),
2623                               make_tree (TREE_TYPE (arg), op1)),
2624                       target, VOIDmode, EXPAND_NORMAL);
2625 }
2626
2627 /* Conveniently construct a function call expression.  FNDECL names the
2628    function to be called, N is the number of arguments, and the "..."
2629    parameters are the argument expressions.  Unlike build_call_exr
2630    this doesn't fold the call, hence it will always return a CALL_EXPR.  */
2631
2632 static tree
2633 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2634 {
2635   va_list ap;
2636   tree fntype = TREE_TYPE (fndecl);
2637   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2638
2639   va_start (ap, n);
2640   fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2641   va_end (ap);
2642   SET_EXPR_LOCATION (fn, loc);
2643   return fn;
2644 }
2645
2646 /* Expand a call to one of the builtin rounding functions gcc defines
2647    as an extension (lfloor and lceil).  As these are gcc extensions we
2648    do not need to worry about setting errno to EDOM.
2649    If expanding via optab fails, lower expression to (int)(floor(x)).
2650    EXP is the expression that is a call to the builtin function;
2651    if convenient, the result should be placed in TARGET.  */
2652
2653 static rtx
2654 expand_builtin_int_roundingfn (tree exp, rtx target)
2655 {
2656   convert_optab builtin_optab;
2657   rtx op0, insns, tmp;
2658   tree fndecl = get_callee_fndecl (exp);
2659   enum built_in_function fallback_fn;
2660   tree fallback_fndecl;
2661   enum machine_mode mode;
2662   tree arg;
2663
2664   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2665     gcc_unreachable ();
2666
2667   arg = CALL_EXPR_ARG (exp, 0);
2668
2669   switch (DECL_FUNCTION_CODE (fndecl))
2670     {
2671     CASE_FLT_FN (BUILT_IN_ICEIL):
2672     CASE_FLT_FN (BUILT_IN_LCEIL):
2673     CASE_FLT_FN (BUILT_IN_LLCEIL):
2674       builtin_optab = lceil_optab;
2675       fallback_fn = BUILT_IN_CEIL;
2676       break;
2677
2678     CASE_FLT_FN (BUILT_IN_IFLOOR):
2679     CASE_FLT_FN (BUILT_IN_LFLOOR):
2680     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2681       builtin_optab = lfloor_optab;
2682       fallback_fn = BUILT_IN_FLOOR;
2683       break;
2684
2685     default:
2686       gcc_unreachable ();
2687     }
2688
2689   /* Make a suitable register to place result in.  */
2690   mode = TYPE_MODE (TREE_TYPE (exp));
2691
2692   target = gen_reg_rtx (mode);
2693
2694   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2695      need to expand the argument again.  This way, we will not perform
2696      side-effects more the once.  */
2697   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2698
2699   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2700
2701   start_sequence ();
2702
2703   /* Compute into TARGET.  */
2704   if (expand_sfix_optab (target, op0, builtin_optab))
2705     {
2706       /* Output the entire sequence.  */
2707       insns = get_insns ();
2708       end_sequence ();
2709       emit_insn (insns);
2710       return target;
2711     }
2712
2713   /* If we were unable to expand via the builtin, stop the sequence
2714      (without outputting the insns).  */
2715   end_sequence ();
2716
2717   /* Fall back to floating point rounding optab.  */
2718   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2719
2720   /* For non-C99 targets we may end up without a fallback fndecl here
2721      if the user called __builtin_lfloor directly.  In this case emit
2722      a call to the floor/ceil variants nevertheless.  This should result
2723      in the best user experience for not full C99 targets.  */
2724   if (fallback_fndecl == NULL_TREE)
2725     {
2726       tree fntype;
2727       const char *name = NULL;
2728
2729       switch (DECL_FUNCTION_CODE (fndecl))
2730         {
2731         case BUILT_IN_ICEIL:
2732         case BUILT_IN_LCEIL:
2733         case BUILT_IN_LLCEIL:
2734           name = "ceil";
2735           break;
2736         case BUILT_IN_ICEILF:
2737         case BUILT_IN_LCEILF:
2738         case BUILT_IN_LLCEILF:
2739           name = "ceilf";
2740           break;
2741         case BUILT_IN_ICEILL:
2742         case BUILT_IN_LCEILL:
2743         case BUILT_IN_LLCEILL:
2744           name = "ceill";
2745           break;
2746         case BUILT_IN_IFLOOR:
2747         case BUILT_IN_LFLOOR:
2748         case BUILT_IN_LLFLOOR:
2749           name = "floor";
2750           break;
2751         case BUILT_IN_IFLOORF:
2752         case BUILT_IN_LFLOORF:
2753         case BUILT_IN_LLFLOORF:
2754           name = "floorf";
2755           break;
2756         case BUILT_IN_IFLOORL:
2757         case BUILT_IN_LFLOORL:
2758         case BUILT_IN_LLFLOORL:
2759           name = "floorl";
2760           break;
2761         default:
2762           gcc_unreachable ();
2763         }
2764
2765       fntype = build_function_type_list (TREE_TYPE (arg),
2766                                          TREE_TYPE (arg), NULL_TREE);
2767       fallback_fndecl = build_fn_decl (name, fntype);
2768     }
2769
2770   exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
2771
2772   tmp = expand_normal (exp);
2773   tmp = maybe_emit_group_store (tmp, TREE_TYPE (exp));
2774
2775   /* Truncate the result of floating point optab to integer
2776      via expand_fix ().  */
2777   target = gen_reg_rtx (mode);
2778   expand_fix (target, tmp, 0);
2779
2780   return target;
2781 }
2782
2783 /* Expand a call to one of the builtin math functions doing integer
2784    conversion (lrint).
2785    Return 0 if a normal call should be emitted rather than expanding the
2786    function in-line.  EXP is the expression that is a call to the builtin
2787    function; if convenient, the result should be placed in TARGET.  */
2788
2789 static rtx
2790 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2791 {
2792   convert_optab builtin_optab;
2793   rtx op0, insns;
2794   tree fndecl = get_callee_fndecl (exp);
2795   tree arg;
2796   enum machine_mode mode;
2797   enum built_in_function fallback_fn = BUILT_IN_NONE;
2798
2799   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2800      gcc_unreachable ();
2801
2802   arg = CALL_EXPR_ARG (exp, 0);
2803
2804   switch (DECL_FUNCTION_CODE (fndecl))
2805     {
2806     CASE_FLT_FN (BUILT_IN_IRINT):
2807       fallback_fn = BUILT_IN_LRINT;
2808       /* FALLTHRU */
2809     CASE_FLT_FN (BUILT_IN_LRINT):
2810     CASE_FLT_FN (BUILT_IN_LLRINT):
2811       builtin_optab = lrint_optab;
2812       break;
2813
2814     CASE_FLT_FN (BUILT_IN_IROUND):
2815       fallback_fn = BUILT_IN_LROUND;
2816       /* FALLTHRU */
2817     CASE_FLT_FN (BUILT_IN_LROUND):
2818     CASE_FLT_FN (BUILT_IN_LLROUND):
2819       builtin_optab = lround_optab;
2820       break;
2821
2822     default:
2823       gcc_unreachable ();
2824     }
2825
2826   /* There's no easy way to detect the case we need to set EDOM.  */
2827   if (flag_errno_math && fallback_fn == BUILT_IN_NONE)
2828     return NULL_RTX;
2829
2830   /* Make a suitable register to place result in.  */
2831   mode = TYPE_MODE (TREE_TYPE (exp));
2832
2833   /* There's no easy way to detect the case we need to set EDOM.  */
2834   if (!flag_errno_math)
2835     {
2836       rtx result = gen_reg_rtx (mode);
2837
2838       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2839          need to expand the argument again.  This way, we will not perform
2840          side-effects more the once.  */
2841       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2842
2843       op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2844
2845       start_sequence ();
2846
2847       if (expand_sfix_optab (result, op0, builtin_optab))
2848         {
2849           /* Output the entire sequence.  */
2850           insns = get_insns ();
2851           end_sequence ();
2852           emit_insn (insns);
2853           return result;
2854         }
2855
2856       /* If we were unable to expand via the builtin, stop the sequence
2857          (without outputting the insns) and call to the library function
2858          with the stabilized argument list.  */
2859       end_sequence ();
2860     }
2861
2862   if (fallback_fn != BUILT_IN_NONE)
2863     {
2864       /* Fall back to rounding to long int.  Use implicit_p 0 - for non-C99
2865          targets, (int) round (x) should never be transformed into
2866          BUILT_IN_IROUND and if __builtin_iround is called directly, emit
2867          a call to lround in the hope that the target provides at least some
2868          C99 functions.  This should result in the best user experience for
2869          not full C99 targets.  */
2870       tree fallback_fndecl = mathfn_built_in_1 (TREE_TYPE (arg),
2871                                                 fallback_fn, 0);
2872
2873       exp = build_call_nofold_loc (EXPR_LOCATION (exp),
2874                                    fallback_fndecl, 1, arg);
2875
2876       target = expand_call (exp, NULL_RTX, target == const0_rtx);
2877       target = maybe_emit_group_store (target, TREE_TYPE (exp));
2878       return convert_to_mode (mode, target, 0);
2879     }
2880
2881   return expand_call (exp, target, target == const0_rtx);
2882 }
2883
2884 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
2885    a normal call should be emitted rather than expanding the function
2886    in-line.  EXP is the expression that is a call to the builtin
2887    function; if convenient, the result should be placed in TARGET.  */
2888
2889 static rtx
2890 expand_builtin_powi (tree exp, rtx target)
2891 {
2892   tree arg0, arg1;
2893   rtx op0, op1;
2894   enum machine_mode mode;
2895   enum machine_mode mode2;
2896
2897   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2898     return NULL_RTX;
2899
2900   arg0 = CALL_EXPR_ARG (exp, 0);
2901   arg1 = CALL_EXPR_ARG (exp, 1);
2902   mode = TYPE_MODE (TREE_TYPE (exp));
2903
2904   /* Emit a libcall to libgcc.  */
2905
2906   /* Mode of the 2nd argument must match that of an int.  */
2907   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2908
2909   if (target == NULL_RTX)
2910     target = gen_reg_rtx (mode);
2911
2912   op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL);
2913   if (GET_MODE (op0) != mode)
2914     op0 = convert_to_mode (mode, op0, 0);
2915   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
2916   if (GET_MODE (op1) != mode2)
2917     op1 = convert_to_mode (mode2, op1, 0);
2918
2919   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2920                                     target, LCT_CONST, mode, 2,
2921                                     op0, mode, op1, mode2);
2922
2923   return target;
2924 }
2925
2926 /* Expand expression EXP which is a call to the strlen builtin.  Return
2927    NULL_RTX if we failed the caller should emit a normal call, otherwise
2928    try to get the result in TARGET, if convenient.  */
2929
2930 static rtx
2931 expand_builtin_strlen (tree exp, rtx target,
2932                        enum machine_mode target_mode)
2933 {
2934   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2935     return NULL_RTX;
2936   else
2937     {
2938       struct expand_operand ops[4];
2939       rtx pat;
2940       tree len;
2941       tree src = CALL_EXPR_ARG (exp, 0);
2942       rtx src_reg, before_strlen;
2943       enum machine_mode insn_mode = target_mode;
2944       enum insn_code icode = CODE_FOR_nothing;
2945       unsigned int align;
2946
2947       /* If the length can be computed at compile-time, return it.  */
2948       len = c_strlen (src, 0);
2949       if (len)
2950         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2951
2952       /* If the length can be computed at compile-time and is constant
2953          integer, but there are side-effects in src, evaluate
2954          src for side-effects, then return len.
2955          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2956          can be optimized into: i++; x = 3;  */
2957       len = c_strlen (src, 1);
2958       if (len && TREE_CODE (len) == INTEGER_CST)
2959         {
2960           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2961           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2962         }
2963
2964       align = get_pointer_alignment (src) / BITS_PER_UNIT;
2965
2966       /* If SRC is not a pointer type, don't do this operation inline.  */
2967       if (align == 0)
2968         return NULL_RTX;
2969
2970       /* Bail out if we can't compute strlen in the right mode.  */
2971       while (insn_mode != VOIDmode)
2972         {
2973           icode = optab_handler (strlen_optab, insn_mode);
2974           if (icode != CODE_FOR_nothing)
2975             break;
2976
2977           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2978         }
2979       if (insn_mode == VOIDmode)
2980         return NULL_RTX;
2981
2982       /* Make a place to hold the source address.  We will not expand
2983          the actual source until we are sure that the expansion will
2984          not fail -- there are trees that cannot be expanded twice.  */
2985       src_reg = gen_reg_rtx (Pmode);
2986
2987       /* Mark the beginning of the strlen sequence so we can emit the
2988          source operand later.  */
2989       before_strlen = get_last_insn ();
2990
2991       create_output_operand (&ops[0], target, insn_mode);
2992       create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg));
2993       create_integer_operand (&ops[2], 0);
2994       create_integer_operand (&ops[3], align);
2995       if (!maybe_expand_insn (icode, 4, ops))
2996         return NULL_RTX;
2997
2998       /* Now that we are assured of success, expand the source.  */
2999       start_sequence ();
3000       pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL);
3001       if (pat != src_reg)
3002         {
3003 #ifdef POINTERS_EXTEND_UNSIGNED
3004           if (GET_MODE (pat) != Pmode)
3005             pat = convert_to_mode (Pmode, pat,
3006                                    POINTERS_EXTEND_UNSIGNED);
3007 #endif
3008           emit_move_insn (src_reg, pat);
3009         }
3010       pat = get_insns ();
3011       end_sequence ();
3012
3013       if (before_strlen)
3014         emit_insn_after (pat, before_strlen);
3015       else
3016         emit_insn_before (pat, get_insns ());
3017
3018       /* Return the value in the proper mode for this function.  */
3019       if (GET_MODE (ops[0].value) == target_mode)
3020         target = ops[0].value;
3021       else if (target != 0)
3022         convert_move (target, ops[0].value, 0);
3023       else
3024         target = convert_to_mode (target_mode, ops[0].value, 0);
3025
3026       return target;
3027     }
3028 }
3029
3030 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3031    bytes from constant string DATA + OFFSET and return it as target
3032    constant.  */
3033
3034 static rtx
3035 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3036                          enum machine_mode mode)
3037 {
3038   const char *str = (const char *) data;
3039
3040   gcc_assert (offset >= 0
3041               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3042                   <= strlen (str) + 1));
3043
3044   return c_readstr (str + offset, mode);
3045 }
3046
3047 /* Expand a call EXP to the memcpy builtin.
3048    Return NULL_RTX if we failed, the caller should emit a normal call,
3049    otherwise try to get the result in TARGET, if convenient (and in
3050    mode MODE if that's convenient).  */
3051
3052 static rtx
3053 expand_builtin_memcpy (tree exp, rtx target)
3054 {
3055   if (!validate_arglist (exp,
3056                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3057     return NULL_RTX;
3058   else
3059     {
3060       tree dest = CALL_EXPR_ARG (exp, 0);
3061       tree src = CALL_EXPR_ARG (exp, 1);
3062       tree len = CALL_EXPR_ARG (exp, 2);
3063       const char *src_str;
3064       unsigned int src_align = get_pointer_alignment (src);
3065       unsigned int dest_align = get_pointer_alignment (dest);
3066       rtx dest_mem, src_mem, dest_addr, len_rtx;
3067       HOST_WIDE_INT expected_size = -1;
3068       unsigned int expected_align = 0;
3069
3070       /* If DEST is not a pointer type, call the normal function.  */
3071       if (dest_align == 0)
3072         return NULL_RTX;
3073
3074       /* If either SRC is not a pointer type, don't do this
3075          operation in-line.  */
3076       if (src_align == 0)
3077         return NULL_RTX;
3078
3079       if (currently_expanding_gimple_stmt)
3080         stringop_block_profile (currently_expanding_gimple_stmt,
3081                                 &expected_align, &expected_size);
3082
3083       if (expected_align < dest_align)
3084         expected_align = dest_align;
3085       dest_mem = get_memory_rtx (dest, len);
3086       set_mem_align (dest_mem, dest_align);
3087       len_rtx = expand_normal (len);
3088       src_str = c_getstr (src);
3089
3090       /* If SRC is a string constant and block move would be done
3091          by pieces, we can avoid loading the string from memory
3092          and only stored the computed constants.  */
3093       if (src_str
3094           && CONST_INT_P (len_rtx)
3095           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3096           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3097                                   CONST_CAST (char *, src_str),
3098                                   dest_align, false))
3099         {
3100           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3101                                       builtin_memcpy_read_str,
3102                                       CONST_CAST (char *, src_str),
3103                                       dest_align, false, 0);
3104           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3105           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3106           return dest_mem;
3107         }
3108
3109       src_mem = get_memory_rtx (src, len);
3110       set_mem_align (src_mem, src_align);
3111
3112       /* Copy word part most expediently.  */
3113       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3114                                          CALL_EXPR_TAILCALL (exp)
3115                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3116                                          expected_align, expected_size);
3117
3118       if (dest_addr == 0)
3119         {
3120           dest_addr = force_operand (XEXP (dest_mem, 0), target);
3121           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3122         }
3123       return dest_addr;
3124     }
3125 }
3126
3127 /* Expand a call EXP to the mempcpy builtin.
3128    Return NULL_RTX if we failed; the caller should emit a normal call,
3129    otherwise try to get the result in TARGET, if convenient (and in
3130    mode MODE if that's convenient).  If ENDP is 0 return the
3131    destination pointer, if ENDP is 1 return the end pointer ala
3132    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3133    stpcpy.  */
3134
3135 static rtx
3136 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3137 {
3138   if (!validate_arglist (exp,
3139                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3140     return NULL_RTX;
3141   else
3142     {
3143       tree dest = CALL_EXPR_ARG (exp, 0);
3144       tree src = CALL_EXPR_ARG (exp, 1);
3145       tree len = CALL_EXPR_ARG (exp, 2);
3146       return expand_builtin_mempcpy_args (dest, src, len,
3147                                           target, mode, /*endp=*/ 1);
3148     }
3149 }
3150
3151 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3152    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3153    so that this can also be called without constructing an actual CALL_EXPR.
3154    The other arguments and return value are the same as for
3155    expand_builtin_mempcpy.  */
3156
3157 static rtx
3158 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3159                              rtx target, enum machine_mode mode, int endp)
3160 {
3161     /* If return value is ignored, transform mempcpy into memcpy.  */
3162   if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
3163     {
3164       tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3165       tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
3166                                            dest, src, len);
3167       return expand_expr (result, target, mode, EXPAND_NORMAL);
3168     }
3169   else
3170     {
3171       const char *src_str;
3172       unsigned int src_align = get_pointer_alignment (src);
3173       unsigned int dest_align = get_pointer_alignment (dest);
3174       rtx dest_mem, src_mem, len_rtx;
3175
3176       /* If either SRC or DEST is not a pointer type, don't do this
3177          operation in-line.  */
3178       if (dest_align == 0 || src_align == 0)
3179         return NULL_RTX;
3180
3181       /* If LEN is not constant, call the normal function.  */
3182       if (! host_integerp (len, 1))
3183         return NULL_RTX;
3184
3185       len_rtx = expand_normal (len);
3186       src_str = c_getstr (src);
3187
3188       /* If SRC is a string constant and block move would be done
3189          by pieces, we can avoid loading the string from memory
3190          and only stored the computed constants.  */
3191       if (src_str
3192           && CONST_INT_P (len_rtx)
3193           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3194           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3195                                   CONST_CAST (char *, src_str),
3196                                   dest_align, false))
3197         {
3198           dest_mem = get_memory_rtx (dest, len);
3199           set_mem_align (dest_mem, dest_align);
3200           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3201                                       builtin_memcpy_read_str,
3202                                       CONST_CAST (char *, src_str),
3203                                       dest_align, false, endp);
3204           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3205           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3206           return dest_mem;
3207         }
3208
3209       if (CONST_INT_P (len_rtx)
3210           && can_move_by_pieces (INTVAL (len_rtx),
3211                                  MIN (dest_align, src_align)))
3212         {
3213           dest_mem = get_memory_rtx (dest, len);
3214           set_mem_align (dest_mem, dest_align);
3215           src_mem = get_memory_rtx (src, len);
3216           set_mem_align (src_mem, src_align);
3217           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3218                                      MIN (dest_align, src_align), endp);
3219           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3220           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3221           return dest_mem;
3222         }
3223
3224       return NULL_RTX;
3225     }
3226 }
3227
3228 #ifndef HAVE_movstr
3229 # define HAVE_movstr 0
3230 # define CODE_FOR_movstr CODE_FOR_nothing
3231 #endif
3232
3233 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3234    we failed, the caller should emit a normal call, otherwise try to
3235    get the result in TARGET, if convenient.  If ENDP is 0 return the
3236    destination pointer, if ENDP is 1 return the end pointer ala
3237    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3238    stpcpy.  */
3239
3240 static rtx
3241 expand_movstr (tree dest, tree src, rtx target, int endp)
3242 {
3243   struct expand_operand ops[3];
3244   rtx dest_mem;
3245   rtx src_mem;
3246
3247   if (!HAVE_movstr)
3248     return NULL_RTX;
3249
3250   dest_mem = get_memory_rtx (dest, NULL);
3251   src_mem = get_memory_rtx (src, NULL);
3252   if (!endp)
3253     {
3254       target = force_reg (Pmode, XEXP (dest_mem, 0));
3255       dest_mem = replace_equiv_address (dest_mem, target);
3256     }
3257
3258   create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
3259   create_fixed_operand (&ops[1], dest_mem);
3260   create_fixed_operand (&ops[2], src_mem);
3261   expand_insn (CODE_FOR_movstr, 3, ops);
3262
3263   if (endp && target != const0_rtx)
3264     {
3265       target = ops[0].value;
3266       /* movstr is supposed to set end to the address of the NUL
3267          terminator.  If the caller requested a mempcpy-like return value,
3268          adjust it.  */
3269       if (endp == 1)
3270         {
3271           rtx tem = plus_constant (GET_MODE (target),
3272                                    gen_lowpart (GET_MODE (target), target), 1);
3273           emit_move_insn (target, force_operand (tem, NULL_RTX));
3274         }
3275     }
3276   return target;
3277 }
3278
3279 /* Expand expression EXP, which is a call to the strcpy builtin.  Return
3280    NULL_RTX if we failed the caller should emit a normal call, otherwise
3281    try to get the result in TARGET, if convenient (and in mode MODE if that's
3282    convenient).  */
3283
3284 static rtx
3285 expand_builtin_strcpy (tree exp, rtx target)
3286 {
3287   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3288    {
3289      tree dest = CALL_EXPR_ARG (exp, 0);
3290      tree src = CALL_EXPR_ARG (exp, 1);
3291      return expand_builtin_strcpy_args (dest, src, target);
3292    }
3293    return NULL_RTX;
3294 }
3295
3296 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3297    arguments to the builtin_strcpy call DEST and SRC are broken out
3298    so that this can also be called without constructing an actual CALL_EXPR.
3299    The other arguments and return value are the same as for
3300    expand_builtin_strcpy.  */
3301
3302 static rtx
3303 expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3304 {
3305   return expand_movstr (dest, src, target, /*endp=*/0);
3306 }
3307
3308 /* Expand a call EXP to the stpcpy builtin.
3309    Return NULL_RTX if we failed the caller should emit a normal call,
3310    otherwise try to get the result in TARGET, if convenient (and in
3311    mode MODE if that's convenient).  */
3312
3313 static rtx
3314 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3315 {
3316   tree dst, src;
3317   location_t loc = EXPR_LOCATION (exp);
3318
3319   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3320     return NULL_RTX;
3321
3322   dst = CALL_EXPR_ARG (exp, 0);
3323   src = CALL_EXPR_ARG (exp, 1);
3324
3325   /* If return value is ignored, transform stpcpy into strcpy.  */
3326   if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY))
3327     {
3328       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3329       tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
3330       return expand_expr (result, target, mode, EXPAND_NORMAL);
3331     }
3332   else
3333     {
3334       tree len, lenp1;
3335       rtx ret;
3336
3337       /* Ensure we get an actual string whose length can be evaluated at
3338          compile-time, not an expression containing a string.  This is
3339          because the latter will potentially produce pessimized code
3340          when used to produce the return value.  */
3341       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3342         return expand_movstr (dst, src, target, /*endp=*/2);
3343
3344       lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3345       ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3346                                          target, mode, /*endp=*/2);
3347
3348       if (ret)
3349         return ret;
3350
3351       if (TREE_CODE (len) == INTEGER_CST)
3352         {
3353           rtx len_rtx = expand_normal (len);
3354
3355           if (CONST_INT_P (len_rtx))
3356             {
3357               ret = expand_builtin_strcpy_args (dst, src, target);
3358
3359               if (ret)
3360                 {
3361                   if (! target)
3362                     {
3363                       if (mode != VOIDmode)
3364                         target = gen_reg_rtx (mode);
3365                       else
3366                         target = gen_reg_rtx (GET_MODE (ret));
3367                     }
3368                   if (GET_MODE (target) != GET_MODE (ret))
3369                     ret = gen_lowpart (GET_MODE (target), ret);
3370
3371                   ret = plus_constant (GET_MODE (ret), ret, INTVAL (len_rtx));
3372                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3373                   gcc_assert (ret);
3374
3375                   return target;
3376                 }
3377             }
3378         }
3379
3380       return expand_movstr (dst, src, target, /*endp=*/2);
3381     }
3382 }
3383
3384 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3385    bytes from constant string DATA + OFFSET and return it as target
3386    constant.  */
3387
3388 rtx
3389 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3390                           enum machine_mode mode)
3391 {
3392   const char *str = (const char *) data;
3393
3394   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3395     return const0_rtx;
3396
3397   return c_readstr (str + offset, mode);
3398 }
3399
3400 /* Expand expression EXP, which is a call to the strncpy builtin.  Return
3401    NULL_RTX if we failed the caller should emit a normal call.  */
3402
3403 static rtx
3404 expand_builtin_strncpy (tree exp, rtx target)
3405 {
3406   location_t loc = EXPR_LOCATION (exp);
3407
3408   if (validate_arglist (exp,
3409                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3410     {
3411       tree dest = CALL_EXPR_ARG (exp, 0);
3412       tree src = CALL_EXPR_ARG (exp, 1);
3413       tree len = CALL_EXPR_ARG (exp, 2);
3414       tree slen = c_strlen (src, 1);
3415
3416       /* We must be passed a constant len and src parameter.  */
3417       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3418         return NULL_RTX;
3419
3420       slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3421
3422       /* We're required to pad with trailing zeros if the requested
3423          len is greater than strlen(s2)+1.  In that case try to
3424          use store_by_pieces, if it fails, punt.  */
3425       if (tree_int_cst_lt (slen, len))
3426         {
3427           unsigned int dest_align = get_pointer_alignment (dest);
3428           const char *p = c_getstr (src);
3429           rtx dest_mem;
3430
3431           if (!p || dest_align == 0 || !host_integerp (len, 1)
3432               || !can_store_by_pieces (tree_low_cst (len, 1),
3433                                        builtin_strncpy_read_str,
3434                                        CONST_CAST (char *, p),
3435                                        dest_align, false))
3436             return NULL_RTX;
3437
3438           dest_mem = get_memory_rtx (dest, len);
3439           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3440                            builtin_strncpy_read_str,
3441                            CONST_CAST (char *, p), dest_align, false, 0);
3442           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3443           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3444           return dest_mem;
3445         }
3446     }
3447   return NULL_RTX;
3448 }
3449
3450 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3451    bytes from constant string DATA + OFFSET and return it as target
3452    constant.  */
3453
3454 rtx
3455 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3456                          enum machine_mode mode)
3457 {
3458   const char *c = (const char *) data;
3459   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3460
3461   memset (p, *c, GET_MODE_SIZE (mode));
3462
3463   return c_readstr (p, mode);
3464 }
3465
3466 /* Callback routine for store_by_pieces.  Return the RTL of a register
3467    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3468    char value given in the RTL register data.  For example, if mode is
3469    4 bytes wide, return the RTL for 0x01010101*data.  */
3470
3471 static rtx
3472 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3473                         enum machine_mode mode)
3474 {
3475   rtx target, coeff;
3476   size_t size;
3477   char *p;
3478
3479   size = GET_MODE_SIZE (mode);
3480   if (size == 1)
3481     return (rtx) data;
3482
3483   p = XALLOCAVEC (char, size);
3484   memset (p, 1, size);
3485   coeff = c_readstr (p, mode);
3486
3487   target = convert_to_mode (mode, (rtx) data, 1);
3488   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3489   return force_reg (mode, target);
3490 }
3491
3492 /* Expand expression EXP, which is a call to the memset builtin.  Return
3493    NULL_RTX if we failed the caller should emit a normal call, otherwise
3494    try to get the result in TARGET, if convenient (and in mode MODE if that's
3495    convenient).  */
3496
3497 static rtx
3498 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3499 {
3500   if (!validate_arglist (exp,
3501                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3502     return NULL_RTX;
3503   else
3504     {
3505       tree dest = CALL_EXPR_ARG (exp, 0);
3506       tree val = CALL_EXPR_ARG (exp, 1);
3507       tree len = CALL_EXPR_ARG (exp, 2);
3508       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3509     }
3510 }
3511
3512 /* Helper function to do the actual work for expand_builtin_memset.  The
3513    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3514    so that this can also be called without constructing an actual CALL_EXPR.
3515    The other arguments and return value are the same as for
3516    expand_builtin_memset.  */
3517
3518 static rtx
3519 expand_builtin_memset_args (tree dest, tree val, tree len,
3520                             rtx target, enum machine_mode mode, tree orig_exp)
3521 {
3522   tree fndecl, fn;
3523   enum built_in_function fcode;
3524   enum machine_mode val_mode;
3525   char c;
3526   unsigned int dest_align;
3527   rtx dest_mem, dest_addr, len_rtx;
3528   HOST_WIDE_INT expected_size = -1;
3529   unsigned int expected_align = 0;
3530
3531   dest_align = get_pointer_alignment (dest);
3532
3533   /* If DEST is not a pointer type, don't do this operation in-line.  */
3534   if (dest_align == 0)
3535     return NULL_RTX;
3536
3537   if (currently_expanding_gimple_stmt)
3538     stringop_block_profile (currently_expanding_gimple_stmt,
3539                             &expected_align, &expected_size);
3540
3541   if (expected_align < dest_align)
3542     expected_align = dest_align;
3543
3544   /* If the LEN parameter is zero, return DEST.  */
3545   if (integer_zerop (len))
3546     {
3547       /* Evaluate and ignore VAL in case it has side-effects.  */
3548       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3549       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3550     }
3551
3552   /* Stabilize the arguments in case we fail.  */
3553   dest = builtin_save_expr (dest);
3554   val = builtin_save_expr (val);
3555   len = builtin_save_expr (len);
3556
3557   len_rtx = expand_normal (len);
3558   dest_mem = get_memory_rtx (dest, len);
3559   val_mode = TYPE_MODE (unsigned_char_type_node);
3560
3561   if (TREE_CODE (val) != INTEGER_CST)
3562     {
3563       rtx val_rtx;
3564
3565       val_rtx = expand_normal (val);
3566       val_rtx = convert_to_mode (val_mode, val_rtx, 0);
3567
3568       /* Assume that we can memset by pieces if we can store
3569        * the coefficients by pieces (in the required modes).
3570        * We can't pass builtin_memset_gen_str as that emits RTL.  */
3571       c = 1;
3572       if (host_integerp (len, 1)
3573           && can_store_by_pieces (tree_low_cst (len, 1),
3574                                   builtin_memset_read_str, &c, dest_align,
3575                                   true))
3576         {
3577           val_rtx = force_reg (val_mode, val_rtx);
3578           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3579                            builtin_memset_gen_str, val_rtx, dest_align,
3580                            true, 0);
3581         }
3582       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3583                                         dest_align, expected_align,
3584                                         expected_size))
3585         goto do_libcall;
3586
3587       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3588       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3589       return dest_mem;
3590     }
3591
3592   if (target_char_cast (val, &c))
3593     goto do_libcall;
3594
3595   if (c)
3596     {
3597       if (host_integerp (len, 1)
3598           && can_store_by_pieces (tree_low_cst (len, 1),
3599                                   builtin_memset_read_str, &c, dest_align,
3600                                   true))
3601         store_by_pieces (dest_mem, tree_low_cst (len, 1),
3602                          builtin_memset_read_str, &c, dest_align, true, 0);
3603       else if (!set_storage_via_setmem (dest_mem, len_rtx,
3604                                         gen_int_mode (c, val_mode),
3605                                         dest_align, expected_align,
3606                                         expected_size))
3607         goto do_libcall;
3608
3609       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3610       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3611       return dest_mem;
3612     }
3613
3614   set_mem_align (dest_mem, dest_align);
3615   dest_addr = clear_storage_hints (dest_mem, len_rtx,
3616                                    CALL_EXPR_TAILCALL (orig_exp)
3617                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3618                                    expected_align, expected_size);
3619
3620   if (dest_addr == 0)
3621     {
3622       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3623       dest_addr = convert_memory_address (ptr_mode, dest_addr);
3624     }
3625
3626   return dest_addr;
3627
3628  do_libcall:
3629   fndecl = get_callee_fndecl (orig_exp);
3630   fcode = DECL_FUNCTION_CODE (fndecl);
3631   if (fcode == BUILT_IN_MEMSET)
3632     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
3633                                 dest, val, len);
3634   else if (fcode == BUILT_IN_BZERO)
3635     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2,
3636                                 dest, len);
3637   else
3638     gcc_unreachable ();
3639   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3640   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3641   return expand_call (fn, target, target == const0_rtx);
3642 }
3643
3644 /* Expand expression EXP, which is a call to the bzero builtin.  Return
3645    NULL_RTX if we failed the caller should emit a normal call.  */
3646
3647 static rtx
3648 expand_builtin_bzero (tree exp)
3649 {
3650   tree dest, size;
3651   location_t loc = EXPR_LOCATION (exp);
3652
3653   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3654     return NULL_RTX;
3655
3656   dest = CALL_EXPR_ARG (exp, 0);
3657   size = CALL_EXPR_ARG (exp, 1);
3658
3659   /* New argument list transforming bzero(ptr x, int y) to
3660      memset(ptr x, int 0, size_t y).   This is done this way
3661      so that if it isn't expanded inline, we fallback to
3662      calling bzero instead of memset.  */
3663
3664   return expand_builtin_memset_args (dest, integer_zero_node,
3665                                      fold_convert_loc (loc,
3666                                                        size_type_node, size),
3667                                      const0_rtx, VOIDmode, exp);
3668 }
3669
3670 /* Expand expression EXP, which is a call to the memcmp built-in function.
3671    Return NULL_RTX if we failed and the caller should emit a normal call,
3672    otherwise try to get the result in TARGET, if convenient (and in mode
3673    MODE, if that's convenient).  */
3674
3675 static rtx
3676 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3677                        ATTRIBUTE_UNUSED enum machine_mode mode)
3678 {
3679   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3680
3681   if (!validate_arglist (exp,
3682                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3683     return NULL_RTX;
3684
3685   /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
3686      implementing memcmp because it will stop if it encounters two
3687      zero bytes.  */
3688 #if defined HAVE_cmpmemsi
3689   {
3690     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3691     rtx result;
3692     rtx insn;
3693     tree arg1 = CALL_EXPR_ARG (exp, 0);
3694     tree arg2 = CALL_EXPR_ARG (exp, 1);
3695     tree len = CALL_EXPR_ARG (exp, 2);
3696
3697     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3698     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3699     enum machine_mode insn_mode;
3700
3701     if (HAVE_cmpmemsi)
3702       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3703     else
3704       return NULL_RTX;
3705
3706     /* If we don't have POINTER_TYPE, call the function.  */
3707     if (arg1_align == 0 || arg2_align == 0)
3708       return NULL_RTX;
3709
3710     /* Make a place to write the result of the instruction.  */
3711     result = target;
3712     if (! (result != 0
3713            && REG_P (result) && GET_MODE (result) == insn_mode
3714            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3715       result = gen_reg_rtx (insn_mode);
3716
3717     arg1_rtx = get_memory_rtx (arg1, len);
3718     arg2_rtx = get_memory_rtx (arg2, len);
3719     arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3720
3721     /* Set MEM_SIZE as appropriate.  */
3722     if (CONST_INT_P (arg3_rtx))
3723       {
3724         set_mem_size (arg1_rtx, INTVAL (arg3_rtx));
3725         set_mem_size (arg2_rtx, INTVAL (arg3_rtx));
3726       }
3727
3728     if (HAVE_cmpmemsi)
3729       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3730                            GEN_INT (MIN (arg1_align, arg2_align)));
3731     else
3732       gcc_unreachable ();
3733
3734     if (insn)
3735       emit_insn (insn);
3736     else
3737       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3738                                TYPE_MODE (integer_type_node), 3,
3739                                XEXP (arg1_rtx, 0), Pmode,
3740                                XEXP (arg2_rtx, 0), Pmode,
3741                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3742                                                 TYPE_UNSIGNED (sizetype)),
3743                                TYPE_MODE (sizetype));
3744
3745     /* Return the value in the proper mode for this function.  */
3746     mode = TYPE_MODE (TREE_TYPE (exp));
3747     if (GET_MODE (result) == mode)
3748       return result;
3749     else if (target != 0)
3750       {
3751         convert_move (target, result, 0);
3752         return target;
3753       }
3754     else
3755       return convert_to_mode (mode, result, 0);
3756   }
3757 #endif /* HAVE_cmpmemsi.  */
3758
3759   return NULL_RTX;
3760 }
3761
3762 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
3763    if we failed the caller should emit a normal call, otherwise try to get
3764    the result in TARGET, if convenient.  */
3765
3766 static rtx
3767 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3768 {
3769   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3770     return NULL_RTX;
3771
3772 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3773   if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing
3774       || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing)
3775     {
3776       rtx arg1_rtx, arg2_rtx;
3777       rtx result, insn = NULL_RTX;
3778       tree fndecl, fn;
3779       tree arg1 = CALL_EXPR_ARG (exp, 0);
3780       tree arg2 = CALL_EXPR_ARG (exp, 1);
3781
3782       unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3783       unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3784
3785       /* If we don't have POINTER_TYPE, call the function.  */
3786       if (arg1_align == 0 || arg2_align == 0)
3787         return NULL_RTX;
3788
3789       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3790       arg1 = builtin_save_expr (arg1);
3791       arg2 = builtin_save_expr (arg2);
3792
3793       arg1_rtx = get_memory_rtx (arg1, NULL);
3794       arg2_rtx = get_memory_rtx (arg2, NULL);
3795
3796 #ifdef HAVE_cmpstrsi
3797       /* Try to call cmpstrsi.  */
3798       if (HAVE_cmpstrsi)
3799         {
3800           enum machine_mode insn_mode
3801             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3802
3803           /* Make a place to write the result of the instruction.  */
3804           result = target;
3805           if (! (result != 0
3806                  && REG_P (result) && GET_MODE (result) == insn_mode
3807                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3808             result = gen_reg_rtx (insn_mode);
3809
3810           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3811                                GEN_INT (MIN (arg1_align, arg2_align)));
3812         }
3813 #endif
3814 #ifdef HAVE_cmpstrnsi
3815       /* Try to determine at least one length and call cmpstrnsi.  */
3816       if (!insn && HAVE_cmpstrnsi)
3817         {
3818           tree len;
3819           rtx arg3_rtx;
3820
3821           enum machine_mode insn_mode
3822             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3823           tree len1 = c_strlen (arg1, 1);
3824           tree len2 = c_strlen (arg2, 1);
3825
3826           if (len1)
3827             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3828           if (len2)
3829             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3830
3831           /* If we don't have a constant length for the first, use the length
3832              of the second, if we know it.  We don't require a constant for
3833              this case; some cost analysis could be done if both are available
3834              but neither is constant.  For now, assume they're equally cheap,
3835              unless one has side effects.  If both strings have constant lengths,
3836              use the smaller.  */
3837
3838           if (!len1)
3839             len = len2;
3840           else if (!len2)
3841             len = len1;
3842           else if (TREE_SIDE_EFFECTS (len1))
3843             len = len2;
3844           else if (TREE_SIDE_EFFECTS (len2))
3845             len = len1;
3846           else if (TREE_CODE (len1) != INTEGER_CST)
3847             len = len2;
3848           else if (TREE_CODE (len2) != INTEGER_CST)
3849             len = len1;
3850           else if (tree_int_cst_lt (len1, len2))
3851             len = len1;
3852           else
3853             len = len2;
3854
3855           /* If both arguments have side effects, we cannot optimize.  */
3856           if (!len || TREE_SIDE_EFFECTS (len))
3857             goto do_libcall;
3858
3859           arg3_rtx = expand_normal (len);
3860
3861           /* Make a place to write the result of the instruction.  */
3862           result = target;
3863           if (! (result != 0
3864                  && REG_P (result) && GET_MODE (result) == insn_mode
3865                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3866             result = gen_reg_rtx (insn_mode);
3867
3868           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3869                                 GEN_INT (MIN (arg1_align, arg2_align)));
3870         }
3871 #endif
3872
3873       if (insn)
3874         {
3875           enum machine_mode mode;
3876           emit_insn (insn);
3877
3878           /* Return the value in the proper mode for this function.  */
3879           mode = TYPE_MODE (TREE_TYPE (exp));
3880           if (GET_MODE (result) == mode)
3881             return result;
3882           if (target == 0)
3883             return convert_to_mode (mode, result, 0);
3884           convert_move (target, result, 0);
3885           return target;
3886         }
3887
3888       /* Expand the library call ourselves using a stabilized argument
3889          list to avoid re-evaluating the function's arguments twice.  */
3890 #ifdef HAVE_cmpstrnsi
3891     do_libcall:
3892 #endif
3893       fndecl = get_callee_fndecl (exp);
3894       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
3895       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3896       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3897       return expand_call (fn, target, target == const0_rtx);
3898     }
3899 #endif
3900   return NULL_RTX;
3901 }
3902
3903 /* Expand expression EXP, which is a call to the strncmp builtin. Return
3904    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
3905    the result in TARGET, if convenient.  */
3906
3907 static rtx
3908 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3909                         ATTRIBUTE_UNUSED enum machine_mode mode)
3910 {
3911   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3912
3913   if (!validate_arglist (exp,
3914                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3915     return NULL_RTX;
3916
3917   /* If c_strlen can determine an expression for one of the string
3918      lengths, and it doesn't have side effects, then emit cmpstrnsi
3919      using length MIN(strlen(string)+1, arg3).  */
3920 #ifdef HAVE_cmpstrnsi
3921   if (HAVE_cmpstrnsi)
3922   {
3923     tree len, len1, len2;
3924     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3925     rtx result, insn;
3926     tree fndecl, fn;
3927     tree arg1 = CALL_EXPR_ARG (exp, 0);
3928     tree arg2 = CALL_EXPR_ARG (exp, 1);
3929     tree arg3 = CALL_EXPR_ARG (exp, 2);
3930
3931     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3932     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3933     enum machine_mode insn_mode
3934       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3935
3936     len1 = c_strlen (arg1, 1);
3937     len2 = c_strlen (arg2, 1);
3938
3939     if (len1)
3940       len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
3941     if (len2)
3942       len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
3943
3944     /* If we don't have a constant length for the first, use the length
3945        of the second, if we know it.  We don't require a constant for
3946        this case; some cost analysis could be done if both are available
3947        but neither is constant.  For now, assume they're equally cheap,
3948        unless one has side effects.  If both strings have constant lengths,
3949        use the smaller.  */
3950
3951     if (!len1)
3952       len = len2;
3953     else if (!len2)
3954       len = len1;
3955     else if (TREE_SIDE_EFFECTS (len1))
3956       len = len2;
3957     else if (TREE_SIDE_EFFECTS (len2))
3958       len = len1;
3959     else if (TREE_CODE (len1) != INTEGER_CST)
3960       len = len2;
3961     else if (TREE_CODE (len2) != INTEGER_CST)
3962       len = len1;
3963     else if (tree_int_cst_lt (len1, len2))
3964       len = len1;
3965     else
3966       len = len2;
3967
3968     /* If both arguments have side effects, we cannot optimize.  */
3969     if (!len || TREE_SIDE_EFFECTS (len))
3970       return NULL_RTX;
3971
3972     /* The actual new length parameter is MIN(len,arg3).  */
3973     len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
3974                        fold_convert_loc (loc, TREE_TYPE (len), arg3));
3975
3976     /* If we don't have POINTER_TYPE, call the function.  */
3977     if (arg1_align == 0 || arg2_align == 0)
3978       return NULL_RTX;
3979
3980     /* Make a place to write the result of the instruction.  */
3981     result = target;
3982     if (! (result != 0
3983            && REG_P (result) && GET_MODE (result) == insn_mode
3984            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3985       result = gen_reg_rtx (insn_mode);
3986
3987     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
3988     arg1 = builtin_save_expr (arg1);
3989     arg2 = builtin_save_expr (arg2);
3990     len = builtin_save_expr (len);
3991
3992     arg1_rtx = get_memory_rtx (arg1, len);
3993     arg2_rtx = get_memory_rtx (arg2, len);
3994     arg3_rtx = expand_normal (len);
3995     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3996                           GEN_INT (MIN (arg1_align, arg2_align)));
3997     if (insn)
3998       {
3999         emit_insn (insn);
4000
4001         /* Return the value in the proper mode for this function.  */
4002         mode = TYPE_MODE (TREE_TYPE (exp));
4003         if (GET_MODE (result) == mode)
4004           return result;
4005         if (target == 0)
4006           return convert_to_mode (mode, result, 0);
4007         convert_move (target, result, 0);
4008         return target;
4009       }
4010
4011     /* Expand the library call ourselves using a stabilized argument
4012        list to avoid re-evaluating the function's arguments twice.  */
4013     fndecl = get_callee_fndecl (exp);
4014     fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
4015                                 arg1, arg2, len);
4016     gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4017     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4018     return expand_call (fn, target, target == const0_rtx);
4019   }
4020 #endif
4021   return NULL_RTX;
4022 }
4023
4024 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4025    if that's convenient.  */
4026
4027 rtx
4028 expand_builtin_saveregs (void)
4029 {
4030   rtx val, seq;
4031
4032   /* Don't do __builtin_saveregs more than once in a function.
4033      Save the result of the first call and reuse it.  */
4034   if (saveregs_value != 0)
4035     return saveregs_value;
4036
4037   /* When this function is called, it means that registers must be
4038      saved on entry to this function.  So we migrate the call to the
4039      first insn of this function.  */
4040
4041   start_sequence ();
4042
4043   /* Do whatever the machine needs done in this case.  */
4044   val = targetm.calls.expand_builtin_saveregs ();
4045
4046   seq = get_insns ();
4047   end_sequence ();
4048
4049   saveregs_value = val;
4050
4051   /* Put the insns after the NOTE that starts the function.  If this
4052      is inside a start_sequence, make the outer-level insn chain current, so
4053      the code is placed at the start of the function.  */
4054   push_topmost_sequence ();
4055   emit_insn_after (seq, entry_of_function ());
4056   pop_topmost_sequence ();
4057
4058   return val;
4059 }
4060
4061 /* Expand a call to __builtin_next_arg.  */
4062
4063 static rtx
4064 expand_builtin_next_arg (void)
4065 {
4066   /* Checking arguments is already done in fold_builtin_next_arg
4067      that must be called before this function.  */
4068   return expand_binop (ptr_mode, add_optab,
4069                        crtl->args.internal_arg_pointer,
4070                        crtl->args.arg_offset_rtx,
4071                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4072 }
4073
4074 /* Make it easier for the backends by protecting the valist argument
4075    from multiple evaluations.  */
4076
4077 static tree
4078 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4079 {
4080   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4081
4082   /* The current way of determining the type of valist is completely
4083      bogus.  We should have the information on the va builtin instead.  */
4084   if (!vatype)
4085     vatype = targetm.fn_abi_va_list (cfun->decl);
4086
4087   if (TREE_CODE (vatype) == ARRAY_TYPE)
4088     {
4089       if (TREE_SIDE_EFFECTS (valist))
4090         valist = save_expr (valist);
4091
4092       /* For this case, the backends will be expecting a pointer to
4093          vatype, but it's possible we've actually been given an array
4094          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4095          So fix it.  */
4096       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4097         {
4098           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4099           valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4100         }
4101     }
4102   else
4103     {
4104       tree pt = build_pointer_type (vatype);
4105
4106       if (! needs_lvalue)
4107         {
4108           if (! TREE_SIDE_EFFECTS (valist))
4109             return valist;
4110
4111           valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4112           TREE_SIDE_EFFECTS (valist) = 1;
4113         }
4114
4115       if (TREE_SIDE_EFFECTS (valist))
4116         valist = save_expr (valist);
4117       valist = fold_build2_loc (loc, MEM_REF,
4118                                 vatype, valist, build_int_cst (pt, 0));
4119     }
4120
4121   return valist;
4122 }
4123
4124 /* The "standard" definition of va_list is void*.  */
4125
4126 tree
4127 std_build_builtin_va_list (void)
4128 {
4129   return ptr_type_node;
4130 }
4131
4132 /* The "standard" abi va_list is va_list_type_node.  */
4133
4134 tree
4135 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4136 {
4137   return va_list_type_node;
4138 }
4139
4140 /* The "standard" type of va_list is va_list_type_node.  */
4141
4142 tree
4143 std_canonical_va_list_type (tree type)
4144 {
4145   tree wtype, htype;
4146
4147   if (INDIRECT_REF_P (type))
4148     type = TREE_TYPE (type);
4149   else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4150     type = TREE_TYPE (type);
4151   wtype = va_list_type_node;
4152   htype = type;
4153   /* Treat structure va_list types.  */
4154   if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4155     htype = TREE_TYPE (htype);
4156   else if (TREE_CODE (wtype) == ARRAY_TYPE)
4157     {
4158       /* If va_list is an array type, the argument may have decayed
4159          to a pointer type, e.g. by being passed to another function.
4160          In that case, unwrap both types so that we can compare the
4161          underlying records.  */
4162       if (TREE_CODE (htype) == ARRAY_TYPE
4163           || POINTER_TYPE_P (htype))
4164         {
4165           wtype = TREE_TYPE (wtype);
4166           htype = TREE_TYPE (htype);
4167         }
4168     }
4169   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4170     return va_list_type_node;
4171
4172   return NULL_TREE;
4173 }
4174
4175 /* The "standard" implementation of va_start: just assign `nextarg' to
4176    the variable.  */
4177
4178 void
4179 std_expand_builtin_va_start (tree valist, rtx nextarg)
4180 {
4181   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4182   convert_move (va_r, nextarg, 0);
4183 }
4184
4185 /* Expand EXP, a call to __builtin_va_start.  */
4186
4187 static rtx
4188 expand_builtin_va_start (tree exp)
4189 {
4190   rtx nextarg;
4191   tree valist;
4192   location_t loc = EXPR_LOCATION (exp);
4193
4194   if (call_expr_nargs (exp) < 2)
4195     {
4196       error_at (loc, "too few arguments to function %<va_start%>");
4197       return const0_rtx;
4198     }
4199
4200   if (fold_builtin_next_arg (exp, true))
4201     return const0_rtx;
4202
4203   nextarg = expand_builtin_next_arg ();
4204   valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4205
4206   if (targetm.expand_builtin_va_start)
4207     targetm.expand_builtin_va_start (valist, nextarg);
4208   else
4209     std_expand_builtin_va_start (valist, nextarg);
4210
4211   return const0_rtx;
4212 }
4213
4214 /* The "standard" implementation of va_arg: read the value from the
4215    current (padded) address and increment by the (padded) size.  */
4216
4217 tree
4218 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4219                           gimple_seq *post_p)
4220 {
4221   tree addr, t, type_size, rounded_size, valist_tmp;
4222   unsigned HOST_WIDE_INT align, boundary;
4223   bool indirect;
4224
4225 #ifdef ARGS_GROW_DOWNWARD
4226   /* All of the alignment and movement below is for args-grow-up machines.
4227      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4228      implement their own specialized gimplify_va_arg_expr routines.  */
4229   gcc_unreachable ();
4230 #endif
4231
4232   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4233   if (indirect)
4234     type = build_pointer_type (type);
4235
4236   align = PARM_BOUNDARY / BITS_PER_UNIT;
4237   boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
4238
4239   /* When we align parameter on stack for caller, if the parameter
4240      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4241      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4242      here with caller.  */
4243   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4244     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4245
4246   boundary /= BITS_PER_UNIT;
4247
4248   /* Hoist the valist value into a temporary for the moment.  */
4249   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4250
4251   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4252      requires greater alignment, we must perform dynamic alignment.  */
4253   if (boundary > align
4254       && !integer_zerop (TYPE_SIZE (type)))
4255     {
4256       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4257                   fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
4258       gimplify_and_add (t, pre_p);
4259
4260       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4261                   fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
4262                                valist_tmp,
4263                                build_int_cst (TREE_TYPE (valist), -boundary)));
4264       gimplify_and_add (t, pre_p);
4265     }
4266   else
4267     boundary = align;
4268
4269   /* If the actual alignment is less than the alignment of the type,
4270      adjust the type accordingly so that we don't assume strict alignment
4271      when dereferencing the pointer.  */
4272   boundary *= BITS_PER_UNIT;
4273   if (boundary < TYPE_ALIGN (type))
4274     {
4275       type = build_variant_type_copy (type);
4276       TYPE_ALIGN (type) = boundary;
4277     }
4278
4279   /* Compute the rounded size of the type.  */
4280   type_size = size_in_bytes (type);
4281   rounded_size = round_up (type_size, align);
4282
4283   /* Reduce rounded_size so it's sharable with the postqueue.  */
4284   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4285
4286   /* Get AP.  */
4287   addr = valist_tmp;
4288   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4289     {
4290       /* Small args are padded downward.  */
4291       t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4292                        rounded_size, size_int (align));
4293       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4294                        size_binop (MINUS_EXPR, rounded_size, type_size));
4295       addr = fold_build_pointer_plus (addr, t);
4296     }
4297
4298   /* Compute new value for AP.  */
4299   t = fold_build_pointer_plus (valist_tmp, rounded_size);
4300   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4301   gimplify_and_add (t, pre_p);
4302
4303   addr = fold_convert (build_pointer_type (type), addr);
4304
4305   if (indirect)
4306     addr = build_va_arg_indirect_ref (addr);
4307
4308   return build_va_arg_indirect_ref (addr);
4309 }
4310
4311 /* Build an indirect-ref expression over the given TREE, which represents a
4312    piece of a va_arg() expansion.  */
4313 tree
4314 build_va_arg_indirect_ref (tree addr)
4315 {
4316   addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
4317
4318   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4319     mf_mark (addr);
4320
4321   return addr;
4322 }
4323
4324 /* Return a dummy expression of type TYPE in order to keep going after an
4325    error.  */
4326
4327 static tree
4328 dummy_object (tree type)
4329 {
4330   tree t = build_int_cst (build_pointer_type (type), 0);
4331   return build2 (MEM_REF, type, t, t);
4332 }
4333
4334 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4335    builtin function, but a very special sort of operator.  */
4336
4337 enum gimplify_status
4338 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4339 {
4340   tree promoted_type, have_va_type;
4341   tree valist = TREE_OPERAND (*expr_p, 0);
4342   tree type = TREE_TYPE (*expr_p);
4343   tree t;
4344   location_t loc = EXPR_LOCATION (*expr_p);
4345
4346   /* Verify that valist is of the proper type.  */
4347   have_va_type = TREE_TYPE (valist);
4348   if (have_va_type == error_mark_node)
4349     return GS_ERROR;
4350   have_va_type = targetm.canonical_va_list_type (have_va_type);
4351
4352   if (have_va_type == NULL_TREE)
4353     {
4354       error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4355       return GS_ERROR;
4356     }
4357
4358   /* Generate a diagnostic for requesting data of a type that cannot
4359      be passed through `...' due to type promotion at the call site.  */
4360   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4361            != type)
4362     {
4363       static bool gave_help;
4364       bool warned;
4365
4366       /* Unfortunately, this is merely undefined, rather than a constraint
4367          violation, so we cannot make this an error.  If this call is never
4368          executed, the program is still strictly conforming.  */
4369       warned = warning_at (loc, 0,
4370                            "%qT is promoted to %qT when passed through %<...%>",
4371                            type, promoted_type);
4372       if (!gave_help && warned)
4373         {
4374           gave_help = true;
4375           inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4376                   promoted_type, type);
4377         }
4378
4379       /* We can, however, treat "undefined" any way we please.
4380          Call abort to encourage the user to fix the program.  */
4381       if (warned)
4382         inform (loc, "if this code is reached, the program will abort");
4383       /* Before the abort, allow the evaluation of the va_list
4384          expression to exit or longjmp.  */
4385       gimplify_and_add (valist, pre_p);
4386       t = build_call_expr_loc (loc,
4387                                builtin_decl_implicit (BUILT_IN_TRAP), 0);
4388       gimplify_and_add (t, pre_p);
4389
4390       /* This is dead code, but go ahead and finish so that the
4391          mode of the result comes out right.  */
4392       *expr_p = dummy_object (type);
4393       return GS_ALL_DONE;
4394     }
4395   else
4396     {
4397       /* Make it easier for the backends by protecting the valist argument
4398          from multiple evaluations.  */
4399       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4400         {
4401           /* For this case, the backends will be expecting a pointer to
4402              TREE_TYPE (abi), but it's possible we've
4403              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4404              So fix it.  */
4405           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4406             {
4407               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4408               valist = fold_convert_loc (loc, p1,
4409                                          build_fold_addr_expr_loc (loc, valist));
4410             }
4411
4412           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4413         }
4414       else
4415         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4416
4417       if (!targetm.gimplify_va_arg_expr)
4418         /* FIXME: Once most targets are converted we should merely
4419            assert this is non-null.  */
4420         return GS_ALL_DONE;
4421
4422       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4423       return GS_OK;
4424     }
4425 }
4426
4427 /* Expand EXP, a call to __builtin_va_end.  */
4428
4429 static rtx
4430 expand_builtin_va_end (tree exp)
4431 {
4432   tree valist = CALL_EXPR_ARG (exp, 0);
4433
4434   /* Evaluate for side effects, if needed.  I hate macros that don't
4435      do that.  */
4436   if (TREE_SIDE_EFFECTS (valist))
4437     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4438
4439   return const0_rtx;
4440 }
4441
4442 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
4443    builtin rather than just as an assignment in stdarg.h because of the
4444    nastiness of array-type va_list types.  */
4445
4446 static rtx
4447 expand_builtin_va_copy (tree exp)
4448 {
4449   tree dst, src, t;
4450   location_t loc = EXPR_LOCATION (exp);
4451
4452   dst = CALL_EXPR_ARG (exp, 0);
4453   src = CALL_EXPR_ARG (exp, 1);
4454
4455   dst = stabilize_va_list_loc (loc, dst, 1);
4456   src = stabilize_va_list_loc (loc, src, 0);
4457
4458   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4459
4460   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4461     {
4462       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4463       TREE_SIDE_EFFECTS (t) = 1;
4464       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4465     }
4466   else
4467     {
4468       rtx dstb, srcb, size;
4469
4470       /* Evaluate to pointers.  */
4471       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4472       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4473       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4474                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
4475
4476       dstb = convert_memory_address (Pmode, dstb);
4477       srcb = convert_memory_address (Pmode, srcb);
4478
4479       /* "Dereference" to BLKmode memories.  */
4480       dstb = gen_rtx_MEM (BLKmode, dstb);
4481       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4482       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4483       srcb = gen_rtx_MEM (BLKmode, srcb);
4484       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4485       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4486
4487       /* Copy.  */
4488       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4489     }
4490
4491   return const0_rtx;
4492 }
4493
4494 /* Expand a call to one of the builtin functions __builtin_frame_address or
4495    __builtin_return_address.  */
4496
4497 static rtx
4498 expand_builtin_frame_address (tree fndecl, tree exp)
4499 {
4500   /* The argument must be a nonnegative integer constant.
4501      It counts the number of frames to scan up the stack.
4502      The value is the return address saved in that frame.  */
4503   if (call_expr_nargs (exp) == 0)
4504     /* Warning about missing arg was already issued.  */
4505     return const0_rtx;
4506   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4507     {
4508       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4509         error ("invalid argument to %<__builtin_frame_address%>");
4510       else
4511         error ("invalid argument to %<__builtin_return_address%>");
4512       return const0_rtx;
4513     }
4514   else
4515     {
4516       rtx tem
4517         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4518                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4519
4520       /* Some ports cannot access arbitrary stack frames.  */
4521       if (tem == NULL)
4522         {
4523           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4524             warning (0, "unsupported argument to %<__builtin_frame_address%>");
4525           else
4526             warning (0, "unsupported argument to %<__builtin_return_address%>");
4527           return const0_rtx;
4528         }
4529
4530       /* For __builtin_frame_address, return what we've got.  */
4531       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4532         return tem;
4533
4534       if (!REG_P (tem)
4535           && ! CONSTANT_P (tem))
4536         tem = copy_addr_to_reg (tem);
4537       return tem;
4538     }
4539 }
4540
4541 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if we
4542    failed and the caller should emit a normal call.  CANNOT_ACCUMULATE
4543    is the same as for allocate_dynamic_stack_space.  */
4544
4545 static rtx
4546 expand_builtin_alloca (tree exp, bool cannot_accumulate)
4547 {
4548   rtx op0;
4549   rtx result;
4550   bool valid_arglist;
4551   unsigned int align;
4552   bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
4553                             == BUILT_IN_ALLOCA_WITH_ALIGN);
4554
4555   /* Emit normal call if we use mudflap.  */
4556   if (flag_mudflap)
4557     return NULL_RTX;
4558
4559   valid_arglist
4560     = (alloca_with_align
4561        ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
4562        : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE));
4563
4564   if (!valid_arglist)
4565     return NULL_RTX;
4566
4567   /* Compute the argument.  */
4568   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4569
4570   /* Compute the alignment.  */
4571   align = (alloca_with_align
4572            ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
4573            : BIGGEST_ALIGNMENT);
4574
4575   /* Allocate the desired space.  */
4576   result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate);
4577   result = convert_memory_address (ptr_mode, result);
4578
4579   return result;
4580 }
4581
4582 /* Expand a call to bswap builtin in EXP.
4583    Return NULL_RTX if a normal call should be emitted rather than expanding the
4584    function in-line.  If convenient, the result should be placed in TARGET.
4585    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4586
4587 static rtx
4588 expand_builtin_bswap (enum machine_mode target_mode, tree exp, rtx target,
4589                       rtx subtarget)
4590 {
4591   tree arg;
4592   rtx op0;
4593
4594   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4595     return NULL_RTX;
4596
4597   arg = CALL_EXPR_ARG (exp, 0);
4598   op0 = expand_expr (arg,
4599                      subtarget && GET_MODE (subtarget) == target_mode
4600                      ? subtarget : NULL_RTX,
4601                      target_mode, EXPAND_NORMAL);
4602   if (GET_MODE (op0) != target_mode)
4603     op0 = convert_to_mode (target_mode, op0, 1);
4604
4605   target = expand_unop (target_mode, bswap_optab, op0, target, 1);
4606
4607   gcc_assert (target);
4608
4609   return convert_to_mode (target_mode, target, 1);
4610 }
4611
4612 /* Expand a call to a unary builtin in EXP.
4613    Return NULL_RTX if a normal call should be emitted rather than expanding the
4614    function in-line.  If convenient, the result should be placed in TARGET.
4615    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4616
4617 static rtx
4618 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4619                      rtx subtarget, optab op_optab)
4620 {
4621   rtx op0;
4622
4623   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4624     return NULL_RTX;
4625
4626   /* Compute the argument.  */
4627   op0 = expand_expr (CALL_EXPR_ARG (exp, 0),
4628                      (subtarget
4629                       && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))
4630                           == GET_MODE (subtarget))) ? subtarget : NULL_RTX,
4631                      VOIDmode, EXPAND_NORMAL);
4632   /* Compute op, into TARGET if possible.
4633      Set TARGET to wherever the result comes back.  */
4634   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4635                         op_optab, op0, target, op_optab != clrsb_optab);
4636   gcc_assert (target);
4637
4638   return convert_to_mode (target_mode, target, 0);
4639 }
4640
4641 /* Expand a call to __builtin_expect.  We just return our argument
4642    as the builtin_expect semantic should've been already executed by
4643    tree branch prediction pass. */
4644
4645 static rtx
4646 expand_builtin_expect (tree exp, rtx target)
4647 {
4648   tree arg;
4649
4650   if (call_expr_nargs (exp) < 2)
4651     return const0_rtx;
4652   arg = CALL_EXPR_ARG (exp, 0);
4653
4654   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4655   /* When guessing was done, the hints should be already stripped away.  */
4656   gcc_assert (!flag_guess_branch_prob
4657               || optimize == 0 || seen_error ());
4658   return target;
4659 }
4660
4661 /* Expand a call to __builtin_assume_aligned.  We just return our first
4662    argument as the builtin_assume_aligned semantic should've been already
4663    executed by CCP.  */
4664
4665 static rtx
4666 expand_builtin_assume_aligned (tree exp, rtx target)
4667 {
4668   if (call_expr_nargs (exp) < 2)
4669     return const0_rtx;
4670   target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode,
4671                         EXPAND_NORMAL);
4672   gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1))
4673               && (call_expr_nargs (exp) < 3
4674                   || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2))));
4675   return target;
4676 }
4677
4678 void
4679 expand_builtin_trap (void)
4680 {
4681 #ifdef HAVE_trap
4682   if (HAVE_trap)
4683     {
4684       rtx insn = emit_insn (gen_trap ());
4685       /* For trap insns when not accumulating outgoing args force
4686          REG_ARGS_SIZE note to prevent crossjumping of calls with
4687          different args sizes.  */
4688       if (!ACCUMULATE_OUTGOING_ARGS)
4689         add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
4690     }
4691   else
4692 #endif
4693     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4694   emit_barrier ();
4695 }
4696
4697 /* Expand a call to __builtin_unreachable.  We do nothing except emit
4698    a barrier saying that control flow will not pass here.
4699
4700    It is the responsibility of the program being compiled to ensure
4701    that control flow does never reach __builtin_unreachable.  */
4702 static void
4703 expand_builtin_unreachable (void)
4704 {
4705   emit_barrier ();
4706 }
4707
4708 /* Expand EXP, a call to fabs, fabsf or fabsl.
4709    Return NULL_RTX if a normal call should be emitted rather than expanding
4710    the function inline.  If convenient, the result should be placed
4711    in TARGET.  SUBTARGET may be used as the target for computing
4712    the operand.  */
4713
4714 static rtx
4715 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4716 {
4717   enum machine_mode mode;
4718   tree arg;
4719   rtx op0;
4720
4721   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4722     return NULL_RTX;
4723
4724   arg = CALL_EXPR_ARG (exp, 0);
4725   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4726   mode = TYPE_MODE (TREE_TYPE (arg));
4727   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4728   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4729 }
4730
4731 /* Expand EXP, a call to copysign, copysignf, or copysignl.
4732    Return NULL is a normal call should be emitted rather than expanding the
4733    function inline.  If convenient, the result should be placed in TARGET.
4734    SUBTARGET may be used as the target for computing the operand.  */
4735
4736 static rtx
4737 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4738 {
4739   rtx op0, op1;
4740   tree arg;
4741
4742   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4743     return NULL_RTX;
4744
4745   arg = CALL_EXPR_ARG (exp, 0);
4746   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4747
4748   arg = CALL_EXPR_ARG (exp, 1);
4749   op1 = expand_normal (arg);
4750
4751   return expand_copysign (op0, op1, target);
4752 }
4753
4754 /* Create a new constant string literal and return a char* pointer to it.
4755    The STRING_CST value is the LEN characters at STR.  */
4756 tree
4757 build_string_literal (int len, const char *str)
4758 {
4759   tree t, elem, index, type;
4760
4761   t = build_string (len, str);
4762   elem = build_type_variant (char_type_node, 1, 0);
4763   index = build_index_type (size_int (len - 1));
4764   type = build_array_type (elem, index);
4765   TREE_TYPE (t) = type;
4766   TREE_CONSTANT (t) = 1;
4767   TREE_READONLY (t) = 1;
4768   TREE_STATIC (t) = 1;
4769
4770   type = build_pointer_type (elem);
4771   t = build1 (ADDR_EXPR, type,
4772               build4 (ARRAY_REF, elem,
4773                       t, integer_zero_node, NULL_TREE, NULL_TREE));
4774   return t;
4775 }
4776
4777 /* Expand a call to __builtin___clear_cache.  */
4778
4779 static rtx
4780 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
4781 {
4782 #ifndef HAVE_clear_cache
4783 #ifdef CLEAR_INSN_CACHE
4784   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4785      does something.  Just do the default expansion to a call to
4786      __clear_cache().  */
4787   return NULL_RTX;
4788 #else
4789   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4790      does nothing.  There is no need to call it.  Do nothing.  */
4791   return const0_rtx;
4792 #endif /* CLEAR_INSN_CACHE */
4793 #else
4794   /* We have a "clear_cache" insn, and it will handle everything.  */
4795   tree begin, end;
4796   rtx begin_rtx, end_rtx;
4797
4798   /* We must not expand to a library call.  If we did, any
4799      fallback library function in libgcc that might contain a call to
4800      __builtin___clear_cache() would recurse infinitely.  */
4801   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4802     {
4803       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
4804       return const0_rtx;
4805     }
4806
4807   if (HAVE_clear_cache)
4808     {
4809       struct expand_operand ops[2];
4810
4811       begin = CALL_EXPR_ARG (exp, 0);
4812       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
4813
4814       end = CALL_EXPR_ARG (exp, 1);
4815       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
4816
4817       create_address_operand (&ops[0], begin_rtx);
4818       create_address_operand (&ops[1], end_rtx);
4819       if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops))
4820         return const0_rtx;
4821     }
4822   return const0_rtx;
4823 #endif /* HAVE_clear_cache */
4824 }
4825
4826 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4827
4828 static rtx
4829 round_trampoline_addr (rtx tramp)
4830 {
4831   rtx temp, addend, mask;
4832
4833   /* If we don't need too much alignment, we'll have been guaranteed
4834      proper alignment by get_trampoline_type.  */
4835   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4836     return tramp;
4837
4838   /* Round address up to desired boundary.  */
4839   temp = gen_reg_rtx (Pmode);
4840   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4841   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4842
4843   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4844                                temp, 0, OPTAB_LIB_WIDEN);
4845   tramp = expand_simple_binop (Pmode, AND, temp, mask,
4846                                temp, 0, OPTAB_LIB_WIDEN);
4847
4848   return tramp;
4849 }
4850
4851 static rtx
4852 expand_builtin_init_trampoline (tree exp, bool onstack)
4853 {
4854   tree t_tramp, t_func, t_chain;
4855   rtx m_tramp, r_tramp, r_chain, tmp;
4856
4857   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4858                          POINTER_TYPE, VOID_TYPE))
4859     return NULL_RTX;
4860
4861   t_tramp = CALL_EXPR_ARG (exp, 0);
4862   t_func = CALL_EXPR_ARG (exp, 1);
4863   t_chain = CALL_EXPR_ARG (exp, 2);
4864
4865   r_tramp = expand_normal (t_tramp);
4866   m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
4867   MEM_NOTRAP_P (m_tramp) = 1;
4868
4869   /* If ONSTACK, the TRAMP argument should be the address of a field
4870      within the local function's FRAME decl.  Either way, let's see if
4871      we can fill in the MEM_ATTRs for this memory.  */
4872   if (TREE_CODE (t_tramp) == ADDR_EXPR)
4873     set_mem_attributes (m_tramp, TREE_OPERAND (t_tramp, 0), true);
4874
4875   /* Creator of a heap trampoline is responsible for making sure the
4876      address is aligned to at least STACK_BOUNDARY.  Normally malloc
4877      will ensure this anyhow.  */
4878   tmp = round_trampoline_addr (r_tramp);
4879   if (tmp != r_tramp)
4880     {
4881       m_tramp = change_address (m_tramp, BLKmode, tmp);
4882       set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
4883       set_mem_size (m_tramp, TRAMPOLINE_SIZE);
4884     }
4885
4886   /* The FUNC argument should be the address of the nested function.
4887      Extract the actual function decl to pass to the hook.  */
4888   gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
4889   t_func = TREE_OPERAND (t_func, 0);
4890   gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
4891
4892   r_chain = expand_normal (t_chain);
4893
4894   /* Generate insns to initialize the trampoline.  */
4895   targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4896
4897   if (onstack)
4898     {
4899       trampolines_created = 1;
4900
4901       warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines,
4902                   "trampoline generated for nested function %qD", t_func);
4903     }
4904
4905   return const0_rtx;
4906 }
4907
4908 static rtx
4909 expand_builtin_adjust_trampoline (tree exp)
4910 {
4911   rtx tramp;
4912
4913   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4914     return NULL_RTX;
4915
4916   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4917   tramp = round_trampoline_addr (tramp);
4918   if (targetm.calls.trampoline_adjust_address)
4919     tramp = targetm.calls.trampoline_adjust_address (tramp);
4920
4921   return tramp;
4922 }
4923
4924 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
4925    function.  The function first checks whether the back end provides
4926    an insn to implement signbit for the respective mode.  If not, it
4927    checks whether the floating point format of the value is such that
4928    the sign bit can be extracted.  If that is not the case, the
4929    function returns NULL_RTX to indicate that a normal call should be
4930    emitted rather than expanding the function in-line.  EXP is the
4931    expression that is a call to the builtin function; if convenient,
4932    the result should be placed in TARGET.  */
4933 static rtx
4934 expand_builtin_signbit (tree exp, rtx target)
4935 {
4936   const struct real_format *fmt;
4937   enum machine_mode fmode, imode, rmode;
4938   tree arg;
4939   int word, bitpos;
4940   enum insn_code icode;
4941   rtx temp;
4942   location_t loc = EXPR_LOCATION (exp);
4943
4944   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4945     return NULL_RTX;
4946
4947   arg = CALL_EXPR_ARG (exp, 0);
4948   fmode = TYPE_MODE (TREE_TYPE (arg));
4949   rmode = TYPE_MODE (TREE_TYPE (exp));
4950   fmt = REAL_MODE_FORMAT (fmode);
4951
4952   arg = builtin_save_expr (arg);
4953
4954   /* Expand the argument yielding a RTX expression. */
4955   temp = expand_normal (arg);
4956
4957   /* Check if the back end provides an insn that handles signbit for the
4958      argument's mode. */
4959   icode = optab_handler (signbit_optab, fmode);
4960   if (icode != CODE_FOR_nothing)
4961     {
4962       rtx last = get_last_insn ();
4963       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
4964       if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
4965         return target;
4966       delete_insns_since (last);
4967     }
4968
4969   /* For floating point formats without a sign bit, implement signbit
4970      as "ARG < 0.0".  */
4971   bitpos = fmt->signbit_ro;
4972   if (bitpos < 0)
4973   {
4974     /* But we can't do this if the format supports signed zero.  */
4975     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4976       return NULL_RTX;
4977
4978     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
4979                        build_real (TREE_TYPE (arg), dconst0));
4980     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4981   }
4982
4983   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4984     {
4985       imode = int_mode_for_mode (fmode);
4986       if (imode == BLKmode)
4987         return NULL_RTX;
4988       temp = gen_lowpart (imode, temp);
4989     }
4990   else
4991     {
4992       imode = word_mode;
4993       /* Handle targets with different FP word orders.  */
4994       if (FLOAT_WORDS_BIG_ENDIAN)
4995         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
4996       else
4997         word = bitpos / BITS_PER_WORD;
4998       temp = operand_subword_force (temp, word, fmode);
4999       bitpos = bitpos % BITS_PER_WORD;
5000     }
5001
5002   /* Force the intermediate word_mode (or narrower) result into a
5003      register.  This avoids attempting to create paradoxical SUBREGs
5004      of floating point modes below.  */
5005   temp = force_reg (imode, temp);
5006
5007   /* If the bitpos is within the "result mode" lowpart, the operation
5008      can be implement with a single bitwise AND.  Otherwise, we need
5009      a right shift and an AND.  */
5010
5011   if (bitpos < GET_MODE_BITSIZE (rmode))
5012     {
5013       double_int mask = double_int_zero.set_bit (bitpos);
5014
5015       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5016         temp = gen_lowpart (rmode, temp);
5017       temp = expand_binop (rmode, and_optab, temp,
5018                            immed_double_int_const (mask, rmode),
5019                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5020     }
5021   else
5022     {
5023       /* Perform a logical right shift to place the signbit in the least
5024          significant bit, then truncate the result to the desired mode
5025          and mask just this bit.  */
5026       temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1);
5027       temp = gen_lowpart (rmode, temp);
5028       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5029                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5030     }
5031
5032   return temp;
5033 }
5034
5035 /* Expand fork or exec calls.  TARGET is the desired target of the
5036    call.  EXP is the call. FN is the
5037    identificator of the actual function.  IGNORE is nonzero if the
5038    value is to be ignored.  */
5039
5040 static rtx
5041 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5042 {
5043   tree id, decl;
5044   tree call;
5045
5046   /* If we are not profiling, just call the function.  */
5047   if (!profile_arc_flag)
5048     return NULL_RTX;
5049
5050   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5051      compiler, so the code does not diverge, and the wrapper may run the
5052      code necessary for keeping the profiling sane.  */
5053
5054   switch (DECL_FUNCTION_CODE (fn))
5055     {
5056     case BUILT_IN_FORK:
5057       id = get_identifier ("__gcov_fork");
5058       break;
5059
5060     case BUILT_IN_EXECL:
5061       id = get_identifier ("__gcov_execl");
5062       break;
5063
5064     case BUILT_IN_EXECV:
5065       id = get_identifier ("__gcov_execv");
5066       break;
5067
5068     case BUILT_IN_EXECLP:
5069       id = get_identifier ("__gcov_execlp");
5070       break;
5071
5072     case BUILT_IN_EXECLE:
5073       id = get_identifier ("__gcov_execle");
5074       break;
5075
5076     case BUILT_IN_EXECVP:
5077       id = get_identifier ("__gcov_execvp");
5078       break;
5079
5080     case BUILT_IN_EXECVE:
5081       id = get_identifier ("__gcov_execve");
5082       break;
5083
5084     default:
5085       gcc_unreachable ();
5086     }
5087
5088   decl = build_decl (DECL_SOURCE_LOCATION (fn),
5089                      FUNCTION_DECL, id, TREE_TYPE (fn));
5090   DECL_EXTERNAL (decl) = 1;
5091   TREE_PUBLIC (decl) = 1;
5092   DECL_ARTIFICIAL (decl) = 1;
5093   TREE_NOTHROW (decl) = 1;
5094   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5095   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5096   call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5097   return expand_call (call, target, ignore);
5098  }
5099
5100
5101 \f
5102 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5103    the pointer in these functions is void*, the tree optimizers may remove
5104    casts.  The mode computed in expand_builtin isn't reliable either, due
5105    to __sync_bool_compare_and_swap.
5106
5107    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5108    group of builtins.  This gives us log2 of the mode size.  */
5109
5110 static inline enum machine_mode
5111 get_builtin_sync_mode (int fcode_diff)
5112 {
5113   /* The size is not negotiable, so ask not to get BLKmode in return
5114      if the target indicates that a smaller size would be better.  */
5115   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5116 }
5117
5118 /* Expand the memory expression LOC and return the appropriate memory operand
5119    for the builtin_sync operations.  */
5120
5121 static rtx
5122 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5123 {
5124   rtx addr, mem;
5125
5126   addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5127   addr = convert_memory_address (Pmode, addr);
5128
5129   /* Note that we explicitly do not want any alias information for this
5130      memory, so that we kill all other live memories.  Otherwise we don't
5131      satisfy the full barrier semantics of the intrinsic.  */
5132   mem = validize_mem (gen_rtx_MEM (mode, addr));
5133
5134   /* The alignment needs to be at least according to that of the mode.  */
5135   set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
5136                            get_pointer_alignment (loc)));
5137   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5138   MEM_VOLATILE_P (mem) = 1;
5139
5140   return mem;
5141 }
5142
5143 /* Make sure an argument is in the right mode.
5144    EXP is the tree argument. 
5145    MODE is the mode it should be in.  */
5146
5147 static rtx
5148 expand_expr_force_mode (tree exp, enum machine_mode mode)
5149 {
5150   rtx val;
5151   enum machine_mode old_mode;
5152
5153   val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
5154   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5155      of CONST_INTs, where we know the old_mode only from the call argument.  */
5156
5157   old_mode = GET_MODE (val);
5158   if (old_mode == VOIDmode)
5159     old_mode = TYPE_MODE (TREE_TYPE (exp));
5160   val = convert_modes (mode, old_mode, val, 1);
5161   return val;
5162 }
5163
5164
5165 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5166    EXP is the CALL_EXPR.  CODE is the rtx code
5167    that corresponds to the arithmetic or logical operation from the name;
5168    an exception here is that NOT actually means NAND.  TARGET is an optional
5169    place for us to store the results; AFTER is true if this is the
5170    fetch_and_xxx form.  */
5171
5172 static rtx
5173 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5174                                enum rtx_code code, bool after,
5175                                rtx target)
5176 {
5177   rtx val, mem;
5178   location_t loc = EXPR_LOCATION (exp);
5179
5180   if (code == NOT && warn_sync_nand)
5181     {
5182       tree fndecl = get_callee_fndecl (exp);
5183       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5184
5185       static bool warned_f_a_n, warned_n_a_f;
5186
5187       switch (fcode)
5188         {
5189         case BUILT_IN_SYNC_FETCH_AND_NAND_1:
5190         case BUILT_IN_SYNC_FETCH_AND_NAND_2:
5191         case BUILT_IN_SYNC_FETCH_AND_NAND_4:
5192         case BUILT_IN_SYNC_FETCH_AND_NAND_8:
5193         case BUILT_IN_SYNC_FETCH_AND_NAND_16:
5194           if (warned_f_a_n)
5195             break;
5196
5197           fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N);
5198           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5199           warned_f_a_n = true;
5200           break;
5201
5202         case BUILT_IN_SYNC_NAND_AND_FETCH_1:
5203         case BUILT_IN_SYNC_NAND_AND_FETCH_2:
5204         case BUILT_IN_SYNC_NAND_AND_FETCH_4:
5205         case BUILT_IN_SYNC_NAND_AND_FETCH_8:
5206         case BUILT_IN_SYNC_NAND_AND_FETCH_16:
5207           if (warned_n_a_f)
5208             break;
5209
5210          fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N);
5211           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5212           warned_n_a_f = true;
5213           break;
5214
5215         default:
5216           gcc_unreachable ();
5217         }
5218     }
5219
5220   /* Expand the operands.  */
5221   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5222   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5223
5224   return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SEQ_CST,
5225                                  after);
5226 }
5227
5228 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5229    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5230    true if this is the boolean form.  TARGET is a place for us to store the
5231    results; this is NOT optional if IS_BOOL is true.  */
5232
5233 static rtx
5234 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5235                                  bool is_bool, rtx target)
5236 {
5237   rtx old_val, new_val, mem;
5238   rtx *pbool, *poval;
5239
5240   /* Expand the operands.  */
5241   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5242   old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5243   new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5244
5245   pbool = poval = NULL;
5246   if (target != const0_rtx)
5247     {
5248       if (is_bool)
5249         pbool = &target;
5250       else
5251         poval = &target;
5252     }
5253   if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val,
5254                                        false, MEMMODEL_SEQ_CST,
5255                                        MEMMODEL_SEQ_CST))
5256     return NULL_RTX;
5257
5258   return target;
5259 }
5260
5261 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5262    general form is actually an atomic exchange, and some targets only
5263    support a reduced form with the second argument being a constant 1.
5264    EXP is the CALL_EXPR; TARGET is an optional place for us to store
5265    the results.  */
5266
5267 static rtx
5268 expand_builtin_sync_lock_test_and_set (enum machine_mode mode, tree exp,
5269                                        rtx target)
5270 {
5271   rtx val, mem;
5272
5273   /* Expand the operands.  */
5274   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5275   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5276
5277   return expand_sync_lock_test_and_set (target, mem, val);
5278 }
5279
5280 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
5281
5282 static void
5283 expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
5284 {
5285   rtx mem;
5286
5287   /* Expand the operands.  */
5288   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5289
5290   expand_atomic_store (mem, const0_rtx, MEMMODEL_RELEASE, true);
5291 }
5292
5293 /* Given an integer representing an ``enum memmodel'', verify its
5294    correctness and return the memory model enum.  */
5295
5296 static enum memmodel
5297 get_memmodel (tree exp)
5298 {
5299   rtx op;
5300   unsigned HOST_WIDE_INT val;
5301
5302   /* If the parameter is not a constant, it's a run time value so we'll just
5303      convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking.  */
5304   if (TREE_CODE (exp) != INTEGER_CST)
5305     return MEMMODEL_SEQ_CST;
5306
5307   op = expand_normal (exp);
5308
5309   val = INTVAL (op);
5310   if (targetm.memmodel_check)
5311     val = targetm.memmodel_check (val);
5312   else if (val & ~MEMMODEL_MASK)
5313     {
5314       warning (OPT_Winvalid_memory_model,
5315                "Unknown architecture specifier in memory model to builtin.");
5316       return MEMMODEL_SEQ_CST;
5317     }
5318
5319   if ((INTVAL(op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
5320     {
5321       warning (OPT_Winvalid_memory_model,
5322                "invalid memory model argument to builtin");
5323       return MEMMODEL_SEQ_CST;
5324     }
5325
5326   return (enum memmodel) val;
5327 }
5328
5329 /* Expand the __atomic_exchange intrinsic:
5330         TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel)
5331    EXP is the CALL_EXPR.
5332    TARGET is an optional place for us to store the results.  */
5333
5334 static rtx
5335 expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
5336 {
5337   rtx val, mem;
5338   enum memmodel model;
5339
5340   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5341   if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME)
5342     {
5343       error ("invalid memory model for %<__atomic_exchange%>");
5344       return NULL_RTX;
5345     }
5346
5347   if (!flag_inline_atomics)
5348     return NULL_RTX;
5349
5350   /* Expand the operands.  */
5351   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5352   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5353
5354   return expand_atomic_exchange (target, mem, val, model);
5355 }
5356
5357 /* Expand the __atomic_compare_exchange intrinsic:
5358         bool __atomic_compare_exchange (TYPE *object, TYPE *expect, 
5359                                         TYPE desired, BOOL weak, 
5360                                         enum memmodel success,
5361                                         enum memmodel failure)
5362    EXP is the CALL_EXPR.
5363    TARGET is an optional place for us to store the results.  */
5364
5365 static rtx
5366 expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, 
5367                                         rtx target)
5368 {
5369   rtx expect, desired, mem, oldval;
5370   enum memmodel success, failure;
5371   tree weak;
5372   bool is_weak;
5373
5374   success = get_memmodel (CALL_EXPR_ARG (exp, 4));
5375   failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
5376
5377   if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
5378       || (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5379     {
5380       error ("invalid failure memory model for %<__atomic_compare_exchange%>");
5381       return NULL_RTX;
5382     }
5383
5384   if (failure > success)
5385     {
5386       error ("failure memory model cannot be stronger than success "
5387              "memory model for %<__atomic_compare_exchange%>");
5388       return NULL_RTX;
5389     }
5390   
5391   if (!flag_inline_atomics)
5392     return NULL_RTX;
5393
5394   /* Expand the operands.  */
5395   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5396
5397   expect = expand_normal (CALL_EXPR_ARG (exp, 1));
5398   expect = convert_memory_address (Pmode, expect);
5399   expect = gen_rtx_MEM (mode, expect);
5400   desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5401
5402   weak = CALL_EXPR_ARG (exp, 3);
5403   is_weak = false;
5404   if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
5405     is_weak = true;
5406
5407   oldval = expect;
5408   if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
5409                                        &oldval, mem, oldval, desired,
5410                                        is_weak, success, failure))
5411     return NULL_RTX;
5412
5413   if (oldval != expect)
5414     emit_move_insn (expect, oldval);
5415
5416   return target;
5417 }
5418
5419 /* Expand the __atomic_load intrinsic:
5420         TYPE __atomic_load (TYPE *object, enum memmodel)
5421    EXP is the CALL_EXPR.
5422    TARGET is an optional place for us to store the results.  */
5423
5424 static rtx
5425 expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
5426 {
5427   rtx mem;
5428   enum memmodel model;
5429
5430   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5431   if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
5432       || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5433     {
5434       error ("invalid memory model for %<__atomic_load%>");
5435       return NULL_RTX;
5436     }
5437
5438   if (!flag_inline_atomics)
5439     return NULL_RTX;
5440
5441   /* Expand the operand.  */
5442   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5443
5444   return expand_atomic_load (target, mem, model);
5445 }
5446
5447
5448 /* Expand the __atomic_store intrinsic:
5449         void __atomic_store (TYPE *object, TYPE desired, enum memmodel)
5450    EXP is the CALL_EXPR.
5451    TARGET is an optional place for us to store the results.  */
5452
5453 static rtx
5454 expand_builtin_atomic_store (enum machine_mode mode, tree exp)
5455 {
5456   rtx mem, val;
5457   enum memmodel model;
5458
5459   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5460   if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED
5461       && (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
5462       && (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
5463     {
5464       error ("invalid memory model for %<__atomic_store%>");
5465       return NULL_RTX;
5466     }
5467
5468   if (!flag_inline_atomics)
5469     return NULL_RTX;
5470
5471   /* Expand the operands.  */
5472   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5473   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5474
5475   return expand_atomic_store (mem, val, model, false);
5476 }
5477
5478 /* Expand the __atomic_fetch_XXX intrinsic:
5479         TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
5480    EXP is the CALL_EXPR.
5481    TARGET is an optional place for us to store the results.
5482    CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR.
5483    FETCH_AFTER is true if returning the result of the operation.
5484    FETCH_AFTER is false if returning the value before the operation.
5485    IGNORE is true if the result is not used.
5486    EXT_CALL is the correct builtin for an external call if this cannot be
5487    resolved to an instruction sequence.  */
5488
5489 static rtx
5490 expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
5491                                 enum rtx_code code, bool fetch_after,
5492                                 bool ignore, enum built_in_function ext_call)
5493 {
5494   rtx val, mem, ret;
5495   enum memmodel model;
5496   tree fndecl;
5497   tree addr;
5498
5499   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5500
5501   /* Expand the operands.  */
5502   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5503   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5504
5505   /* Only try generating instructions if inlining is turned on.  */
5506   if (flag_inline_atomics)
5507     {
5508       ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after);
5509       if (ret)
5510         return ret;
5511     }
5512
5513   /* Return if a different routine isn't needed for the library call.  */
5514   if (ext_call == BUILT_IN_NONE)
5515     return NULL_RTX;
5516
5517   /* Change the call to the specified function.  */
5518   fndecl = get_callee_fndecl (exp);
5519   addr = CALL_EXPR_FN (exp);
5520   STRIP_NOPS (addr);
5521
5522   gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
5523   TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
5524
5525   /* Expand the call here so we can emit trailing code.  */
5526   ret = expand_call (exp, target, ignore);
5527
5528   /* Replace the original function just in case it matters.  */
5529   TREE_OPERAND (addr, 0) = fndecl;
5530
5531   /* Then issue the arithmetic correction to return the right result.  */
5532   if (!ignore)
5533     {
5534       if (code == NOT)
5535         {
5536           ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
5537                                      OPTAB_LIB_WIDEN);
5538           ret = expand_simple_unop (mode, NOT, ret, target, true);
5539         }
5540       else
5541         ret = expand_simple_binop (mode, code, ret, val, target, true,
5542                                    OPTAB_LIB_WIDEN);
5543     }
5544   return ret;
5545 }
5546
5547
5548 #ifndef HAVE_atomic_clear
5549 # define HAVE_atomic_clear 0
5550 # define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX)
5551 #endif
5552
5553 /* Expand an atomic clear operation.
5554         void _atomic_clear (BOOL *obj, enum memmodel)
5555    EXP is the call expression.  */
5556
5557 static rtx
5558 expand_builtin_atomic_clear (tree exp) 
5559 {
5560   enum machine_mode mode;
5561   rtx mem, ret;
5562   enum memmodel model;
5563
5564   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5565   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5566   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5567
5568   if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
5569       || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5570     {
5571       error ("invalid memory model for %<__atomic_store%>");
5572       return const0_rtx;
5573     }
5574
5575   if (HAVE_atomic_clear)
5576     {
5577       emit_insn (gen_atomic_clear (mem, model));
5578       return const0_rtx;
5579     }
5580
5581   /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release.
5582      Failing that, a store is issued by __atomic_store.  The only way this can
5583      fail is if the bool type is larger than a word size.  Unlikely, but
5584      handle it anyway for completeness.  Assume a single threaded model since
5585      there is no atomic support in this case, and no barriers are required.  */
5586   ret = expand_atomic_store (mem, const0_rtx, model, true);
5587   if (!ret)
5588     emit_move_insn (mem, const0_rtx);
5589   return const0_rtx;
5590 }
5591
5592 /* Expand an atomic test_and_set operation.
5593         bool _atomic_test_and_set (BOOL *obj, enum memmodel)
5594    EXP is the call expression.  */
5595
5596 static rtx
5597 expand_builtin_atomic_test_and_set (tree exp, rtx target)
5598 {
5599   rtx mem;
5600   enum memmodel model;
5601   enum machine_mode mode;
5602
5603   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5604   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5605   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5606
5607   return expand_atomic_test_and_set (target, mem, model);
5608 }
5609
5610
5611 /* Return true if (optional) argument ARG1 of size ARG0 is always lock free on
5612    this architecture.  If ARG1 is NULL, use typical alignment for size ARG0.  */
5613
5614 static tree
5615 fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
5616 {
5617   int size;
5618   enum machine_mode mode;
5619   unsigned int mode_align, type_align;
5620
5621   if (TREE_CODE (arg0) != INTEGER_CST)
5622     return NULL_TREE;
5623
5624   size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT;
5625   mode = mode_for_size (size, MODE_INT, 0);
5626   mode_align = GET_MODE_ALIGNMENT (mode);
5627
5628   if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
5629     type_align = mode_align;
5630   else
5631     {
5632       tree ttype = TREE_TYPE (arg1);
5633
5634       /* This function is usually invoked and folded immediately by the front
5635          end before anything else has a chance to look at it.  The pointer
5636          parameter at this point is usually cast to a void *, so check for that
5637          and look past the cast.  */
5638       if (TREE_CODE (arg1) == NOP_EXPR && POINTER_TYPE_P (ttype)
5639           && VOID_TYPE_P (TREE_TYPE (ttype)))
5640         arg1 = TREE_OPERAND (arg1, 0);
5641
5642       ttype = TREE_TYPE (arg1);
5643       gcc_assert (POINTER_TYPE_P (ttype));
5644
5645       /* Get the underlying type of the object.  */
5646       ttype = TREE_TYPE (ttype);
5647       type_align = TYPE_ALIGN (ttype);
5648     }
5649
5650   /* If the object has smaller alignment, the the lock free routines cannot
5651      be used.  */
5652   if (type_align < mode_align)
5653     return boolean_false_node;
5654
5655   /* Check if a compare_and_swap pattern exists for the mode which represents
5656      the required size.  The pattern is not allowed to fail, so the existence
5657      of the pattern indicates support is present.  */
5658   if (can_compare_and_swap_p (mode, true))
5659     return boolean_true_node;
5660   else
5661     return boolean_false_node;
5662 }
5663
5664 /* Return true if the parameters to call EXP represent an object which will
5665    always generate lock free instructions.  The first argument represents the
5666    size of the object, and the second parameter is a pointer to the object 
5667    itself.  If NULL is passed for the object, then the result is based on 
5668    typical alignment for an object of the specified size.  Otherwise return 
5669    false.  */
5670
5671 static rtx
5672 expand_builtin_atomic_always_lock_free (tree exp)
5673 {
5674   tree size;
5675   tree arg0 = CALL_EXPR_ARG (exp, 0);
5676   tree arg1 = CALL_EXPR_ARG (exp, 1);
5677
5678   if (TREE_CODE (arg0) != INTEGER_CST)
5679     {
5680       error ("non-constant argument 1 to __atomic_always_lock_free");
5681       return const0_rtx;
5682     }
5683
5684   size = fold_builtin_atomic_always_lock_free (arg0, arg1);
5685   if (size == boolean_true_node)
5686     return const1_rtx;
5687   return const0_rtx;
5688 }
5689
5690 /* Return a one or zero if it can be determined that object ARG1 of size ARG 
5691    is lock free on this architecture.  */
5692
5693 static tree
5694 fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
5695 {
5696   if (!flag_inline_atomics)
5697     return NULL_TREE;
5698   
5699   /* If it isn't always lock free, don't generate a result.  */
5700   if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node)
5701     return boolean_true_node;
5702
5703   return NULL_TREE;
5704 }
5705
5706 /* Return true if the parameters to call EXP represent an object which will
5707    always generate lock free instructions.  The first argument represents the
5708    size of the object, and the second parameter is a pointer to the object 
5709    itself.  If NULL is passed for the object, then the result is based on 
5710    typical alignment for an object of the specified size.  Otherwise return 
5711    NULL*/
5712
5713 static rtx
5714 expand_builtin_atomic_is_lock_free (tree exp)
5715 {
5716   tree size;
5717   tree arg0 = CALL_EXPR_ARG (exp, 0);
5718   tree arg1 = CALL_EXPR_ARG (exp, 1);
5719
5720   if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
5721     {
5722       error ("non-integer argument 1 to __atomic_is_lock_free");
5723       return NULL_RTX;
5724     }
5725
5726   if (!flag_inline_atomics)
5727     return NULL_RTX; 
5728
5729   /* If the value is known at compile time, return the RTX for it.  */
5730   size = fold_builtin_atomic_is_lock_free (arg0, arg1);
5731   if (size == boolean_true_node)
5732     return const1_rtx;
5733
5734   return NULL_RTX;
5735 }
5736
5737 /* Expand the __atomic_thread_fence intrinsic:
5738         void __atomic_thread_fence (enum memmodel)
5739    EXP is the CALL_EXPR.  */
5740
5741 static void
5742 expand_builtin_atomic_thread_fence (tree exp)
5743 {
5744   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5745   expand_mem_thread_fence (model);
5746 }
5747
5748 /* Expand the __atomic_signal_fence intrinsic:
5749         void __atomic_signal_fence (enum memmodel)
5750    EXP is the CALL_EXPR.  */
5751
5752 static void
5753 expand_builtin_atomic_signal_fence (tree exp)
5754 {
5755   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5756   expand_mem_signal_fence (model);
5757 }
5758
5759 /* Expand the __sync_synchronize intrinsic.  */
5760
5761 static void
5762 expand_builtin_sync_synchronize (void)
5763 {
5764   expand_mem_thread_fence (MEMMODEL_SEQ_CST);
5765 }
5766
5767 static rtx
5768 expand_builtin_thread_pointer (tree exp, rtx target)
5769 {
5770   enum insn_code icode;
5771   if (!validate_arglist (exp, VOID_TYPE))
5772     return const0_rtx;
5773   icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
5774   if (icode != CODE_FOR_nothing)
5775     {
5776       struct expand_operand op;
5777       if (!REG_P (target) || GET_MODE (target) != Pmode)
5778         target = gen_reg_rtx (Pmode);
5779       create_output_operand (&op, target, Pmode);
5780       expand_insn (icode, 1, &op);
5781       return target;
5782     }
5783   error ("__builtin_thread_pointer is not supported on this target");
5784   return const0_rtx;
5785 }
5786
5787 static void
5788 expand_builtin_set_thread_pointer (tree exp)
5789 {
5790   enum insn_code icode;
5791   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5792     return;
5793   icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
5794   if (icode != CODE_FOR_nothing)
5795     {
5796       struct expand_operand op;
5797       rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
5798                              Pmode, EXPAND_NORMAL);      
5799       create_input_operand (&op, val, Pmode);
5800       expand_insn (icode, 1, &op);
5801       return;
5802     }
5803   error ("__builtin_set_thread_pointer is not supported on this target");
5804 }
5805
5806 \f
5807 /* Expand an expression EXP that calls a built-in function,
5808    with result going to TARGET if that's convenient
5809    (and in mode MODE if that's convenient).
5810    SUBTARGET may be used as the target for computing one of EXP's operands.
5811    IGNORE is nonzero if the value is to be ignored.  */
5812
5813 rtx
5814 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5815                 int ignore)
5816 {
5817   tree fndecl = get_callee_fndecl (exp);
5818   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5819   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5820   int flags;
5821
5822   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5823     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5824
5825   /* When not optimizing, generate calls to library functions for a certain
5826      set of builtins.  */
5827   if (!optimize
5828       && !called_as_built_in (fndecl)
5829       && fcode != BUILT_IN_ALLOCA
5830       && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
5831       && fcode != BUILT_IN_FREE)
5832     return expand_call (exp, target, ignore);
5833
5834   /* The built-in function expanders test for target == const0_rtx
5835      to determine whether the function's result will be ignored.  */
5836   if (ignore)
5837     target = const0_rtx;
5838
5839   /* If the result of a pure or const built-in function is ignored, and
5840      none of its arguments are volatile, we can avoid expanding the
5841      built-in call and just evaluate the arguments for side-effects.  */
5842   if (target == const0_rtx
5843       && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
5844       && !(flags & ECF_LOOPING_CONST_OR_PURE))
5845     {
5846       bool volatilep = false;
5847       tree arg;
5848       call_expr_arg_iterator iter;
5849
5850       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5851         if (TREE_THIS_VOLATILE (arg))
5852           {
5853             volatilep = true;
5854             break;
5855           }
5856
5857       if (! volatilep)
5858         {
5859           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5860             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5861           return const0_rtx;
5862         }
5863     }
5864
5865   switch (fcode)
5866     {
5867     CASE_FLT_FN (BUILT_IN_FABS):
5868       target = expand_builtin_fabs (exp, target, subtarget);
5869       if (target)
5870         return target;
5871       break;
5872
5873     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5874       target = expand_builtin_copysign (exp, target, subtarget);
5875       if (target)
5876         return target;
5877       break;
5878
5879       /* Just do a normal library call if we were unable to fold
5880          the values.  */
5881     CASE_FLT_FN (BUILT_IN_CABS):
5882       break;
5883
5884     CASE_FLT_FN (BUILT_IN_EXP):
5885     CASE_FLT_FN (BUILT_IN_EXP10):
5886     CASE_FLT_FN (BUILT_IN_POW10):
5887     CASE_FLT_FN (BUILT_IN_EXP2):
5888     CASE_FLT_FN (BUILT_IN_EXPM1):
5889     CASE_FLT_FN (BUILT_IN_LOGB):
5890     CASE_FLT_FN (BUILT_IN_LOG):
5891     CASE_FLT_FN (BUILT_IN_LOG10):
5892     CASE_FLT_FN (BUILT_IN_LOG2):
5893     CASE_FLT_FN (BUILT_IN_LOG1P):
5894     CASE_FLT_FN (BUILT_IN_TAN):
5895     CASE_FLT_FN (BUILT_IN_ASIN):
5896     CASE_FLT_FN (BUILT_IN_ACOS):
5897     CASE_FLT_FN (BUILT_IN_ATAN):
5898     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5899       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5900          because of possible accuracy problems.  */
5901       if (! flag_unsafe_math_optimizations)
5902         break;
5903     CASE_FLT_FN (BUILT_IN_SQRT):
5904     CASE_FLT_FN (BUILT_IN_FLOOR):
5905     CASE_FLT_FN (BUILT_IN_CEIL):
5906     CASE_FLT_FN (BUILT_IN_TRUNC):
5907     CASE_FLT_FN (BUILT_IN_ROUND):
5908     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5909     CASE_FLT_FN (BUILT_IN_RINT):
5910       target = expand_builtin_mathfn (exp, target, subtarget);
5911       if (target)
5912         return target;
5913       break;
5914
5915     CASE_FLT_FN (BUILT_IN_FMA):
5916       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
5917       if (target)
5918         return target;
5919       break;
5920
5921     CASE_FLT_FN (BUILT_IN_ILOGB):
5922       if (! flag_unsafe_math_optimizations)
5923         break;
5924     CASE_FLT_FN (BUILT_IN_ISINF):
5925     CASE_FLT_FN (BUILT_IN_FINITE):
5926     case BUILT_IN_ISFINITE:
5927     case BUILT_IN_ISNORMAL:
5928       target = expand_builtin_interclass_mathfn (exp, target);
5929       if (target)
5930         return target;
5931       break;
5932
5933     CASE_FLT_FN (BUILT_IN_ICEIL):
5934     CASE_FLT_FN (BUILT_IN_LCEIL):
5935     CASE_FLT_FN (BUILT_IN_LLCEIL):
5936     CASE_FLT_FN (BUILT_IN_LFLOOR):
5937     CASE_FLT_FN (BUILT_IN_IFLOOR):
5938     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5939       target = expand_builtin_int_roundingfn (exp, target);
5940       if (target)
5941         return target;
5942       break;
5943
5944     CASE_FLT_FN (BUILT_IN_IRINT):
5945     CASE_FLT_FN (BUILT_IN_LRINT):
5946     CASE_FLT_FN (BUILT_IN_LLRINT):
5947     CASE_FLT_FN (BUILT_IN_IROUND):
5948     CASE_FLT_FN (BUILT_IN_LROUND):
5949     CASE_FLT_FN (BUILT_IN_LLROUND):
5950       target = expand_builtin_int_roundingfn_2 (exp, target);
5951       if (target)
5952         return target;
5953       break;
5954
5955     CASE_FLT_FN (BUILT_IN_POWI):
5956       target = expand_builtin_powi (exp, target);
5957       if (target)
5958         return target;
5959       break;
5960
5961     CASE_FLT_FN (BUILT_IN_ATAN2):
5962     CASE_FLT_FN (BUILT_IN_LDEXP):
5963     CASE_FLT_FN (BUILT_IN_SCALB):
5964     CASE_FLT_FN (BUILT_IN_SCALBN):
5965     CASE_FLT_FN (BUILT_IN_SCALBLN):
5966       if (! flag_unsafe_math_optimizations)
5967         break;
5968
5969     CASE_FLT_FN (BUILT_IN_FMOD):
5970     CASE_FLT_FN (BUILT_IN_REMAINDER):
5971     CASE_FLT_FN (BUILT_IN_DREM):
5972     CASE_FLT_FN (BUILT_IN_POW):
5973       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5974       if (target)
5975         return target;
5976       break;
5977
5978     CASE_FLT_FN (BUILT_IN_CEXPI):
5979       target = expand_builtin_cexpi (exp, target);
5980       gcc_assert (target);
5981       return target;
5982
5983     CASE_FLT_FN (BUILT_IN_SIN):
5984     CASE_FLT_FN (BUILT_IN_COS):
5985       if (! flag_unsafe_math_optimizations)
5986         break;
5987       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5988       if (target)
5989         return target;
5990       break;
5991
5992     CASE_FLT_FN (BUILT_IN_SINCOS):
5993       if (! flag_unsafe_math_optimizations)
5994         break;
5995       target = expand_builtin_sincos (exp);
5996       if (target)
5997         return target;
5998       break;
5999
6000     case BUILT_IN_APPLY_ARGS:
6001       return expand_builtin_apply_args ();
6002
6003       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6004          FUNCTION with a copy of the parameters described by
6005          ARGUMENTS, and ARGSIZE.  It returns a block of memory
6006          allocated on the stack into which is stored all the registers
6007          that might possibly be used for returning the result of a
6008          function.  ARGUMENTS is the value returned by
6009          __builtin_apply_args.  ARGSIZE is the number of bytes of
6010          arguments that must be copied.  ??? How should this value be
6011          computed?  We'll also need a safe worst case value for varargs
6012          functions.  */
6013     case BUILT_IN_APPLY:
6014       if (!validate_arglist (exp, POINTER_TYPE,
6015                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
6016           && !validate_arglist (exp, REFERENCE_TYPE,
6017                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6018         return const0_rtx;
6019       else
6020         {
6021           rtx ops[3];
6022
6023           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6024           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6025           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6026
6027           return expand_builtin_apply (ops[0], ops[1], ops[2]);
6028         }
6029
6030       /* __builtin_return (RESULT) causes the function to return the
6031          value described by RESULT.  RESULT is address of the block of
6032          memory returned by __builtin_apply.  */
6033     case BUILT_IN_RETURN:
6034       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6035         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6036       return const0_rtx;
6037
6038     case BUILT_IN_SAVEREGS:
6039       return expand_builtin_saveregs ();
6040
6041     case BUILT_IN_VA_ARG_PACK:
6042       /* All valid uses of __builtin_va_arg_pack () are removed during
6043          inlining.  */
6044       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6045       return const0_rtx;
6046
6047     case BUILT_IN_VA_ARG_PACK_LEN:
6048       /* All valid uses of __builtin_va_arg_pack_len () are removed during
6049          inlining.  */
6050       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6051       return const0_rtx;
6052
6053       /* Return the address of the first anonymous stack arg.  */
6054     case BUILT_IN_NEXT_ARG:
6055       if (fold_builtin_next_arg (exp, false))
6056         return const0_rtx;
6057       return expand_builtin_next_arg ();
6058
6059     case BUILT_IN_CLEAR_CACHE:
6060       target = expand_builtin___clear_cache (exp);
6061       if (target)
6062         return target;
6063       break;
6064
6065     case BUILT_IN_CLASSIFY_TYPE:
6066       return expand_builtin_classify_type (exp);
6067
6068     case BUILT_IN_CONSTANT_P:
6069       return const0_rtx;
6070
6071     case BUILT_IN_FRAME_ADDRESS:
6072     case BUILT_IN_RETURN_ADDRESS:
6073       return expand_builtin_frame_address (fndecl, exp);
6074
6075     /* Returns the address of the area where the structure is returned.
6076        0 otherwise.  */
6077     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6078       if (call_expr_nargs (exp) != 0
6079           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6080           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6081         return const0_rtx;
6082       else
6083         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6084
6085     case BUILT_IN_ALLOCA:
6086     case BUILT_IN_ALLOCA_WITH_ALIGN:
6087       /* If the allocation stems from the declaration of a variable-sized
6088          object, it cannot accumulate.  */
6089       target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp));
6090       if (target)
6091         return target;
6092       break;
6093
6094     case BUILT_IN_STACK_SAVE:
6095       return expand_stack_save ();
6096
6097     case BUILT_IN_STACK_RESTORE:
6098       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6099       return const0_rtx;
6100
6101     case BUILT_IN_BSWAP16:
6102     case BUILT_IN_BSWAP32:
6103     case BUILT_IN_BSWAP64:
6104       target = expand_builtin_bswap (target_mode, exp, target, subtarget);
6105       if (target)
6106         return target;
6107       break;
6108
6109     CASE_INT_FN (BUILT_IN_FFS):
6110     case BUILT_IN_FFSIMAX:
6111       target = expand_builtin_unop (target_mode, exp, target,
6112                                     subtarget, ffs_optab);
6113       if (target)
6114         return target;
6115       break;
6116
6117     CASE_INT_FN (BUILT_IN_CLZ):
6118     case BUILT_IN_CLZIMAX:
6119       target = expand_builtin_unop (target_mode, exp, target,
6120                                     subtarget, clz_optab);
6121       if (target)
6122         return target;
6123       break;
6124
6125     CASE_INT_FN (BUILT_IN_CTZ):
6126     case BUILT_IN_CTZIMAX:
6127       target = expand_builtin_unop (target_mode, exp, target,
6128                                     subtarget, ctz_optab);
6129       if (target)
6130         return target;
6131       break;
6132
6133     CASE_INT_FN (BUILT_IN_CLRSB):
6134     case BUILT_IN_CLRSBIMAX:
6135       target = expand_builtin_unop (target_mode, exp, target,
6136                                     subtarget, clrsb_optab);
6137       if (target)
6138         return target;
6139       break;
6140
6141     CASE_INT_FN (BUILT_IN_POPCOUNT):
6142     case BUILT_IN_POPCOUNTIMAX:
6143       target = expand_builtin_unop (target_mode, exp, target,
6144                                     subtarget, popcount_optab);
6145       if (target)
6146         return target;
6147       break;
6148
6149     CASE_INT_FN (BUILT_IN_PARITY):
6150     case BUILT_IN_PARITYIMAX:
6151       target = expand_builtin_unop (target_mode, exp, target,
6152                                     subtarget, parity_optab);
6153       if (target)
6154         return target;
6155       break;
6156
6157     case BUILT_IN_STRLEN:
6158       target = expand_builtin_strlen (exp, target, target_mode);
6159       if (target)
6160         return target;
6161       break;
6162
6163     case BUILT_IN_STRCPY:
6164       target = expand_builtin_strcpy (exp, target);
6165       if (target)
6166         return target;
6167       break;
6168
6169     case BUILT_IN_STRNCPY:
6170       target = expand_builtin_strncpy (exp, target);
6171       if (target)
6172         return target;
6173       break;
6174
6175     case BUILT_IN_STPCPY:
6176       target = expand_builtin_stpcpy (exp, target, mode);
6177       if (target)
6178         return target;
6179       break;
6180
6181     case BUILT_IN_MEMCPY:
6182       target = expand_builtin_memcpy (exp, target);
6183       if (target)
6184         return target;
6185       break;
6186
6187     case BUILT_IN_MEMPCPY:
6188       target = expand_builtin_mempcpy (exp, target, mode);
6189       if (target)
6190         return target;
6191       break;
6192
6193     case BUILT_IN_MEMSET:
6194       target = expand_builtin_memset (exp, target, mode);
6195       if (target)
6196         return target;
6197       break;
6198
6199     case BUILT_IN_BZERO:
6200       target = expand_builtin_bzero (exp);
6201       if (target)
6202         return target;
6203       break;
6204
6205     case BUILT_IN_STRCMP:
6206       target = expand_builtin_strcmp (exp, target);
6207       if (target)
6208         return target;
6209       break;
6210
6211     case BUILT_IN_STRNCMP:
6212       target = expand_builtin_strncmp (exp, target, mode);
6213       if (target)
6214         return target;
6215       break;
6216
6217     case BUILT_IN_BCMP:
6218     case BUILT_IN_MEMCMP:
6219       target = expand_builtin_memcmp (exp, target, mode);
6220       if (target)
6221         return target;
6222       break;
6223
6224     case BUILT_IN_SETJMP:
6225       /* This should have been lowered to the builtins below.  */
6226       gcc_unreachable ();
6227
6228     case BUILT_IN_SETJMP_SETUP:
6229       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6230           and the receiver label.  */
6231       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6232         {
6233           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6234                                       VOIDmode, EXPAND_NORMAL);
6235           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6236           rtx label_r = label_rtx (label);
6237
6238           /* This is copied from the handling of non-local gotos.  */
6239           expand_builtin_setjmp_setup (buf_addr, label_r);
6240           nonlocal_goto_handler_labels
6241             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6242                                  nonlocal_goto_handler_labels);
6243           /* ??? Do not let expand_label treat us as such since we would
6244              not want to be both on the list of non-local labels and on
6245              the list of forced labels.  */
6246           FORCED_LABEL (label) = 0;
6247           return const0_rtx;
6248         }
6249       break;
6250
6251     case BUILT_IN_SETJMP_DISPATCHER:
6252        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6253       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6254         {
6255           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6256           rtx label_r = label_rtx (label);
6257
6258           /* Remove the dispatcher label from the list of non-local labels
6259              since the receiver labels have been added to it above.  */
6260           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6261           return const0_rtx;
6262         }
6263       break;
6264
6265     case BUILT_IN_SETJMP_RECEIVER:
6266        /* __builtin_setjmp_receiver is passed the receiver label.  */
6267       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6268         {
6269           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6270           rtx label_r = label_rtx (label);
6271
6272           expand_builtin_setjmp_receiver (label_r);
6273           return const0_rtx;
6274         }
6275       break;
6276
6277       /* __builtin_longjmp is passed a pointer to an array of five words.
6278          It's similar to the C library longjmp function but works with
6279          __builtin_setjmp above.  */
6280     case BUILT_IN_LONGJMP:
6281       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6282         {
6283           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6284                                       VOIDmode, EXPAND_NORMAL);
6285           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6286
6287           if (value != const1_rtx)
6288             {
6289               error ("%<__builtin_longjmp%> second argument must be 1");
6290               return const0_rtx;
6291             }
6292
6293           expand_builtin_longjmp (buf_addr, value);
6294           return const0_rtx;
6295         }
6296       break;
6297
6298     case BUILT_IN_NONLOCAL_GOTO:
6299       target = expand_builtin_nonlocal_goto (exp);
6300       if (target)
6301         return target;
6302       break;
6303
6304       /* This updates the setjmp buffer that is its argument with the value
6305          of the current stack pointer.  */
6306     case BUILT_IN_UPDATE_SETJMP_BUF:
6307       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6308         {
6309           rtx buf_addr
6310             = expand_normal (CALL_EXPR_ARG (exp, 0));
6311
6312           expand_builtin_update_setjmp_buf (buf_addr);
6313           return const0_rtx;
6314         }
6315       break;
6316
6317     case BUILT_IN_TRAP:
6318       expand_builtin_trap ();
6319       return const0_rtx;
6320
6321     case BUILT_IN_UNREACHABLE:
6322       expand_builtin_unreachable ();
6323       return const0_rtx;
6324
6325     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6326     case BUILT_IN_SIGNBITD32:
6327     case BUILT_IN_SIGNBITD64:
6328     case BUILT_IN_SIGNBITD128:
6329       target = expand_builtin_signbit (exp, target);
6330       if (target)
6331         return target;
6332       break;
6333
6334       /* Various hooks for the DWARF 2 __throw routine.  */
6335     case BUILT_IN_UNWIND_INIT:
6336       expand_builtin_unwind_init ();
6337       return const0_rtx;
6338     case BUILT_IN_DWARF_CFA:
6339       return virtual_cfa_rtx;
6340 #ifdef DWARF2_UNWIND_INFO
6341     case BUILT_IN_DWARF_SP_COLUMN:
6342       return expand_builtin_dwarf_sp_column ();
6343     case BUILT_IN_INIT_DWARF_REG_SIZES:
6344       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6345       return const0_rtx;
6346 #endif
6347     case BUILT_IN_FROB_RETURN_ADDR:
6348       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6349     case BUILT_IN_EXTRACT_RETURN_ADDR:
6350       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6351     case BUILT_IN_EH_RETURN:
6352       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6353                                 CALL_EXPR_ARG (exp, 1));
6354       return const0_rtx;
6355 #ifdef EH_RETURN_DATA_REGNO
6356     case BUILT_IN_EH_RETURN_DATA_REGNO:
6357       return expand_builtin_eh_return_data_regno (exp);
6358 #endif
6359     case BUILT_IN_EXTEND_POINTER:
6360       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6361     case BUILT_IN_EH_POINTER:
6362       return expand_builtin_eh_pointer (exp);
6363     case BUILT_IN_EH_FILTER:
6364       return expand_builtin_eh_filter (exp);
6365     case BUILT_IN_EH_COPY_VALUES:
6366       return expand_builtin_eh_copy_values (exp);
6367
6368     case BUILT_IN_VA_START:
6369       return expand_builtin_va_start (exp);
6370     case BUILT_IN_VA_END:
6371       return expand_builtin_va_end (exp);
6372     case BUILT_IN_VA_COPY:
6373       return expand_builtin_va_copy (exp);
6374     case BUILT_IN_EXPECT:
6375       return expand_builtin_expect (exp, target);
6376     case BUILT_IN_ASSUME_ALIGNED:
6377       return expand_builtin_assume_aligned (exp, target);
6378     case BUILT_IN_PREFETCH:
6379       expand_builtin_prefetch (exp);
6380       return const0_rtx;
6381
6382     case BUILT_IN_INIT_TRAMPOLINE:
6383       return expand_builtin_init_trampoline (exp, true);
6384     case BUILT_IN_INIT_HEAP_TRAMPOLINE:
6385       return expand_builtin_init_trampoline (exp, false);
6386     case BUILT_IN_ADJUST_TRAMPOLINE:
6387       return expand_builtin_adjust_trampoline (exp);
6388
6389     case BUILT_IN_FORK:
6390     case BUILT_IN_EXECL:
6391     case BUILT_IN_EXECV:
6392     case BUILT_IN_EXECLP:
6393     case BUILT_IN_EXECLE:
6394     case BUILT_IN_EXECVP:
6395     case BUILT_IN_EXECVE:
6396       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6397       if (target)
6398         return target;
6399       break;
6400
6401     case BUILT_IN_SYNC_FETCH_AND_ADD_1:
6402     case BUILT_IN_SYNC_FETCH_AND_ADD_2:
6403     case BUILT_IN_SYNC_FETCH_AND_ADD_4:
6404     case BUILT_IN_SYNC_FETCH_AND_ADD_8:
6405     case BUILT_IN_SYNC_FETCH_AND_ADD_16:
6406       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1);
6407       target = expand_builtin_sync_operation (mode, exp, PLUS, false, target);
6408       if (target)
6409         return target;
6410       break;
6411
6412     case BUILT_IN_SYNC_FETCH_AND_SUB_1:
6413     case BUILT_IN_SYNC_FETCH_AND_SUB_2:
6414     case BUILT_IN_SYNC_FETCH_AND_SUB_4:
6415     case BUILT_IN_SYNC_FETCH_AND_SUB_8:
6416     case BUILT_IN_SYNC_FETCH_AND_SUB_16:
6417       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1);
6418       target = expand_builtin_sync_operation (mode, exp, MINUS, false, target);
6419       if (target)
6420         return target;
6421       break;
6422
6423     case BUILT_IN_SYNC_FETCH_AND_OR_1:
6424     case BUILT_IN_SYNC_FETCH_AND_OR_2:
6425     case BUILT_IN_SYNC_FETCH_AND_OR_4:
6426     case BUILT_IN_SYNC_FETCH_AND_OR_8:
6427     case BUILT_IN_SYNC_FETCH_AND_OR_16:
6428       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1);
6429       target = expand_builtin_sync_operation (mode, exp, IOR, false, target);
6430       if (target)
6431         return target;
6432       break;
6433
6434     case BUILT_IN_SYNC_FETCH_AND_AND_1:
6435     case BUILT_IN_SYNC_FETCH_AND_AND_2:
6436     case BUILT_IN_SYNC_FETCH_AND_AND_4:
6437     case BUILT_IN_SYNC_FETCH_AND_AND_8:
6438     case BUILT_IN_SYNC_FETCH_AND_AND_16:
6439       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1);
6440       target = expand_builtin_sync_operation (mode, exp, AND, false, target);
6441       if (target)
6442         return target;
6443       break;
6444
6445     case BUILT_IN_SYNC_FETCH_AND_XOR_1:
6446     case BUILT_IN_SYNC_FETCH_AND_XOR_2:
6447     case BUILT_IN_SYNC_FETCH_AND_XOR_4:
6448     case BUILT_IN_SYNC_FETCH_AND_XOR_8:
6449     case BUILT_IN_SYNC_FETCH_AND_XOR_16:
6450       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1);
6451       target = expand_builtin_sync_operation (mode, exp, XOR, false, target);
6452       if (target)
6453         return target;
6454       break;
6455
6456     case BUILT_IN_SYNC_FETCH_AND_NAND_1:
6457     case BUILT_IN_SYNC_FETCH_AND_NAND_2:
6458     case BUILT_IN_SYNC_FETCH_AND_NAND_4:
6459     case BUILT_IN_SYNC_FETCH_AND_NAND_8:
6460     case BUILT_IN_SYNC_FETCH_AND_NAND_16:
6461       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1);
6462       target = expand_builtin_sync_operation (mode, exp, NOT, false, target);
6463       if (target)
6464         return target;
6465       break;
6466
6467     case BUILT_IN_SYNC_ADD_AND_FETCH_1:
6468     case BUILT_IN_SYNC_ADD_AND_FETCH_2:
6469     case BUILT_IN_SYNC_ADD_AND_FETCH_4:
6470     case BUILT_IN_SYNC_ADD_AND_FETCH_8:
6471     case BUILT_IN_SYNC_ADD_AND_FETCH_16:
6472       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1);
6473       target = expand_builtin_sync_operation (mode, exp, PLUS, true, target);
6474       if (target)
6475         return target;
6476       break;
6477
6478     case BUILT_IN_SYNC_SUB_AND_FETCH_1:
6479     case BUILT_IN_SYNC_SUB_AND_FETCH_2:
6480     case BUILT_IN_SYNC_SUB_AND_FETCH_4:
6481     case BUILT_IN_SYNC_SUB_AND_FETCH_8:
6482     case BUILT_IN_SYNC_SUB_AND_FETCH_16:
6483       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1);
6484       target = expand_builtin_sync_operation (mode, exp, MINUS, true, target);
6485       if (target)
6486         return target;
6487       break;
6488
6489     case BUILT_IN_SYNC_OR_AND_FETCH_1:
6490     case BUILT_IN_SYNC_OR_AND_FETCH_2:
6491     case BUILT_IN_SYNC_OR_AND_FETCH_4:
6492     case BUILT_IN_SYNC_OR_AND_FETCH_8:
6493     case BUILT_IN_SYNC_OR_AND_FETCH_16:
6494       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1);
6495       target = expand_builtin_sync_operation (mode, exp, IOR, true, target);
6496       if (target)
6497         return target;
6498       break;
6499
6500     case BUILT_IN_SYNC_AND_AND_FETCH_1:
6501     case BUILT_IN_SYNC_AND_AND_FETCH_2:
6502     case BUILT_IN_SYNC_AND_AND_FETCH_4:
6503     case BUILT_IN_SYNC_AND_AND_FETCH_8:
6504     case BUILT_IN_SYNC_AND_AND_FETCH_16:
6505       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1);
6506       target = expand_builtin_sync_operation (mode, exp, AND, true, target);
6507       if (target)
6508         return target;
6509       break;
6510
6511     case BUILT_IN_SYNC_XOR_AND_FETCH_1:
6512     case BUILT_IN_SYNC_XOR_AND_FETCH_2:
6513     case BUILT_IN_SYNC_XOR_AND_FETCH_4:
6514     case BUILT_IN_SYNC_XOR_AND_FETCH_8:
6515     case BUILT_IN_SYNC_XOR_AND_FETCH_16:
6516       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1);
6517       target = expand_builtin_sync_operation (mode, exp, XOR, true, target);
6518       if (target)
6519         return target;
6520       break;
6521
6522     case BUILT_IN_SYNC_NAND_AND_FETCH_1:
6523     case BUILT_IN_SYNC_NAND_AND_FETCH_2:
6524     case BUILT_IN_SYNC_NAND_AND_FETCH_4:
6525     case BUILT_IN_SYNC_NAND_AND_FETCH_8:
6526     case BUILT_IN_SYNC_NAND_AND_FETCH_16:
6527       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1);
6528       target = expand_builtin_sync_operation (mode, exp, NOT, true, target);
6529       if (target)
6530         return target;
6531       break;
6532
6533     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
6534     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
6535     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
6536     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
6537     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
6538       if (mode == VOIDmode)
6539         mode = TYPE_MODE (boolean_type_node);
6540       if (!target || !register_operand (target, mode))
6541         target = gen_reg_rtx (mode);
6542
6543       mode = get_builtin_sync_mode 
6544                                 (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1);
6545       target = expand_builtin_compare_and_swap (mode, exp, true, target);
6546       if (target)
6547         return target;
6548       break;
6549
6550     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
6551     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
6552     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
6553     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
6554     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
6555       mode = get_builtin_sync_mode 
6556                                 (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1);
6557       target = expand_builtin_compare_and_swap (mode, exp, false, target);
6558       if (target)
6559         return target;
6560       break;
6561
6562     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
6563     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
6564     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
6565     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
6566     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
6567       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1);
6568       target = expand_builtin_sync_lock_test_and_set (mode, exp, target);
6569       if (target)
6570         return target;
6571       break;
6572
6573     case BUILT_IN_SYNC_LOCK_RELEASE_1:
6574     case BUILT_IN_SYNC_LOCK_RELEASE_2:
6575     case BUILT_IN_SYNC_LOCK_RELEASE_4:
6576     case BUILT_IN_SYNC_LOCK_RELEASE_8:
6577     case BUILT_IN_SYNC_LOCK_RELEASE_16:
6578       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1);
6579       expand_builtin_sync_lock_release (mode, exp);
6580       return const0_rtx;
6581
6582     case BUILT_IN_SYNC_SYNCHRONIZE:
6583       expand_builtin_sync_synchronize ();
6584       return const0_rtx;
6585
6586     case BUILT_IN_ATOMIC_EXCHANGE_1:
6587     case BUILT_IN_ATOMIC_EXCHANGE_2:
6588     case BUILT_IN_ATOMIC_EXCHANGE_4:
6589     case BUILT_IN_ATOMIC_EXCHANGE_8:
6590     case BUILT_IN_ATOMIC_EXCHANGE_16:
6591       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1);
6592       target = expand_builtin_atomic_exchange (mode, exp, target);
6593       if (target)
6594         return target;
6595       break;
6596
6597     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
6598     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
6599     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
6600     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
6601     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
6602       {
6603         unsigned int nargs, z;
6604         vec<tree, va_gc> *vec;
6605
6606         mode = 
6607             get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
6608         target = expand_builtin_atomic_compare_exchange (mode, exp, target);
6609         if (target)
6610           return target;
6611
6612         /* If this is turned into an external library call, the weak parameter
6613            must be dropped to match the expected parameter list.  */
6614         nargs = call_expr_nargs (exp);
6615         vec_alloc (vec, nargs - 1);
6616         for (z = 0; z < 3; z++)
6617           vec->quick_push (CALL_EXPR_ARG (exp, z));
6618         /* Skip the boolean weak parameter.  */
6619         for (z = 4; z < 6; z++)
6620           vec->quick_push (CALL_EXPR_ARG (exp, z));
6621         exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
6622         break;
6623       }
6624
6625     case BUILT_IN_ATOMIC_LOAD_1:
6626     case BUILT_IN_ATOMIC_LOAD_2:
6627     case BUILT_IN_ATOMIC_LOAD_4:
6628     case BUILT_IN_ATOMIC_LOAD_8:
6629     case BUILT_IN_ATOMIC_LOAD_16:
6630       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1);
6631       target = expand_builtin_atomic_load (mode, exp, target);
6632       if (target)
6633         return target;
6634       break;
6635
6636     case BUILT_IN_ATOMIC_STORE_1:
6637     case BUILT_IN_ATOMIC_STORE_2:
6638     case BUILT_IN_ATOMIC_STORE_4:
6639     case BUILT_IN_ATOMIC_STORE_8:
6640     case BUILT_IN_ATOMIC_STORE_16:
6641       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1);
6642       target = expand_builtin_atomic_store (mode, exp);
6643       if (target)
6644         return const0_rtx;
6645       break;
6646
6647     case BUILT_IN_ATOMIC_ADD_FETCH_1:
6648     case BUILT_IN_ATOMIC_ADD_FETCH_2:
6649     case BUILT_IN_ATOMIC_ADD_FETCH_4:
6650     case BUILT_IN_ATOMIC_ADD_FETCH_8:
6651     case BUILT_IN_ATOMIC_ADD_FETCH_16:
6652       {
6653         enum built_in_function lib;
6654         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1);
6655         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 + 
6656                                        (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1));
6657         target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true,
6658                                                  ignore, lib);
6659         if (target)
6660           return target;
6661         break;
6662       }
6663     case BUILT_IN_ATOMIC_SUB_FETCH_1:
6664     case BUILT_IN_ATOMIC_SUB_FETCH_2:
6665     case BUILT_IN_ATOMIC_SUB_FETCH_4:
6666     case BUILT_IN_ATOMIC_SUB_FETCH_8:
6667     case BUILT_IN_ATOMIC_SUB_FETCH_16:
6668       {
6669         enum built_in_function lib;
6670         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1);
6671         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 + 
6672                                        (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1));
6673         target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true,
6674                                                  ignore, lib);
6675         if (target)
6676           return target;
6677         break;
6678       }
6679     case BUILT_IN_ATOMIC_AND_FETCH_1:
6680     case BUILT_IN_ATOMIC_AND_FETCH_2:
6681     case BUILT_IN_ATOMIC_AND_FETCH_4:
6682     case BUILT_IN_ATOMIC_AND_FETCH_8:
6683     case BUILT_IN_ATOMIC_AND_FETCH_16:
6684       {
6685         enum built_in_function lib;
6686         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1);
6687         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 + 
6688                                        (fcode - BUILT_IN_ATOMIC_AND_FETCH_1));
6689         target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true,
6690                                                  ignore, lib);
6691         if (target)
6692           return target;
6693         break;
6694       }
6695     case BUILT_IN_ATOMIC_NAND_FETCH_1:
6696     case BUILT_IN_ATOMIC_NAND_FETCH_2:
6697     case BUILT_IN_ATOMIC_NAND_FETCH_4:
6698     case BUILT_IN_ATOMIC_NAND_FETCH_8:
6699     case BUILT_IN_ATOMIC_NAND_FETCH_16:
6700       {
6701         enum built_in_function lib;
6702         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1);
6703         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 + 
6704                                        (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1));
6705         target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true,
6706                                                  ignore, lib);
6707         if (target)
6708           return target;
6709         break;
6710       }
6711     case BUILT_IN_ATOMIC_XOR_FETCH_1:
6712     case BUILT_IN_ATOMIC_XOR_FETCH_2:
6713     case BUILT_IN_ATOMIC_XOR_FETCH_4:
6714     case BUILT_IN_ATOMIC_XOR_FETCH_8:
6715     case BUILT_IN_ATOMIC_XOR_FETCH_16:
6716       {
6717         enum built_in_function lib;
6718         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1);
6719         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 + 
6720                                        (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1));
6721         target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true,
6722                                                  ignore, lib);
6723         if (target)
6724           return target;
6725         break;
6726       }
6727     case BUILT_IN_ATOMIC_OR_FETCH_1:
6728     case BUILT_IN_ATOMIC_OR_FETCH_2:
6729     case BUILT_IN_ATOMIC_OR_FETCH_4:
6730     case BUILT_IN_ATOMIC_OR_FETCH_8:
6731     case BUILT_IN_ATOMIC_OR_FETCH_16:
6732       {
6733         enum built_in_function lib;
6734         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1);
6735         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 + 
6736                                        (fcode - BUILT_IN_ATOMIC_OR_FETCH_1));
6737         target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true,
6738                                                  ignore, lib);
6739         if (target)
6740           return target;
6741         break;
6742       }
6743     case BUILT_IN_ATOMIC_FETCH_ADD_1:
6744     case BUILT_IN_ATOMIC_FETCH_ADD_2:
6745     case BUILT_IN_ATOMIC_FETCH_ADD_4:
6746     case BUILT_IN_ATOMIC_FETCH_ADD_8:
6747     case BUILT_IN_ATOMIC_FETCH_ADD_16:
6748       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1);
6749       target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false,
6750                                                ignore, BUILT_IN_NONE);
6751       if (target)
6752         return target;
6753       break;
6754  
6755     case BUILT_IN_ATOMIC_FETCH_SUB_1:
6756     case BUILT_IN_ATOMIC_FETCH_SUB_2:
6757     case BUILT_IN_ATOMIC_FETCH_SUB_4:
6758     case BUILT_IN_ATOMIC_FETCH_SUB_8:
6759     case BUILT_IN_ATOMIC_FETCH_SUB_16:
6760       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1);
6761       target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false,
6762                                                ignore, BUILT_IN_NONE);
6763       if (target)
6764         return target;
6765       break;
6766
6767     case BUILT_IN_ATOMIC_FETCH_AND_1:
6768     case BUILT_IN_ATOMIC_FETCH_AND_2:
6769     case BUILT_IN_ATOMIC_FETCH_AND_4:
6770     case BUILT_IN_ATOMIC_FETCH_AND_8:
6771     case BUILT_IN_ATOMIC_FETCH_AND_16:
6772       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1);
6773       target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false,
6774                                                ignore, BUILT_IN_NONE);
6775       if (target)
6776         return target;
6777       break;
6778   
6779     case BUILT_IN_ATOMIC_FETCH_NAND_1:
6780     case BUILT_IN_ATOMIC_FETCH_NAND_2:
6781     case BUILT_IN_ATOMIC_FETCH_NAND_4:
6782     case BUILT_IN_ATOMIC_FETCH_NAND_8:
6783     case BUILT_IN_ATOMIC_FETCH_NAND_16:
6784       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1);
6785       target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false,
6786                                                ignore, BUILT_IN_NONE);
6787       if (target)
6788         return target;
6789       break;
6790  
6791     case BUILT_IN_ATOMIC_FETCH_XOR_1:
6792     case BUILT_IN_ATOMIC_FETCH_XOR_2:
6793     case BUILT_IN_ATOMIC_FETCH_XOR_4:
6794     case BUILT_IN_ATOMIC_FETCH_XOR_8:
6795     case BUILT_IN_ATOMIC_FETCH_XOR_16:
6796       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1);
6797       target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false,
6798                                                ignore, BUILT_IN_NONE);
6799       if (target)
6800         return target;
6801       break;
6802  
6803     case BUILT_IN_ATOMIC_FETCH_OR_1:
6804     case BUILT_IN_ATOMIC_FETCH_OR_2:
6805     case BUILT_IN_ATOMIC_FETCH_OR_4:
6806     case BUILT_IN_ATOMIC_FETCH_OR_8:
6807     case BUILT_IN_ATOMIC_FETCH_OR_16:
6808       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1);
6809       target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false,
6810                                                ignore, BUILT_IN_NONE);
6811       if (target)
6812         return target;
6813       break;
6814
6815     case BUILT_IN_ATOMIC_TEST_AND_SET:
6816       return expand_builtin_atomic_test_and_set (exp, target);
6817
6818     case BUILT_IN_ATOMIC_CLEAR:
6819       return expand_builtin_atomic_clear (exp);
6820  
6821     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
6822       return expand_builtin_atomic_always_lock_free (exp);
6823
6824     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
6825       target = expand_builtin_atomic_is_lock_free (exp);
6826       if (target)
6827         return target;
6828       break;
6829
6830     case BUILT_IN_ATOMIC_THREAD_FENCE:
6831       expand_builtin_atomic_thread_fence (exp);
6832       return const0_rtx;
6833
6834     case BUILT_IN_ATOMIC_SIGNAL_FENCE:
6835       expand_builtin_atomic_signal_fence (exp);
6836       return const0_rtx;
6837
6838     case BUILT_IN_OBJECT_SIZE:
6839       return expand_builtin_object_size (exp);
6840
6841     case BUILT_IN_MEMCPY_CHK:
6842     case BUILT_IN_MEMPCPY_CHK:
6843     case BUILT_IN_MEMMOVE_CHK:
6844     case BUILT_IN_MEMSET_CHK:
6845       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6846       if (target)
6847         return target;
6848       break;
6849
6850     case BUILT_IN_STRCPY_CHK:
6851     case BUILT_IN_STPCPY_CHK:
6852     case BUILT_IN_STRNCPY_CHK:
6853     case BUILT_IN_STPNCPY_CHK:
6854     case BUILT_IN_STRCAT_CHK:
6855     case BUILT_IN_STRNCAT_CHK:
6856     case BUILT_IN_SNPRINTF_CHK:
6857     case BUILT_IN_VSNPRINTF_CHK:
6858       maybe_emit_chk_warning (exp, fcode);
6859       break;
6860
6861     case BUILT_IN_SPRINTF_CHK:
6862     case BUILT_IN_VSPRINTF_CHK:
6863       maybe_emit_sprintf_chk_warning (exp, fcode);
6864       break;
6865
6866     case BUILT_IN_FREE:
6867       if (warn_free_nonheap_object)
6868         maybe_emit_free_warning (exp);
6869       break;
6870
6871     case BUILT_IN_THREAD_POINTER:
6872       return expand_builtin_thread_pointer (exp, target);
6873
6874     case BUILT_IN_SET_THREAD_POINTER:
6875       expand_builtin_set_thread_pointer (exp);
6876       return const0_rtx;
6877
6878     default:    /* just do library call, if unknown builtin */
6879       break;
6880     }
6881
6882   /* The switch statement above can drop through to cause the function
6883      to be called normally.  */
6884   return expand_call (exp, target, ignore);
6885 }
6886
6887 /* Determine whether a tree node represents a call to a built-in
6888    function.  If the tree T is a call to a built-in function with
6889    the right number of arguments of the appropriate types, return
6890    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6891    Otherwise the return value is END_BUILTINS.  */
6892
6893 enum built_in_function
6894 builtin_mathfn_code (const_tree t)
6895 {
6896   const_tree fndecl, arg, parmlist;
6897   const_tree argtype, parmtype;
6898   const_call_expr_arg_iterator iter;
6899
6900   if (TREE_CODE (t) != CALL_EXPR
6901       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6902     return END_BUILTINS;
6903
6904   fndecl = get_callee_fndecl (t);
6905   if (fndecl == NULL_TREE
6906       || TREE_CODE (fndecl) != FUNCTION_DECL
6907       || ! DECL_BUILT_IN (fndecl)
6908       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6909     return END_BUILTINS;
6910
6911   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6912   init_const_call_expr_arg_iterator (t, &iter);
6913   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6914     {
6915       /* If a function doesn't take a variable number of arguments,
6916          the last element in the list will have type `void'.  */
6917       parmtype = TREE_VALUE (parmlist);
6918       if (VOID_TYPE_P (parmtype))
6919         {
6920           if (more_const_call_expr_args_p (&iter))
6921             return END_BUILTINS;
6922           return DECL_FUNCTION_CODE (fndecl);
6923         }
6924
6925       if (! more_const_call_expr_args_p (&iter))
6926         return END_BUILTINS;
6927
6928       arg = next_const_call_expr_arg (&iter);
6929       argtype = TREE_TYPE (arg);
6930
6931       if (SCALAR_FLOAT_TYPE_P (parmtype))
6932         {
6933           if (! SCALAR_FLOAT_TYPE_P (argtype))
6934             return END_BUILTINS;
6935         }
6936       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6937         {
6938           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6939             return END_BUILTINS;
6940         }
6941       else if (POINTER_TYPE_P (parmtype))
6942         {
6943           if (! POINTER_TYPE_P (argtype))
6944             return END_BUILTINS;
6945         }
6946       else if (INTEGRAL_TYPE_P (parmtype))
6947         {
6948           if (! INTEGRAL_TYPE_P (argtype))
6949             return END_BUILTINS;
6950         }
6951       else
6952         return END_BUILTINS;
6953     }
6954
6955   /* Variable-length argument list.  */
6956   return DECL_FUNCTION_CODE (fndecl);
6957 }
6958
6959 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
6960    evaluate to a constant.  */
6961
6962 static tree
6963 fold_builtin_constant_p (tree arg)
6964 {
6965   /* We return 1 for a numeric type that's known to be a constant
6966      value at compile-time or for an aggregate type that's a
6967      literal constant.  */
6968   STRIP_NOPS (arg);
6969
6970   /* If we know this is a constant, emit the constant of one.  */
6971   if (CONSTANT_CLASS_P (arg)
6972       || (TREE_CODE (arg) == CONSTRUCTOR
6973           && TREE_CONSTANT (arg)))
6974     return integer_one_node;
6975   if (TREE_CODE (arg) == ADDR_EXPR)
6976     {
6977        tree op = TREE_OPERAND (arg, 0);
6978        if (TREE_CODE (op) == STRING_CST
6979            || (TREE_CODE (op) == ARRAY_REF
6980                && integer_zerop (TREE_OPERAND (op, 1))
6981                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6982          return integer_one_node;
6983     }
6984
6985   /* If this expression has side effects, show we don't know it to be a
6986      constant.  Likewise if it's a pointer or aggregate type since in
6987      those case we only want literals, since those are only optimized
6988      when generating RTL, not later.
6989      And finally, if we are compiling an initializer, not code, we
6990      need to return a definite result now; there's not going to be any
6991      more optimization done.  */
6992   if (TREE_SIDE_EFFECTS (arg)
6993       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6994       || POINTER_TYPE_P (TREE_TYPE (arg))
6995       || cfun == 0
6996       || folding_initializer
6997       || force_folding_builtin_constant_p)
6998     return integer_zero_node;
6999
7000   return NULL_TREE;
7001 }
7002
7003 /* Create builtin_expect with PRED and EXPECTED as its arguments and
7004    return it as a truthvalue.  */
7005
7006 static tree
7007 build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
7008 {
7009   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
7010
7011   fn = builtin_decl_explicit (BUILT_IN_EXPECT);
7012   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7013   ret_type = TREE_TYPE (TREE_TYPE (fn));
7014   pred_type = TREE_VALUE (arg_types);
7015   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7016
7017   pred = fold_convert_loc (loc, pred_type, pred);
7018   expected = fold_convert_loc (loc, expected_type, expected);
7019   call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
7020
7021   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7022                  build_int_cst (ret_type, 0));
7023 }
7024
7025 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
7026    NULL_TREE if no simplification is possible.  */
7027
7028 static tree
7029 fold_builtin_expect (location_t loc, tree arg0, tree arg1)
7030 {
7031   tree inner, fndecl, inner_arg0;
7032   enum tree_code code;
7033
7034   /* Distribute the expected value over short-circuiting operators.
7035      See through the cast from truthvalue_type_node to long.  */
7036   inner_arg0 = arg0;
7037   while (TREE_CODE (inner_arg0) == NOP_EXPR
7038          && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0))
7039          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0))))
7040     inner_arg0 = TREE_OPERAND (inner_arg0, 0);
7041
7042   /* If this is a builtin_expect within a builtin_expect keep the
7043      inner one.  See through a comparison against a constant.  It
7044      might have been added to create a thruthvalue.  */
7045   inner = inner_arg0;
7046
7047   if (COMPARISON_CLASS_P (inner)
7048       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7049     inner = TREE_OPERAND (inner, 0);
7050
7051   if (TREE_CODE (inner) == CALL_EXPR
7052       && (fndecl = get_callee_fndecl (inner))
7053       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7054       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7055     return arg0;
7056
7057   inner = inner_arg0;
7058   code = TREE_CODE (inner);
7059   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7060     {
7061       tree op0 = TREE_OPERAND (inner, 0);
7062       tree op1 = TREE_OPERAND (inner, 1);
7063
7064       op0 = build_builtin_expect_predicate (loc, op0, arg1);
7065       op1 = build_builtin_expect_predicate (loc, op1, arg1);
7066       inner = build2 (code, TREE_TYPE (inner), op0, op1);
7067
7068       return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
7069     }
7070
7071   /* If the argument isn't invariant then there's nothing else we can do.  */
7072   if (!TREE_CONSTANT (inner_arg0))
7073     return NULL_TREE;
7074
7075   /* If we expect that a comparison against the argument will fold to
7076      a constant return the constant.  In practice, this means a true
7077      constant or the address of a non-weak symbol.  */
7078   inner = inner_arg0;
7079   STRIP_NOPS (inner);
7080   if (TREE_CODE (inner) == ADDR_EXPR)
7081     {
7082       do
7083         {
7084           inner = TREE_OPERAND (inner, 0);
7085         }
7086       while (TREE_CODE (inner) == COMPONENT_REF
7087              || TREE_CODE (inner) == ARRAY_REF);
7088       if ((TREE_CODE (inner) == VAR_DECL
7089            || TREE_CODE (inner) == FUNCTION_DECL)
7090           && DECL_WEAK (inner))
7091         return NULL_TREE;
7092     }
7093
7094   /* Otherwise, ARG0 already has the proper type for the return value.  */
7095   return arg0;
7096 }
7097
7098 /* Fold a call to __builtin_classify_type with argument ARG.  */
7099
7100 static tree
7101 fold_builtin_classify_type (tree arg)
7102 {
7103   if (arg == 0)
7104     return build_int_cst (integer_type_node, no_type_class);
7105
7106   return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg)));
7107 }
7108
7109 /* Fold a call to __builtin_strlen with argument ARG.  */
7110
7111 static tree
7112 fold_builtin_strlen (location_t loc, tree type, tree arg)
7113 {
7114   if (!validate_arg (arg, POINTER_TYPE))
7115     return NULL_TREE;
7116   else
7117     {
7118       tree len = c_strlen (arg, 0);
7119
7120       if (len)
7121         return fold_convert_loc (loc, type, len);
7122
7123       return NULL_TREE;
7124     }
7125 }
7126
7127 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
7128
7129 static tree
7130 fold_builtin_inf (location_t loc, tree type, int warn)
7131 {
7132   REAL_VALUE_TYPE real;
7133
7134   /* __builtin_inff is intended to be usable to define INFINITY on all
7135      targets.  If an infinity is not available, INFINITY expands "to a
7136      positive constant of type float that overflows at translation
7137      time", footnote "In this case, using INFINITY will violate the
7138      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7139      Thus we pedwarn to ensure this constraint violation is
7140      diagnosed.  */
7141   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7142     pedwarn (loc, 0, "target format does not support infinity");
7143
7144   real_inf (&real);
7145   return build_real (type, real);
7146 }
7147
7148 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7149
7150 static tree
7151 fold_builtin_nan (tree arg, tree type, int quiet)
7152 {
7153   REAL_VALUE_TYPE real;
7154   const char *str;
7155
7156   if (!validate_arg (arg, POINTER_TYPE))
7157     return NULL_TREE;
7158   str = c_getstr (arg);
7159   if (!str)
7160     return NULL_TREE;
7161
7162   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7163     return NULL_TREE;
7164
7165   return build_real (type, real);
7166 }
7167
7168 /* Return true if the floating point expression T has an integer value.
7169    We also allow +Inf, -Inf and NaN to be considered integer values.  */
7170
7171 static bool
7172 integer_valued_real_p (tree t)
7173 {
7174   switch (TREE_CODE (t))
7175     {
7176     case FLOAT_EXPR:
7177       return true;
7178
7179     case ABS_EXPR:
7180     case SAVE_EXPR:
7181       return integer_valued_real_p (TREE_OPERAND (t, 0));
7182
7183     case COMPOUND_EXPR:
7184     case MODIFY_EXPR:
7185     case BIND_EXPR:
7186       return integer_valued_real_p (TREE_OPERAND (t, 1));
7187
7188     case PLUS_EXPR:
7189     case MINUS_EXPR:
7190     case MULT_EXPR:
7191     case MIN_EXPR:
7192     case MAX_EXPR:
7193       return integer_valued_real_p (TREE_OPERAND (t, 0))
7194              && integer_valued_real_p (TREE_OPERAND (t, 1));
7195
7196     case COND_EXPR:
7197       return integer_valued_real_p (TREE_OPERAND (t, 1))
7198              && integer_valued_real_p (TREE_OPERAND (t, 2));
7199
7200     case REAL_CST:
7201       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7202
7203     case NOP_EXPR:
7204       {
7205         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7206         if (TREE_CODE (type) == INTEGER_TYPE)
7207           return true;
7208         if (TREE_CODE (type) == REAL_TYPE)
7209           return integer_valued_real_p (TREE_OPERAND (t, 0));
7210         break;
7211       }
7212
7213     case CALL_EXPR:
7214       switch (builtin_mathfn_code (t))
7215         {
7216         CASE_FLT_FN (BUILT_IN_CEIL):
7217         CASE_FLT_FN (BUILT_IN_FLOOR):
7218         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7219         CASE_FLT_FN (BUILT_IN_RINT):
7220         CASE_FLT_FN (BUILT_IN_ROUND):
7221         CASE_FLT_FN (BUILT_IN_TRUNC):
7222           return true;
7223
7224         CASE_FLT_FN (BUILT_IN_FMIN):
7225         CASE_FLT_FN (BUILT_IN_FMAX):
7226           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7227             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7228
7229         default:
7230           break;
7231         }
7232       break;
7233
7234     default:
7235       break;
7236     }
7237   return false;
7238 }
7239
7240 /* FNDECL is assumed to be a builtin where truncation can be propagated
7241    across (for instance floor((double)f) == (double)floorf (f).
7242    Do the transformation for a call with argument ARG.  */
7243
7244 static tree
7245 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7246 {
7247   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7248
7249   if (!validate_arg (arg, REAL_TYPE))
7250     return NULL_TREE;
7251
7252   /* Integer rounding functions are idempotent.  */
7253   if (fcode == builtin_mathfn_code (arg))
7254     return arg;
7255
7256   /* If argument is already integer valued, and we don't need to worry
7257      about setting errno, there's no need to perform rounding.  */
7258   if (! flag_errno_math && integer_valued_real_p (arg))
7259     return arg;
7260
7261   if (optimize)
7262     {
7263       tree arg0 = strip_float_extensions (arg);
7264       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7265       tree newtype = TREE_TYPE (arg0);
7266       tree decl;
7267
7268       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7269           && (decl = mathfn_built_in (newtype, fcode)))
7270         return fold_convert_loc (loc, ftype,
7271                                  build_call_expr_loc (loc, decl, 1,
7272                                                   fold_convert_loc (loc,
7273                                                                     newtype,
7274                                                                     arg0)));
7275     }
7276   return NULL_TREE;
7277 }
7278
7279 /* FNDECL is assumed to be builtin which can narrow the FP type of
7280    the argument, for instance lround((double)f) -> lroundf (f).
7281    Do the transformation for a call with argument ARG.  */
7282
7283 static tree
7284 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7285 {
7286   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7287
7288   if (!validate_arg (arg, REAL_TYPE))
7289     return NULL_TREE;
7290
7291   /* If argument is already integer valued, and we don't need to worry
7292      about setting errno, there's no need to perform rounding.  */
7293   if (! flag_errno_math && integer_valued_real_p (arg))
7294     return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7295                         TREE_TYPE (TREE_TYPE (fndecl)), arg);
7296
7297   if (optimize)
7298     {
7299       tree ftype = TREE_TYPE (arg);
7300       tree arg0 = strip_float_extensions (arg);
7301       tree newtype = TREE_TYPE (arg0);
7302       tree decl;
7303
7304       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7305           && (decl = mathfn_built_in (newtype, fcode)))
7306         return build_call_expr_loc (loc, decl, 1,
7307                                 fold_convert_loc (loc, newtype, arg0));
7308     }
7309
7310   /* Canonicalize iround (x) to lround (x) on ILP32 targets where
7311      sizeof (int) == sizeof (long).  */
7312   if (TYPE_PRECISION (integer_type_node)
7313       == TYPE_PRECISION (long_integer_type_node))
7314     {
7315       tree newfn = NULL_TREE;
7316       switch (fcode)
7317         {
7318         CASE_FLT_FN (BUILT_IN_ICEIL):
7319           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7320           break;
7321
7322         CASE_FLT_FN (BUILT_IN_IFLOOR):
7323           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7324           break;
7325
7326         CASE_FLT_FN (BUILT_IN_IROUND):
7327           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7328           break;
7329
7330         CASE_FLT_FN (BUILT_IN_IRINT):
7331           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7332           break;
7333
7334         default:
7335           break;
7336         }
7337
7338       if (newfn)
7339         {
7340           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7341           return fold_convert_loc (loc,
7342                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7343         }
7344     }
7345
7346   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7347      sizeof (long long) == sizeof (long).  */
7348   if (TYPE_PRECISION (long_long_integer_type_node)
7349       == TYPE_PRECISION (long_integer_type_node))
7350     {
7351       tree newfn = NULL_TREE;
7352       switch (fcode)
7353         {
7354         CASE_FLT_FN (BUILT_IN_LLCEIL):
7355           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7356           break;
7357
7358         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7359           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7360           break;
7361
7362         CASE_FLT_FN (BUILT_IN_LLROUND):
7363           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7364           break;
7365
7366         CASE_FLT_FN (BUILT_IN_LLRINT):
7367           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7368           break;
7369
7370         default:
7371           break;
7372         }
7373
7374       if (newfn)
7375         {
7376           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7377           return fold_convert_loc (loc,
7378                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7379         }
7380     }
7381
7382   return NULL_TREE;
7383 }
7384
7385 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7386    return type.  Return NULL_TREE if no simplification can be made.  */
7387
7388 static tree
7389 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7390 {
7391   tree res;
7392
7393   if (!validate_arg (arg, COMPLEX_TYPE)
7394       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7395     return NULL_TREE;
7396
7397   /* Calculate the result when the argument is a constant.  */
7398   if (TREE_CODE (arg) == COMPLEX_CST
7399       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7400                               type, mpfr_hypot)))
7401     return res;
7402
7403   if (TREE_CODE (arg) == COMPLEX_EXPR)
7404     {
7405       tree real = TREE_OPERAND (arg, 0);
7406       tree imag = TREE_OPERAND (arg, 1);
7407
7408       /* If either part is zero, cabs is fabs of the other.  */
7409       if (real_zerop (real))
7410         return fold_build1_loc (loc, ABS_EXPR, type, imag);
7411       if (real_zerop (imag))
7412         return fold_build1_loc (loc, ABS_EXPR, type, real);
7413
7414       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7415       if (flag_unsafe_math_optimizations
7416           && operand_equal_p (real, imag, OEP_PURE_SAME))
7417         {
7418           const REAL_VALUE_TYPE sqrt2_trunc
7419             = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7420           STRIP_NOPS (real);
7421           return fold_build2_loc (loc, MULT_EXPR, type,
7422                               fold_build1_loc (loc, ABS_EXPR, type, real),
7423                               build_real (type, sqrt2_trunc));
7424         }
7425     }
7426
7427   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7428   if (TREE_CODE (arg) == NEGATE_EXPR
7429       || TREE_CODE (arg) == CONJ_EXPR)
7430     return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7431
7432   /* Don't do this when optimizing for size.  */
7433   if (flag_unsafe_math_optimizations
7434       && optimize && optimize_function_for_speed_p (cfun))
7435     {
7436       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7437
7438       if (sqrtfn != NULL_TREE)
7439         {
7440           tree rpart, ipart, result;
7441
7442           arg = builtin_save_expr (arg);
7443
7444           rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7445           ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7446
7447           rpart = builtin_save_expr (rpart);
7448           ipart = builtin_save_expr (ipart);
7449
7450           result = fold_build2_loc (loc, PLUS_EXPR, type,
7451                                 fold_build2_loc (loc, MULT_EXPR, type,
7452                                              rpart, rpart),
7453                                 fold_build2_loc (loc, MULT_EXPR, type,
7454                                              ipart, ipart));
7455
7456           return build_call_expr_loc (loc, sqrtfn, 1, result);
7457         }
7458     }
7459
7460   return NULL_TREE;
7461 }
7462
7463 /* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
7464    complex tree type of the result.  If NEG is true, the imaginary
7465    zero is negative.  */
7466
7467 static tree
7468 build_complex_cproj (tree type, bool neg)
7469 {
7470   REAL_VALUE_TYPE rinf, rzero = dconst0;
7471   
7472   real_inf (&rinf);
7473   rzero.sign = neg;
7474   return build_complex (type, build_real (TREE_TYPE (type), rinf),
7475                         build_real (TREE_TYPE (type), rzero));
7476 }
7477
7478 /* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
7479    return type.  Return NULL_TREE if no simplification can be made.  */
7480
7481 static tree
7482 fold_builtin_cproj (location_t loc, tree arg, tree type)
7483 {
7484   if (!validate_arg (arg, COMPLEX_TYPE)
7485       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7486     return NULL_TREE;
7487
7488   /* If there are no infinities, return arg.  */
7489   if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
7490     return non_lvalue_loc (loc, arg);
7491
7492   /* Calculate the result when the argument is a constant.  */
7493   if (TREE_CODE (arg) == COMPLEX_CST)
7494     {
7495       const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
7496       const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
7497       
7498       if (real_isinf (real) || real_isinf (imag))
7499         return build_complex_cproj (type, imag->sign);
7500       else
7501         return arg;
7502     }
7503   else if (TREE_CODE (arg) == COMPLEX_EXPR)
7504     {
7505       tree real = TREE_OPERAND (arg, 0);
7506       tree imag = TREE_OPERAND (arg, 1);
7507
7508       STRIP_NOPS (real);
7509       STRIP_NOPS (imag);
7510       
7511       /* If the real part is inf and the imag part is known to be
7512          nonnegative, return (inf + 0i).  Remember side-effects are
7513          possible in the imag part.  */
7514       if (TREE_CODE (real) == REAL_CST
7515           && real_isinf (TREE_REAL_CST_PTR (real))
7516           && tree_expr_nonnegative_p (imag))
7517         return omit_one_operand_loc (loc, type,
7518                                      build_complex_cproj (type, false),
7519                                      arg);
7520       
7521       /* If the imag part is inf, return (inf+I*copysign(0,imag)).
7522          Remember side-effects are possible in the real part.  */
7523       if (TREE_CODE (imag) == REAL_CST
7524           && real_isinf (TREE_REAL_CST_PTR (imag)))
7525         return
7526           omit_one_operand_loc (loc, type,
7527                                 build_complex_cproj (type, TREE_REAL_CST_PTR
7528                                                      (imag)->sign), arg);
7529     }
7530
7531   return NULL_TREE;
7532 }
7533
7534 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7535    Return NULL_TREE if no simplification can be made.  */
7536
7537 static tree
7538 fold_builtin_sqrt (location_t loc, tree arg, tree type)
7539 {
7540
7541   enum built_in_function fcode;
7542   tree res;
7543
7544   if (!validate_arg (arg, REAL_TYPE))
7545     return NULL_TREE;
7546
7547   /* Calculate the result when the argument is a constant.  */
7548   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7549     return res;
7550
7551   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7552   fcode = builtin_mathfn_code (arg);
7553   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7554     {
7555       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7556       arg = fold_build2_loc (loc, MULT_EXPR, type,
7557                          CALL_EXPR_ARG (arg, 0),
7558                          build_real (type, dconsthalf));
7559       return build_call_expr_loc (loc, expfn, 1, arg);
7560     }
7561
7562   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7563   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7564     {
7565       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7566
7567       if (powfn)
7568         {
7569           tree arg0 = CALL_EXPR_ARG (arg, 0);
7570           tree tree_root;
7571           /* The inner root was either sqrt or cbrt.  */
7572           /* This was a conditional expression but it triggered a bug
7573              in Sun C 5.5.  */
7574           REAL_VALUE_TYPE dconstroot;
7575           if (BUILTIN_SQRT_P (fcode))
7576             dconstroot = dconsthalf;
7577           else
7578             dconstroot = dconst_third ();
7579
7580           /* Adjust for the outer root.  */
7581           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7582           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7583           tree_root = build_real (type, dconstroot);
7584           return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7585         }
7586     }
7587
7588   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7589   if (flag_unsafe_math_optimizations
7590       && (fcode == BUILT_IN_POW
7591           || fcode == BUILT_IN_POWF
7592           || fcode == BUILT_IN_POWL))
7593     {
7594       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7595       tree arg0 = CALL_EXPR_ARG (arg, 0);
7596       tree arg1 = CALL_EXPR_ARG (arg, 1);
7597       tree narg1;
7598       if (!tree_expr_nonnegative_p (arg0))
7599         arg0 = build1 (ABS_EXPR, type, arg0);
7600       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7601                            build_real (type, dconsthalf));
7602       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7603     }
7604
7605   return NULL_TREE;
7606 }
7607
7608 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7609    Return NULL_TREE if no simplification can be made.  */
7610
7611 static tree
7612 fold_builtin_cbrt (location_t loc, tree arg, tree type)
7613 {
7614   const enum built_in_function fcode = builtin_mathfn_code (arg);
7615   tree res;
7616
7617   if (!validate_arg (arg, REAL_TYPE))
7618     return NULL_TREE;
7619
7620   /* Calculate the result when the argument is a constant.  */
7621   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7622     return res;
7623
7624   if (flag_unsafe_math_optimizations)
7625     {
7626       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7627       if (BUILTIN_EXPONENT_P (fcode))
7628         {
7629           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7630           const REAL_VALUE_TYPE third_trunc =
7631             real_value_truncate (TYPE_MODE (type), dconst_third ());
7632           arg = fold_build2_loc (loc, MULT_EXPR, type,
7633                              CALL_EXPR_ARG (arg, 0),
7634                              build_real (type, third_trunc));
7635           return build_call_expr_loc (loc, expfn, 1, arg);
7636         }
7637
7638       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7639       if (BUILTIN_SQRT_P (fcode))
7640         {
7641           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7642
7643           if (powfn)
7644             {
7645               tree arg0 = CALL_EXPR_ARG (arg, 0);
7646               tree tree_root;
7647               REAL_VALUE_TYPE dconstroot = dconst_third ();
7648
7649               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7650               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7651               tree_root = build_real (type, dconstroot);
7652               return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7653             }
7654         }
7655
7656       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7657       if (BUILTIN_CBRT_P (fcode))
7658         {
7659           tree arg0 = CALL_EXPR_ARG (arg, 0);
7660           if (tree_expr_nonnegative_p (arg0))
7661             {
7662               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7663
7664               if (powfn)
7665                 {
7666                   tree tree_root;
7667                   REAL_VALUE_TYPE dconstroot;
7668
7669                   real_arithmetic (&dconstroot, MULT_EXPR,
7670                                    dconst_third_ptr (), dconst_third_ptr ());
7671                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7672                   tree_root = build_real (type, dconstroot);
7673                   return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7674                 }
7675             }
7676         }
7677
7678       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7679       if (fcode == BUILT_IN_POW
7680           || fcode == BUILT_IN_POWF
7681           || fcode == BUILT_IN_POWL)
7682         {
7683           tree arg00 = CALL_EXPR_ARG (arg, 0);
7684           tree arg01 = CALL_EXPR_ARG (arg, 1);
7685           if (tree_expr_nonnegative_p (arg00))
7686             {
7687               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7688               const REAL_VALUE_TYPE dconstroot
7689                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7690               tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7691                                          build_real (type, dconstroot));
7692               return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7693             }
7694         }
7695     }
7696   return NULL_TREE;
7697 }
7698
7699 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7700    TYPE is the type of the return value.  Return NULL_TREE if no
7701    simplification can be made.  */
7702
7703 static tree
7704 fold_builtin_cos (location_t loc,
7705                   tree arg, tree type, tree fndecl)
7706 {
7707   tree res, narg;
7708
7709   if (!validate_arg (arg, REAL_TYPE))
7710     return NULL_TREE;
7711
7712   /* Calculate the result when the argument is a constant.  */
7713   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7714     return res;
7715
7716   /* Optimize cos(-x) into cos (x).  */
7717   if ((narg = fold_strip_sign_ops (arg)))
7718     return build_call_expr_loc (loc, fndecl, 1, narg);
7719
7720   return NULL_TREE;
7721 }
7722
7723 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7724    Return NULL_TREE if no simplification can be made.  */
7725
7726 static tree
7727 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7728 {
7729   if (validate_arg (arg, REAL_TYPE))
7730     {
7731       tree res, narg;
7732
7733       /* Calculate the result when the argument is a constant.  */
7734       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7735         return res;
7736
7737       /* Optimize cosh(-x) into cosh (x).  */
7738       if ((narg = fold_strip_sign_ops (arg)))
7739         return build_call_expr_loc (loc, fndecl, 1, narg);
7740     }
7741
7742   return NULL_TREE;
7743 }
7744
7745 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7746    argument ARG.  TYPE is the type of the return value.  Return
7747    NULL_TREE if no simplification can be made.  */
7748
7749 static tree
7750 fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl,
7751                    bool hyper)
7752 {
7753   if (validate_arg (arg, COMPLEX_TYPE)
7754       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7755     {
7756       tree tmp;
7757
7758       /* Calculate the result when the argument is a constant.  */
7759       if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7760         return tmp;
7761
7762       /* Optimize fn(-x) into fn(x).  */
7763       if ((tmp = fold_strip_sign_ops (arg)))
7764         return build_call_expr_loc (loc, fndecl, 1, tmp);
7765     }
7766
7767   return NULL_TREE;
7768 }
7769
7770 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7771    Return NULL_TREE if no simplification can be made.  */
7772
7773 static tree
7774 fold_builtin_tan (tree arg, tree type)
7775 {
7776   enum built_in_function fcode;
7777   tree res;
7778
7779   if (!validate_arg (arg, REAL_TYPE))
7780     return NULL_TREE;
7781
7782   /* Calculate the result when the argument is a constant.  */
7783   if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7784     return res;
7785
7786   /* Optimize tan(atan(x)) = x.  */
7787   fcode = builtin_mathfn_code (arg);
7788   if (flag_unsafe_math_optimizations
7789       && (fcode == BUILT_IN_ATAN
7790           || fcode == BUILT_IN_ATANF
7791           || fcode == BUILT_IN_ATANL))
7792     return CALL_EXPR_ARG (arg, 0);
7793
7794   return NULL_TREE;
7795 }
7796
7797 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7798    NULL_TREE if no simplification can be made.  */
7799
7800 static tree
7801 fold_builtin_sincos (location_t loc,
7802                      tree arg0, tree arg1, tree arg2)
7803 {
7804   tree type;
7805   tree res, fn, call;
7806
7807   if (!validate_arg (arg0, REAL_TYPE)
7808       || !validate_arg (arg1, POINTER_TYPE)
7809       || !validate_arg (arg2, POINTER_TYPE))
7810     return NULL_TREE;
7811
7812   type = TREE_TYPE (arg0);
7813
7814   /* Calculate the result when the argument is a constant.  */
7815   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7816     return res;
7817
7818   /* Canonicalize sincos to cexpi.  */
7819   if (!TARGET_C99_FUNCTIONS)
7820     return NULL_TREE;
7821   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7822   if (!fn)
7823     return NULL_TREE;
7824
7825   call = build_call_expr_loc (loc, fn, 1, arg0);
7826   call = builtin_save_expr (call);
7827
7828   return build2 (COMPOUND_EXPR, void_type_node,
7829                  build2 (MODIFY_EXPR, void_type_node,
7830                          build_fold_indirect_ref_loc (loc, arg1),
7831                          build1 (IMAGPART_EXPR, type, call)),
7832                  build2 (MODIFY_EXPR, void_type_node,
7833                          build_fold_indirect_ref_loc (loc, arg2),
7834                          build1 (REALPART_EXPR, type, call)));
7835 }
7836
7837 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7838    NULL_TREE if no simplification can be made.  */
7839
7840 static tree
7841 fold_builtin_cexp (location_t loc, tree arg0, tree type)
7842 {
7843   tree rtype;
7844   tree realp, imagp, ifn;
7845   tree res;
7846
7847   if (!validate_arg (arg0, COMPLEX_TYPE)
7848       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7849     return NULL_TREE;
7850
7851   /* Calculate the result when the argument is a constant.  */
7852   if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7853     return res;
7854
7855   rtype = TREE_TYPE (TREE_TYPE (arg0));
7856
7857   /* In case we can figure out the real part of arg0 and it is constant zero
7858      fold to cexpi.  */
7859   if (!TARGET_C99_FUNCTIONS)
7860     return NULL_TREE;
7861   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7862   if (!ifn)
7863     return NULL_TREE;
7864
7865   if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7866       && real_zerop (realp))
7867     {
7868       tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7869       return build_call_expr_loc (loc, ifn, 1, narg);
7870     }
7871
7872   /* In case we can easily decompose real and imaginary parts split cexp
7873      to exp (r) * cexpi (i).  */
7874   if (flag_unsafe_math_optimizations
7875       && realp)
7876     {
7877       tree rfn, rcall, icall;
7878
7879       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7880       if (!rfn)
7881         return NULL_TREE;
7882
7883       imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7884       if (!imagp)
7885         return NULL_TREE;
7886
7887       icall = build_call_expr_loc (loc, ifn, 1, imagp);
7888       icall = builtin_save_expr (icall);
7889       rcall = build_call_expr_loc (loc, rfn, 1, realp);
7890       rcall = builtin_save_expr (rcall);
7891       return fold_build2_loc (loc, COMPLEX_EXPR, type,
7892                           fold_build2_loc (loc, MULT_EXPR, rtype,
7893                                        rcall,
7894                                        fold_build1_loc (loc, REALPART_EXPR,
7895                                                     rtype, icall)),
7896                           fold_build2_loc (loc, MULT_EXPR, rtype,
7897                                        rcall,
7898                                        fold_build1_loc (loc, IMAGPART_EXPR,
7899                                                     rtype, icall)));
7900     }
7901
7902   return NULL_TREE;
7903 }
7904
7905 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7906    Return NULL_TREE if no simplification can be made.  */
7907
7908 static tree
7909 fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7910 {
7911   if (!validate_arg (arg, REAL_TYPE))
7912     return NULL_TREE;
7913
7914   /* Optimize trunc of constant value.  */
7915   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7916     {
7917       REAL_VALUE_TYPE r, x;
7918       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7919
7920       x = TREE_REAL_CST (arg);
7921       real_trunc (&r, TYPE_MODE (type), &x);
7922       return build_real (type, r);
7923     }
7924
7925   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7926 }
7927
7928 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7929    Return NULL_TREE if no simplification can be made.  */
7930
7931 static tree
7932 fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7933 {
7934   if (!validate_arg (arg, REAL_TYPE))
7935     return NULL_TREE;
7936
7937   /* Optimize floor of constant value.  */
7938   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7939     {
7940       REAL_VALUE_TYPE x;
7941
7942       x = TREE_REAL_CST (arg);
7943       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7944         {
7945           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7946           REAL_VALUE_TYPE r;
7947
7948           real_floor (&r, TYPE_MODE (type), &x);
7949           return build_real (type, r);
7950         }
7951     }
7952
7953   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7954   if (tree_expr_nonnegative_p (arg))
7955     {
7956       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7957       if (truncfn)
7958         return build_call_expr_loc (loc, truncfn, 1, arg);
7959     }
7960
7961   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7962 }
7963
7964 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7965    Return NULL_TREE if no simplification can be made.  */
7966
7967 static tree
7968 fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7969 {
7970   if (!validate_arg (arg, REAL_TYPE))
7971     return NULL_TREE;
7972
7973   /* Optimize ceil of constant value.  */
7974   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7975     {
7976       REAL_VALUE_TYPE x;
7977
7978       x = TREE_REAL_CST (arg);
7979       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7980         {
7981           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7982           REAL_VALUE_TYPE r;
7983
7984           real_ceil (&r, TYPE_MODE (type), &x);
7985           return build_real (type, r);
7986         }
7987     }
7988
7989   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7990 }
7991
7992 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7993    Return NULL_TREE if no simplification can be made.  */
7994
7995 static tree
7996 fold_builtin_round (location_t loc, tree fndecl, tree arg)
7997 {
7998   if (!validate_arg (arg, REAL_TYPE))
7999     return NULL_TREE;
8000
8001   /* Optimize round of constant value.  */
8002   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8003     {
8004       REAL_VALUE_TYPE x;
8005
8006       x = TREE_REAL_CST (arg);
8007       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8008         {
8009           tree type = TREE_TYPE (TREE_TYPE (fndecl));
8010           REAL_VALUE_TYPE r;
8011
8012           real_round (&r, TYPE_MODE (type), &x);
8013           return build_real (type, r);
8014         }
8015     }
8016
8017   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
8018 }
8019
8020 /* Fold function call to builtin lround, lroundf or lroundl (or the
8021    corresponding long long versions) and other rounding functions.  ARG
8022    is the argument to the call.  Return NULL_TREE if no simplification
8023    can be made.  */
8024
8025 static tree
8026 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
8027 {
8028   if (!validate_arg (arg, REAL_TYPE))
8029     return NULL_TREE;
8030
8031   /* Optimize lround of constant value.  */
8032   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8033     {
8034       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8035
8036       if (real_isfinite (&x))
8037         {
8038           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
8039           tree ftype = TREE_TYPE (arg);
8040           double_int val;
8041           REAL_VALUE_TYPE r;
8042
8043           switch (DECL_FUNCTION_CODE (fndecl))
8044             {
8045             CASE_FLT_FN (BUILT_IN_IFLOOR):
8046             CASE_FLT_FN (BUILT_IN_LFLOOR):
8047             CASE_FLT_FN (BUILT_IN_LLFLOOR):
8048               real_floor (&r, TYPE_MODE (ftype), &x);
8049               break;
8050
8051             CASE_FLT_FN (BUILT_IN_ICEIL):
8052             CASE_FLT_FN (BUILT_IN_LCEIL):
8053             CASE_FLT_FN (BUILT_IN_LLCEIL):
8054               real_ceil (&r, TYPE_MODE (ftype), &x);
8055               break;
8056
8057             CASE_FLT_FN (BUILT_IN_IROUND):
8058             CASE_FLT_FN (BUILT_IN_LROUND):
8059             CASE_FLT_FN (BUILT_IN_LLROUND):
8060               real_round (&r, TYPE_MODE (ftype), &x);
8061               break;
8062
8063             default:
8064               gcc_unreachable ();
8065             }
8066
8067           real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
8068           if (double_int_fits_to_tree_p (itype, val))
8069             return double_int_to_tree (itype, val);
8070         }
8071     }
8072
8073   switch (DECL_FUNCTION_CODE (fndecl))
8074     {
8075     CASE_FLT_FN (BUILT_IN_LFLOOR):
8076     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8077       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8078       if (tree_expr_nonnegative_p (arg))
8079         return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8080                             TREE_TYPE (TREE_TYPE (fndecl)), arg);
8081       break;
8082     default:;
8083     }
8084
8085   return fold_fixed_mathfn (loc, fndecl, arg);
8086 }
8087
8088 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8089    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8090    the argument to the call.  Return NULL_TREE if no simplification can
8091    be made.  */
8092
8093 static tree
8094 fold_builtin_bitop (tree fndecl, tree arg)
8095 {
8096   if (!validate_arg (arg, INTEGER_TYPE))
8097     return NULL_TREE;
8098
8099   /* Optimize for constant argument.  */
8100   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8101     {
8102       HOST_WIDE_INT hi, width, result;
8103       unsigned HOST_WIDE_INT lo;
8104       tree type;
8105
8106       type = TREE_TYPE (arg);
8107       width = TYPE_PRECISION (type);
8108       lo = TREE_INT_CST_LOW (arg);
8109
8110       /* Clear all the bits that are beyond the type's precision.  */
8111       if (width > HOST_BITS_PER_WIDE_INT)
8112         {
8113           hi = TREE_INT_CST_HIGH (arg);
8114           if (width < HOST_BITS_PER_DOUBLE_INT)
8115             hi &= ~((unsigned HOST_WIDE_INT) (-1)
8116                     << (width - HOST_BITS_PER_WIDE_INT));
8117         }
8118       else
8119         {
8120           hi = 0;
8121           if (width < HOST_BITS_PER_WIDE_INT)
8122             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8123         }
8124
8125       switch (DECL_FUNCTION_CODE (fndecl))
8126         {
8127         CASE_INT_FN (BUILT_IN_FFS):
8128           if (lo != 0)
8129             result = ffs_hwi (lo);
8130           else if (hi != 0)
8131             result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
8132           else
8133             result = 0;
8134           break;
8135
8136         CASE_INT_FN (BUILT_IN_CLZ):
8137           if (hi != 0)
8138             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8139           else if (lo != 0)
8140             result = width - floor_log2 (lo) - 1;
8141           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8142             result = width;
8143           break;
8144
8145         CASE_INT_FN (BUILT_IN_CTZ):
8146           if (lo != 0)
8147             result = ctz_hwi (lo);
8148           else if (hi != 0)
8149             result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
8150           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8151             result = width;
8152           break;
8153
8154         CASE_INT_FN (BUILT_IN_CLRSB):
8155           if (width > HOST_BITS_PER_WIDE_INT
8156               && (hi & ((unsigned HOST_WIDE_INT) 1
8157                         << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
8158             {
8159               hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
8160                            << (width - HOST_BITS_PER_WIDE_INT - 1));
8161               lo = ~lo;
8162             }
8163           else if (width <= HOST_BITS_PER_WIDE_INT
8164                    && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
8165             lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
8166           if (hi != 0)
8167             result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
8168           else if (lo != 0)
8169             result = width - floor_log2 (lo) - 2;
8170           else
8171             result = width - 1;
8172           break;
8173
8174         CASE_INT_FN (BUILT_IN_POPCOUNT):
8175           result = 0;
8176           while (lo)
8177             result++, lo &= lo - 1;
8178           while (hi)
8179             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8180           break;
8181
8182         CASE_INT_FN (BUILT_IN_PARITY):
8183           result = 0;
8184           while (lo)
8185             result++, lo &= lo - 1;
8186           while (hi)
8187             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8188           result &= 1;
8189           break;
8190
8191         default:
8192           gcc_unreachable ();
8193         }
8194
8195       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8196     }
8197
8198   return NULL_TREE;
8199 }
8200
8201 /* Fold function call to builtin_bswap and the short, long and long long
8202    variants.  Return NULL_TREE if no simplification can be made.  */
8203 static tree
8204 fold_builtin_bswap (tree fndecl, tree arg)
8205 {
8206   if (! validate_arg (arg, INTEGER_TYPE))
8207     return NULL_TREE;
8208
8209   /* Optimize constant value.  */
8210   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8211     {
8212       HOST_WIDE_INT hi, width, r_hi = 0;
8213       unsigned HOST_WIDE_INT lo, r_lo = 0;
8214       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8215
8216       width = TYPE_PRECISION (type);
8217       lo = TREE_INT_CST_LOW (arg);
8218       hi = TREE_INT_CST_HIGH (arg);
8219
8220       switch (DECL_FUNCTION_CODE (fndecl))
8221         {
8222           case BUILT_IN_BSWAP16:
8223           case BUILT_IN_BSWAP32:
8224           case BUILT_IN_BSWAP64:
8225             {
8226               int s;
8227
8228               for (s = 0; s < width; s += 8)
8229                 {
8230                   int d = width - s - 8;
8231                   unsigned HOST_WIDE_INT byte;
8232
8233                   if (s < HOST_BITS_PER_WIDE_INT)
8234                     byte = (lo >> s) & 0xff;
8235                   else
8236                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8237
8238                   if (d < HOST_BITS_PER_WIDE_INT)
8239                     r_lo |= byte << d;
8240                   else
8241                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8242                 }
8243             }
8244
8245             break;
8246
8247         default:
8248           gcc_unreachable ();
8249         }
8250
8251       if (width < HOST_BITS_PER_WIDE_INT)
8252         return build_int_cst (type, r_lo);
8253       else
8254         return build_int_cst_wide (type, r_lo, r_hi);
8255     }
8256
8257   return NULL_TREE;
8258 }
8259
8260 /* A subroutine of fold_builtin to fold the various logarithmic
8261    functions.  Return NULL_TREE if no simplification can me made.
8262    FUNC is the corresponding MPFR logarithm function.  */
8263
8264 static tree
8265 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
8266                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8267 {
8268   if (validate_arg (arg, REAL_TYPE))
8269     {
8270       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8271       tree res;
8272       const enum built_in_function fcode = builtin_mathfn_code (arg);
8273
8274       /* Calculate the result when the argument is a constant.  */
8275       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8276         return res;
8277
8278       /* Special case, optimize logN(expN(x)) = x.  */
8279       if (flag_unsafe_math_optimizations
8280           && ((func == mpfr_log
8281                && (fcode == BUILT_IN_EXP
8282                    || fcode == BUILT_IN_EXPF
8283                    || fcode == BUILT_IN_EXPL))
8284               || (func == mpfr_log2
8285                   && (fcode == BUILT_IN_EXP2
8286                       || fcode == BUILT_IN_EXP2F
8287                       || fcode == BUILT_IN_EXP2L))
8288               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8289         return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8290
8291       /* Optimize logN(func()) for various exponential functions.  We
8292          want to determine the value "x" and the power "exponent" in
8293          order to transform logN(x**exponent) into exponent*logN(x).  */
8294       if (flag_unsafe_math_optimizations)
8295         {
8296           tree exponent = 0, x = 0;
8297
8298           switch (fcode)
8299           {
8300           CASE_FLT_FN (BUILT_IN_EXP):
8301             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8302             x = build_real (type, real_value_truncate (TYPE_MODE (type),
8303                                                        dconst_e ()));
8304             exponent = CALL_EXPR_ARG (arg, 0);
8305             break;
8306           CASE_FLT_FN (BUILT_IN_EXP2):
8307             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8308             x = build_real (type, dconst2);
8309             exponent = CALL_EXPR_ARG (arg, 0);
8310             break;
8311           CASE_FLT_FN (BUILT_IN_EXP10):
8312           CASE_FLT_FN (BUILT_IN_POW10):
8313             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8314             {
8315               REAL_VALUE_TYPE dconst10;
8316               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8317               x = build_real (type, dconst10);
8318             }
8319             exponent = CALL_EXPR_ARG (arg, 0);
8320             break;
8321           CASE_FLT_FN (BUILT_IN_SQRT):
8322             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8323             x = CALL_EXPR_ARG (arg, 0);
8324             exponent = build_real (type, dconsthalf);
8325             break;
8326           CASE_FLT_FN (BUILT_IN_CBRT):
8327             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8328             x = CALL_EXPR_ARG (arg, 0);
8329             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8330                                                               dconst_third ()));
8331             break;
8332           CASE_FLT_FN (BUILT_IN_POW):
8333             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8334             x = CALL_EXPR_ARG (arg, 0);
8335             exponent = CALL_EXPR_ARG (arg, 1);
8336             break;
8337           default:
8338             break;
8339           }
8340
8341           /* Now perform the optimization.  */
8342           if (x && exponent)
8343             {
8344               tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8345               return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8346             }
8347         }
8348     }
8349
8350   return NULL_TREE;
8351 }
8352
8353 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8354    NULL_TREE if no simplification can be made.  */
8355
8356 static tree
8357 fold_builtin_hypot (location_t loc, tree fndecl,
8358                     tree arg0, tree arg1, tree type)
8359 {
8360   tree res, narg0, narg1;
8361
8362   if (!validate_arg (arg0, REAL_TYPE)
8363       || !validate_arg (arg1, REAL_TYPE))
8364     return NULL_TREE;
8365
8366   /* Calculate the result when the argument is a constant.  */
8367   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8368     return res;
8369
8370   /* If either argument to hypot has a negate or abs, strip that off.
8371      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8372   narg0 = fold_strip_sign_ops (arg0);
8373   narg1 = fold_strip_sign_ops (arg1);
8374   if (narg0 || narg1)
8375     {
8376       return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
8377                               narg1 ? narg1 : arg1);
8378     }
8379
8380   /* If either argument is zero, hypot is fabs of the other.  */
8381   if (real_zerop (arg0))
8382     return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8383   else if (real_zerop (arg1))
8384     return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8385
8386   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8387   if (flag_unsafe_math_optimizations
8388       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8389     {
8390       const REAL_VALUE_TYPE sqrt2_trunc
8391         = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8392       return fold_build2_loc (loc, MULT_EXPR, type,
8393                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
8394                           build_real (type, sqrt2_trunc));
8395     }
8396
8397   return NULL_TREE;
8398 }
8399
8400
8401 /* Fold a builtin function call to pow, powf, or powl.  Return
8402    NULL_TREE if no simplification can be made.  */
8403 static tree
8404 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8405 {
8406   tree res;
8407
8408   if (!validate_arg (arg0, REAL_TYPE)
8409        || !validate_arg (arg1, REAL_TYPE))
8410     return NULL_TREE;
8411
8412   /* Calculate the result when the argument is a constant.  */
8413   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8414     return res;
8415
8416   /* Optimize pow(1.0,y) = 1.0.  */
8417   if (real_onep (arg0))
8418     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8419
8420   if (TREE_CODE (arg1) == REAL_CST
8421       && !TREE_OVERFLOW (arg1))
8422     {
8423       REAL_VALUE_TYPE cint;
8424       REAL_VALUE_TYPE c;
8425       HOST_WIDE_INT n;
8426
8427       c = TREE_REAL_CST (arg1);
8428
8429       /* Optimize pow(x,0.0) = 1.0.  */
8430       if (REAL_VALUES_EQUAL (c, dconst0))
8431         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8432                                  arg0);
8433
8434       /* Optimize pow(x,1.0) = x.  */
8435       if (REAL_VALUES_EQUAL (c, dconst1))
8436         return arg0;
8437
8438       /* Optimize pow(x,-1.0) = 1.0/x.  */
8439       if (REAL_VALUES_EQUAL (c, dconstm1))
8440         return fold_build2_loc (loc, RDIV_EXPR, type,
8441                             build_real (type, dconst1), arg0);
8442
8443       /* Optimize pow(x,0.5) = sqrt(x).  */
8444       if (flag_unsafe_math_optimizations
8445           && REAL_VALUES_EQUAL (c, dconsthalf))
8446         {
8447           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8448
8449           if (sqrtfn != NULL_TREE)
8450             return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8451         }
8452
8453       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8454       if (flag_unsafe_math_optimizations)
8455         {
8456           const REAL_VALUE_TYPE dconstroot
8457             = real_value_truncate (TYPE_MODE (type), dconst_third ());
8458
8459           if (REAL_VALUES_EQUAL (c, dconstroot))
8460             {
8461               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8462               if (cbrtfn != NULL_TREE)
8463                 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8464             }
8465         }
8466
8467       /* Check for an integer exponent.  */
8468       n = real_to_integer (&c);
8469       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8470       if (real_identical (&c, &cint))
8471         {
8472           /* Attempt to evaluate pow at compile-time, unless this should
8473              raise an exception.  */
8474           if (TREE_CODE (arg0) == REAL_CST
8475               && !TREE_OVERFLOW (arg0)
8476               && (n > 0
8477                   || (!flag_trapping_math && !flag_errno_math)
8478                   || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8479             {
8480               REAL_VALUE_TYPE x;
8481               bool inexact;
8482
8483               x = TREE_REAL_CST (arg0);
8484               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8485               if (flag_unsafe_math_optimizations || !inexact)
8486                 return build_real (type, x);
8487             }
8488
8489           /* Strip sign ops from even integer powers.  */
8490           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8491             {
8492               tree narg0 = fold_strip_sign_ops (arg0);
8493               if (narg0)
8494                 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8495             }
8496         }
8497     }
8498
8499   if (flag_unsafe_math_optimizations)
8500     {
8501       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8502
8503       /* Optimize pow(expN(x),y) = expN(x*y).  */
8504       if (BUILTIN_EXPONENT_P (fcode))
8505         {
8506           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8507           tree arg = CALL_EXPR_ARG (arg0, 0);
8508           arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8509           return build_call_expr_loc (loc, expfn, 1, arg);
8510         }
8511
8512       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8513       if (BUILTIN_SQRT_P (fcode))
8514         {
8515           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8516           tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8517                                     build_real (type, dconsthalf));
8518           return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8519         }
8520
8521       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8522       if (BUILTIN_CBRT_P (fcode))
8523         {
8524           tree arg = CALL_EXPR_ARG (arg0, 0);
8525           if (tree_expr_nonnegative_p (arg))
8526             {
8527               const REAL_VALUE_TYPE dconstroot
8528                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8529               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8530                                         build_real (type, dconstroot));
8531               return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8532             }
8533         }
8534
8535       /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative.  */
8536       if (fcode == BUILT_IN_POW
8537           || fcode == BUILT_IN_POWF
8538           || fcode == BUILT_IN_POWL)
8539         {
8540           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8541           if (tree_expr_nonnegative_p (arg00))
8542             {
8543               tree arg01 = CALL_EXPR_ARG (arg0, 1);
8544               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8545               return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8546             }
8547         }
8548     }
8549
8550   return NULL_TREE;
8551 }
8552
8553 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8554    Return NULL_TREE if no simplification can be made.  */
8555 static tree
8556 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8557                    tree arg0, tree arg1, tree type)
8558 {
8559   if (!validate_arg (arg0, REAL_TYPE)
8560       || !validate_arg (arg1, INTEGER_TYPE))
8561     return NULL_TREE;
8562
8563   /* Optimize pow(1.0,y) = 1.0.  */
8564   if (real_onep (arg0))
8565     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8566
8567   if (host_integerp (arg1, 0))
8568     {
8569       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8570
8571       /* Evaluate powi at compile-time.  */
8572       if (TREE_CODE (arg0) == REAL_CST
8573           && !TREE_OVERFLOW (arg0))
8574         {
8575           REAL_VALUE_TYPE x;
8576           x = TREE_REAL_CST (arg0);
8577           real_powi (&x, TYPE_MODE (type), &x, c);
8578           return build_real (type, x);
8579         }
8580
8581       /* Optimize pow(x,0) = 1.0.  */
8582       if (c == 0)
8583         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8584                                  arg0);
8585
8586       /* Optimize pow(x,1) = x.  */
8587       if (c == 1)
8588         return arg0;
8589
8590       /* Optimize pow(x,-1) = 1.0/x.  */
8591       if (c == -1)
8592         return fold_build2_loc (loc, RDIV_EXPR, type,
8593                            build_real (type, dconst1), arg0);
8594     }
8595
8596   return NULL_TREE;
8597 }
8598
8599 /* A subroutine of fold_builtin to fold the various exponent
8600    functions.  Return NULL_TREE if no simplification can be made.
8601    FUNC is the corresponding MPFR exponent function.  */
8602
8603 static tree
8604 fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8605                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8606 {
8607   if (validate_arg (arg, REAL_TYPE))
8608     {
8609       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8610       tree res;
8611
8612       /* Calculate the result when the argument is a constant.  */
8613       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8614         return res;
8615
8616       /* Optimize expN(logN(x)) = x.  */
8617       if (flag_unsafe_math_optimizations)
8618         {
8619           const enum built_in_function fcode = builtin_mathfn_code (arg);
8620
8621           if ((func == mpfr_exp
8622                && (fcode == BUILT_IN_LOG
8623                    || fcode == BUILT_IN_LOGF
8624                    || fcode == BUILT_IN_LOGL))
8625               || (func == mpfr_exp2
8626                   && (fcode == BUILT_IN_LOG2
8627                       || fcode == BUILT_IN_LOG2F
8628                       || fcode == BUILT_IN_LOG2L))
8629               || (func == mpfr_exp10
8630                   && (fcode == BUILT_IN_LOG10
8631                       || fcode == BUILT_IN_LOG10F
8632                       || fcode == BUILT_IN_LOG10L)))
8633             return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8634         }
8635     }
8636
8637   return NULL_TREE;
8638 }
8639
8640 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8641
8642 static bool
8643 var_decl_component_p (tree var)
8644 {
8645   tree inner = var;
8646   while (handled_component_p (inner))
8647     inner = TREE_OPERAND (inner, 0);
8648   return SSA_VAR_P (inner);
8649 }
8650
8651 /* Fold function call to builtin memset.  Return
8652    NULL_TREE if no simplification can be made.  */
8653
8654 static tree
8655 fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8656                      tree type, bool ignore)
8657 {
8658   tree var, ret, etype;
8659   unsigned HOST_WIDE_INT length, cval;
8660
8661   if (! validate_arg (dest, POINTER_TYPE)
8662       || ! validate_arg (c, INTEGER_TYPE)
8663       || ! validate_arg (len, INTEGER_TYPE))
8664     return NULL_TREE;
8665
8666   if (! host_integerp (len, 1))
8667     return NULL_TREE;
8668
8669   /* If the LEN parameter is zero, return DEST.  */
8670   if (integer_zerop (len))
8671     return omit_one_operand_loc (loc, type, dest, c);
8672
8673   if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
8674     return NULL_TREE;
8675
8676   var = dest;
8677   STRIP_NOPS (var);
8678   if (TREE_CODE (var) != ADDR_EXPR)
8679     return NULL_TREE;
8680
8681   var = TREE_OPERAND (var, 0);
8682   if (TREE_THIS_VOLATILE (var))
8683     return NULL_TREE;
8684
8685   etype = TREE_TYPE (var);
8686   if (TREE_CODE (etype) == ARRAY_TYPE)
8687     etype = TREE_TYPE (etype);
8688
8689   if (!INTEGRAL_TYPE_P (etype)
8690       && !POINTER_TYPE_P (etype))
8691     return NULL_TREE;
8692
8693   if (! var_decl_component_p (var))
8694     return NULL_TREE;
8695
8696   length = tree_low_cst (len, 1);
8697   if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8698       || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
8699     return NULL_TREE;
8700
8701   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8702     return NULL_TREE;
8703
8704   if (integer_zerop (c))
8705     cval = 0;
8706   else
8707     {
8708       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8709         return NULL_TREE;
8710
8711       cval = TREE_INT_CST_LOW (c);
8712       cval &= 0xff;
8713       cval |= cval << 8;
8714       cval |= cval << 16;
8715       cval |= (cval << 31) << 1;
8716     }
8717
8718   ret = build_int_cst_type (etype, cval);
8719   var = build_fold_indirect_ref_loc (loc,
8720                                  fold_convert_loc (loc,
8721                                                    build_pointer_type (etype),
8722                                                    dest));
8723   ret = build2 (MODIFY_EXPR, etype, var, ret);
8724   if (ignore)
8725     return ret;
8726
8727   return omit_one_operand_loc (loc, type, dest, ret);
8728 }
8729
8730 /* Fold function call to builtin memset.  Return
8731    NULL_TREE if no simplification can be made.  */
8732
8733 static tree
8734 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8735 {
8736   if (! validate_arg (dest, POINTER_TYPE)
8737       || ! validate_arg (size, INTEGER_TYPE))
8738     return NULL_TREE;
8739
8740   if (!ignore)
8741     return NULL_TREE;
8742
8743   /* New argument list transforming bzero(ptr x, int y) to
8744      memset(ptr x, int 0, size_t y).   This is done this way
8745      so that if it isn't expanded inline, we fallback to
8746      calling bzero instead of memset.  */
8747
8748   return fold_builtin_memset (loc, dest, integer_zero_node,
8749                               fold_convert_loc (loc, size_type_node, size),
8750                               void_type_node, ignore);
8751 }
8752
8753 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8754    NULL_TREE if no simplification can be made.
8755    If ENDP is 0, return DEST (like memcpy).
8756    If ENDP is 1, return DEST+LEN (like mempcpy).
8757    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8758    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8759    (memmove).   */
8760
8761 static tree
8762 fold_builtin_memory_op (location_t loc, tree dest, tree src,
8763                         tree len, tree type, bool ignore, int endp)
8764 {
8765   tree destvar, srcvar, expr;
8766
8767   if (! validate_arg (dest, POINTER_TYPE)
8768       || ! validate_arg (src, POINTER_TYPE)
8769       || ! validate_arg (len, INTEGER_TYPE))
8770     return NULL_TREE;
8771
8772   /* If the LEN parameter is zero, return DEST.  */
8773   if (integer_zerop (len))
8774     return omit_one_operand_loc (loc, type, dest, src);
8775
8776   /* If SRC and DEST are the same (and not volatile), return
8777      DEST{,+LEN,+LEN-1}.  */
8778   if (operand_equal_p (src, dest, 0))
8779     expr = len;
8780   else
8781     {
8782       tree srctype, desttype;
8783       unsigned int src_align, dest_align;
8784       tree off0;
8785
8786       if (endp == 3)
8787         {
8788           src_align = get_pointer_alignment (src);
8789           dest_align = get_pointer_alignment (dest);
8790
8791           /* Both DEST and SRC must be pointer types.
8792              ??? This is what old code did.  Is the testing for pointer types
8793              really mandatory?
8794
8795              If either SRC is readonly or length is 1, we can use memcpy.  */
8796           if (!dest_align || !src_align)
8797             return NULL_TREE;
8798           if (readonly_data_expr (src)
8799               || (host_integerp (len, 1)
8800                   && (MIN (src_align, dest_align) / BITS_PER_UNIT
8801                       >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
8802             {
8803               tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8804               if (!fn)
8805                 return NULL_TREE;
8806               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8807             }
8808
8809           /* If *src and *dest can't overlap, optimize into memcpy as well.  */
8810           if (TREE_CODE (src) == ADDR_EXPR
8811               && TREE_CODE (dest) == ADDR_EXPR)
8812             {
8813               tree src_base, dest_base, fn;
8814               HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8815               HOST_WIDE_INT size = -1;
8816               HOST_WIDE_INT maxsize = -1;
8817
8818               srcvar = TREE_OPERAND (src, 0);
8819               src_base = get_ref_base_and_extent (srcvar, &src_offset,
8820                                                   &size, &maxsize);
8821               destvar = TREE_OPERAND (dest, 0);
8822               dest_base = get_ref_base_and_extent (destvar, &dest_offset,
8823                                                    &size, &maxsize);
8824               if (host_integerp (len, 1))
8825                 maxsize = tree_low_cst (len, 1);
8826               else
8827                 maxsize = -1;
8828               src_offset /= BITS_PER_UNIT;
8829               dest_offset /= BITS_PER_UNIT;
8830               if (SSA_VAR_P (src_base)
8831                   && SSA_VAR_P (dest_base))
8832                 {
8833                   if (operand_equal_p (src_base, dest_base, 0)
8834                       && ranges_overlap_p (src_offset, maxsize,
8835                                            dest_offset, maxsize))
8836                     return NULL_TREE;
8837                 }
8838               else if (TREE_CODE (src_base) == MEM_REF
8839                        && TREE_CODE (dest_base) == MEM_REF)
8840                 {
8841                   double_int off;
8842                   if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8843                                          TREE_OPERAND (dest_base, 0), 0))
8844                     return NULL_TREE;
8845                   off = mem_ref_offset (src_base) +
8846                                         double_int::from_shwi (src_offset);
8847                   if (!off.fits_shwi ())
8848                     return NULL_TREE;
8849                   src_offset = off.low;
8850                   off = mem_ref_offset (dest_base) +
8851                                         double_int::from_shwi (dest_offset);
8852                   if (!off.fits_shwi ())
8853                     return NULL_TREE;
8854                   dest_offset = off.low;
8855                   if (ranges_overlap_p (src_offset, maxsize,
8856                                         dest_offset, maxsize))
8857                     return NULL_TREE;
8858                 }
8859               else
8860                 return NULL_TREE;
8861
8862               fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8863               if (!fn)
8864                 return NULL_TREE;
8865               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8866             }
8867
8868           /* If the destination and source do not alias optimize into
8869              memcpy as well.  */
8870           if ((is_gimple_min_invariant (dest)
8871                || TREE_CODE (dest) == SSA_NAME)
8872               && (is_gimple_min_invariant (src)
8873                   || TREE_CODE (src) == SSA_NAME))
8874             {
8875               ao_ref destr, srcr;
8876               ao_ref_init_from_ptr_and_size (&destr, dest, len);
8877               ao_ref_init_from_ptr_and_size (&srcr, src, len);
8878               if (!refs_may_alias_p_1 (&destr, &srcr, false))
8879                 {
8880                   tree fn;
8881                   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8882                   if (!fn)
8883                     return NULL_TREE;
8884                   return build_call_expr_loc (loc, fn, 3, dest, src, len);
8885                 }
8886             }
8887
8888           return NULL_TREE;
8889         }
8890
8891       if (!host_integerp (len, 0))
8892         return NULL_TREE;
8893       /* FIXME:
8894          This logic lose for arguments like (type *)malloc (sizeof (type)),
8895          since we strip the casts of up to VOID return value from malloc.
8896          Perhaps we ought to inherit type from non-VOID argument here?  */
8897       STRIP_NOPS (src);
8898       STRIP_NOPS (dest);
8899       if (!POINTER_TYPE_P (TREE_TYPE (src))
8900           || !POINTER_TYPE_P (TREE_TYPE (dest)))
8901         return NULL_TREE;
8902       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
8903       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8904         {
8905           tree tem = TREE_OPERAND (src, 0);
8906           STRIP_NOPS (tem);
8907           if (tem != TREE_OPERAND (src, 0))
8908             src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8909         }
8910       if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8911         {
8912           tree tem = TREE_OPERAND (dest, 0);
8913           STRIP_NOPS (tem);
8914           if (tem != TREE_OPERAND (dest, 0))
8915             dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8916         }
8917       srctype = TREE_TYPE (TREE_TYPE (src));
8918       if (TREE_CODE (srctype) == ARRAY_TYPE
8919           && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8920         {
8921           srctype = TREE_TYPE (srctype);
8922           STRIP_NOPS (src);
8923           src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8924         }
8925       desttype = TREE_TYPE (TREE_TYPE (dest));
8926       if (TREE_CODE (desttype) == ARRAY_TYPE
8927           && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8928         {
8929           desttype = TREE_TYPE (desttype);
8930           STRIP_NOPS (dest);
8931           dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8932         }
8933       if (TREE_ADDRESSABLE (srctype)
8934           || TREE_ADDRESSABLE (desttype))
8935         return NULL_TREE;
8936
8937       src_align = get_pointer_alignment (src);
8938       dest_align = get_pointer_alignment (dest);
8939       if (dest_align < TYPE_ALIGN (desttype)
8940           || src_align < TYPE_ALIGN (srctype))
8941         return NULL_TREE;
8942
8943       if (!ignore)
8944         dest = builtin_save_expr (dest);
8945
8946       /* Build accesses at offset zero with a ref-all character type.  */
8947       off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
8948                                                          ptr_mode, true), 0);
8949
8950       destvar = dest;
8951       STRIP_NOPS (destvar);
8952       if (TREE_CODE (destvar) == ADDR_EXPR
8953           && var_decl_component_p (TREE_OPERAND (destvar, 0))
8954           && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8955         destvar = fold_build2 (MEM_REF, desttype, destvar, off0);
8956       else
8957         destvar = NULL_TREE;
8958
8959       srcvar = src;
8960       STRIP_NOPS (srcvar);
8961       if (TREE_CODE (srcvar) == ADDR_EXPR
8962           && var_decl_component_p (TREE_OPERAND (srcvar, 0))
8963           && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8964         {
8965           if (!destvar
8966               || src_align >= TYPE_ALIGN (desttype))
8967             srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
8968                                   srcvar, off0);
8969           else if (!STRICT_ALIGNMENT)
8970             {
8971               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8972                                             src_align);
8973               srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0);
8974             }
8975           else
8976             srcvar = NULL_TREE;
8977         }
8978       else
8979         srcvar = NULL_TREE;
8980
8981       if (srcvar == NULL_TREE && destvar == NULL_TREE)
8982         return NULL_TREE;
8983
8984       if (srcvar == NULL_TREE)
8985         {
8986           STRIP_NOPS (src);
8987           if (src_align >= TYPE_ALIGN (desttype))
8988             srcvar = fold_build2 (MEM_REF, desttype, src, off0);
8989           else
8990             {
8991               if (STRICT_ALIGNMENT)
8992                 return NULL_TREE;
8993               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8994                                             src_align);
8995               srcvar = fold_build2 (MEM_REF, srctype, src, off0);
8996             }
8997         }
8998       else if (destvar == NULL_TREE)
8999         {
9000           STRIP_NOPS (dest);
9001           if (dest_align >= TYPE_ALIGN (srctype))
9002             destvar = fold_build2 (MEM_REF, srctype, dest, off0);
9003           else
9004             {
9005               if (STRICT_ALIGNMENT)
9006                 return NULL_TREE;
9007               desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
9008                                              dest_align);
9009               destvar = fold_build2 (MEM_REF, desttype, dest, off0);
9010             }
9011         }
9012
9013       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar);
9014     }
9015
9016   if (ignore)
9017     return expr;
9018
9019   if (endp == 0 || endp == 3)
9020     return omit_one_operand_loc (loc, type, dest, expr);
9021
9022   if (expr == len)
9023     expr = NULL_TREE;
9024
9025   if (endp == 2)
9026     len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
9027                        ssize_int (1));
9028
9029   dest = fold_build_pointer_plus_loc (loc, dest, len);
9030   dest = fold_convert_loc (loc, type, dest);
9031   if (expr)
9032     dest = omit_one_operand_loc (loc, type, dest, expr);
9033   return dest;
9034 }
9035
9036 /* Fold function call to builtin strcpy with arguments DEST and SRC.
9037    If LEN is not NULL, it represents the length of the string to be
9038    copied.  Return NULL_TREE if no simplification can be made.  */
9039
9040 tree
9041 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
9042 {
9043   tree fn;
9044
9045   if (!validate_arg (dest, POINTER_TYPE)
9046       || !validate_arg (src, POINTER_TYPE))
9047     return NULL_TREE;
9048
9049   /* If SRC and DEST are the same (and not volatile), return DEST.  */
9050   if (operand_equal_p (src, dest, 0))
9051     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
9052
9053   if (optimize_function_for_size_p (cfun))
9054     return NULL_TREE;
9055
9056   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9057   if (!fn)
9058     return NULL_TREE;
9059
9060   if (!len)
9061     {
9062       len = c_strlen (src, 1);
9063       if (! len || TREE_SIDE_EFFECTS (len))
9064         return NULL_TREE;
9065     }
9066
9067   len = fold_convert_loc (loc, size_type_node, len);
9068   len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
9069   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9070                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9071 }
9072
9073 /* Fold function call to builtin stpcpy with arguments DEST and SRC.
9074    Return NULL_TREE if no simplification can be made.  */
9075
9076 static tree
9077 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
9078 {
9079   tree fn, len, lenp1, call, type;
9080
9081   if (!validate_arg (dest, POINTER_TYPE)
9082       || !validate_arg (src, POINTER_TYPE))
9083     return NULL_TREE;
9084
9085   len = c_strlen (src, 1);
9086   if (!len
9087       || TREE_CODE (len) != INTEGER_CST)
9088     return NULL_TREE;
9089
9090   if (optimize_function_for_size_p (cfun)
9091       /* If length is zero it's small enough.  */
9092       && !integer_zerop (len))
9093     return NULL_TREE;
9094
9095   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9096   if (!fn)
9097     return NULL_TREE;
9098
9099   lenp1 = size_binop_loc (loc, PLUS_EXPR,
9100                           fold_convert_loc (loc, size_type_node, len),
9101                           build_int_cst (size_type_node, 1));
9102   /* We use dest twice in building our expression.  Save it from
9103      multiple expansions.  */
9104   dest = builtin_save_expr (dest);
9105   call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
9106
9107   type = TREE_TYPE (TREE_TYPE (fndecl));
9108   dest = fold_build_pointer_plus_loc (loc, dest, len);
9109   dest = fold_convert_loc (loc, type, dest);
9110   dest = omit_one_operand_loc (loc, type, dest, call);
9111   return dest;
9112 }
9113
9114 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9115    If SLEN is not NULL, it represents the length of the source string.
9116    Return NULL_TREE if no simplification can be made.  */
9117
9118 tree
9119 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9120                       tree src, tree len, tree slen)
9121 {
9122   tree fn;
9123
9124   if (!validate_arg (dest, POINTER_TYPE)
9125       || !validate_arg (src, POINTER_TYPE)
9126       || !validate_arg (len, INTEGER_TYPE))
9127     return NULL_TREE;
9128
9129   /* If the LEN parameter is zero, return DEST.  */
9130   if (integer_zerop (len))
9131     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9132
9133   /* We can't compare slen with len as constants below if len is not a
9134      constant.  */
9135   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9136     return NULL_TREE;
9137
9138   if (!slen)
9139     slen = c_strlen (src, 1);
9140
9141   /* Now, we must be passed a constant src ptr parameter.  */
9142   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9143     return NULL_TREE;
9144
9145   slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
9146
9147   /* We do not support simplification of this case, though we do
9148      support it when expanding trees into RTL.  */
9149   /* FIXME: generate a call to __builtin_memset.  */
9150   if (tree_int_cst_lt (slen, len))
9151     return NULL_TREE;
9152
9153   /* OK transform into builtin memcpy.  */
9154   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9155   if (!fn)
9156     return NULL_TREE;
9157
9158   len = fold_convert_loc (loc, size_type_node, len);
9159   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9160                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9161 }
9162
9163 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
9164    arguments to the call, and TYPE is its return type.
9165    Return NULL_TREE if no simplification can be made.  */
9166
9167 static tree
9168 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
9169 {
9170   if (!validate_arg (arg1, POINTER_TYPE)
9171       || !validate_arg (arg2, INTEGER_TYPE)
9172       || !validate_arg (len, INTEGER_TYPE))
9173     return NULL_TREE;
9174   else
9175     {
9176       const char *p1;
9177
9178       if (TREE_CODE (arg2) != INTEGER_CST
9179           || !host_integerp (len, 1))
9180         return NULL_TREE;
9181
9182       p1 = c_getstr (arg1);
9183       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9184         {
9185           char c;
9186           const char *r;
9187           tree tem;
9188
9189           if (target_char_cast (arg2, &c))
9190             return NULL_TREE;
9191
9192           r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
9193
9194           if (r == NULL)
9195             return build_int_cst (TREE_TYPE (arg1), 0);
9196
9197           tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1);
9198           return fold_convert_loc (loc, type, tem);
9199         }
9200       return NULL_TREE;
9201     }
9202 }
9203
9204 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9205    Return NULL_TREE if no simplification can be made.  */
9206
9207 static tree
9208 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9209 {
9210   const char *p1, *p2;
9211
9212   if (!validate_arg (arg1, POINTER_TYPE)
9213       || !validate_arg (arg2, POINTER_TYPE)
9214       || !validate_arg (len, INTEGER_TYPE))
9215     return NULL_TREE;
9216
9217   /* If the LEN parameter is zero, return zero.  */
9218   if (integer_zerop (len))
9219     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9220                               arg1, arg2);
9221
9222   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9223   if (operand_equal_p (arg1, arg2, 0))
9224     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9225
9226   p1 = c_getstr (arg1);
9227   p2 = c_getstr (arg2);
9228
9229   /* If all arguments are constant, and the value of len is not greater
9230      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9231   if (host_integerp (len, 1) && p1 && p2
9232       && compare_tree_int (len, strlen (p1) + 1) <= 0
9233       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9234     {
9235       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9236
9237       if (r > 0)
9238         return integer_one_node;
9239       else if (r < 0)
9240         return integer_minus_one_node;
9241       else
9242         return integer_zero_node;
9243     }
9244
9245   /* If len parameter is one, return an expression corresponding to
9246      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9247   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9248     {
9249       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9250       tree cst_uchar_ptr_node
9251         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9252
9253       tree ind1
9254         = fold_convert_loc (loc, integer_type_node,
9255                             build1 (INDIRECT_REF, cst_uchar_node,
9256                                     fold_convert_loc (loc,
9257                                                       cst_uchar_ptr_node,
9258                                                       arg1)));
9259       tree ind2
9260         = fold_convert_loc (loc, integer_type_node,
9261                             build1 (INDIRECT_REF, cst_uchar_node,
9262                                     fold_convert_loc (loc,
9263                                                       cst_uchar_ptr_node,
9264                                                       arg2)));
9265       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9266     }
9267
9268   return NULL_TREE;
9269 }
9270
9271 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9272    Return NULL_TREE if no simplification can be made.  */
9273
9274 static tree
9275 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9276 {
9277   const char *p1, *p2;
9278
9279   if (!validate_arg (arg1, POINTER_TYPE)
9280       || !validate_arg (arg2, POINTER_TYPE))
9281     return NULL_TREE;
9282
9283   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9284   if (operand_equal_p (arg1, arg2, 0))
9285     return integer_zero_node;
9286
9287   p1 = c_getstr (arg1);
9288   p2 = c_getstr (arg2);
9289
9290   if (p1 && p2)
9291     {
9292       const int i = strcmp (p1, p2);
9293       if (i < 0)
9294         return integer_minus_one_node;
9295       else if (i > 0)
9296         return integer_one_node;
9297       else
9298         return integer_zero_node;
9299     }
9300
9301   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9302   if (p2 && *p2 == '\0')
9303     {
9304       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9305       tree cst_uchar_ptr_node
9306         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9307
9308       return fold_convert_loc (loc, integer_type_node,
9309                                build1 (INDIRECT_REF, cst_uchar_node,
9310                                        fold_convert_loc (loc,
9311                                                          cst_uchar_ptr_node,
9312                                                          arg1)));
9313     }
9314
9315   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9316   if (p1 && *p1 == '\0')
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       tree temp
9323         = fold_convert_loc (loc, integer_type_node,
9324                             build1 (INDIRECT_REF, cst_uchar_node,
9325                                     fold_convert_loc (loc,
9326                                                       cst_uchar_ptr_node,
9327                                                       arg2)));
9328       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9329     }
9330
9331   return NULL_TREE;
9332 }
9333
9334 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9335    Return NULL_TREE if no simplification can be made.  */
9336
9337 static tree
9338 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9339 {
9340   const char *p1, *p2;
9341
9342   if (!validate_arg (arg1, POINTER_TYPE)
9343       || !validate_arg (arg2, POINTER_TYPE)
9344       || !validate_arg (len, INTEGER_TYPE))
9345     return NULL_TREE;
9346
9347   /* If the LEN parameter is zero, return zero.  */
9348   if (integer_zerop (len))
9349     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9350                               arg1, arg2);
9351
9352   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9353   if (operand_equal_p (arg1, arg2, 0))
9354     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9355
9356   p1 = c_getstr (arg1);
9357   p2 = c_getstr (arg2);
9358
9359   if (host_integerp (len, 1) && p1 && p2)
9360     {
9361       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9362       if (i > 0)
9363         return integer_one_node;
9364       else if (i < 0)
9365         return integer_minus_one_node;
9366       else
9367         return integer_zero_node;
9368     }
9369
9370   /* If the second arg is "", and the length is greater than zero,
9371      return *(const unsigned char*)arg1.  */
9372   if (p2 && *p2 == '\0'
9373       && TREE_CODE (len) == INTEGER_CST
9374       && tree_int_cst_sgn (len) == 1)
9375     {
9376       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9377       tree cst_uchar_ptr_node
9378         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9379
9380       return fold_convert_loc (loc, integer_type_node,
9381                                build1 (INDIRECT_REF, cst_uchar_node,
9382                                        fold_convert_loc (loc,
9383                                                          cst_uchar_ptr_node,
9384                                                          arg1)));
9385     }
9386
9387   /* If the first arg is "", and the length is greater than zero,
9388      return -*(const unsigned char*)arg2.  */
9389   if (p1 && *p1 == '\0'
9390       && TREE_CODE (len) == INTEGER_CST
9391       && tree_int_cst_sgn (len) == 1)
9392     {
9393       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9394       tree cst_uchar_ptr_node
9395         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9396
9397       tree temp = fold_convert_loc (loc, integer_type_node,
9398                                     build1 (INDIRECT_REF, cst_uchar_node,
9399                                             fold_convert_loc (loc,
9400                                                               cst_uchar_ptr_node,
9401                                                               arg2)));
9402       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9403     }
9404
9405   /* If len parameter is one, return an expression corresponding to
9406      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9407   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9408     {
9409       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9410       tree cst_uchar_ptr_node
9411         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9412
9413       tree ind1 = fold_convert_loc (loc, integer_type_node,
9414                                     build1 (INDIRECT_REF, cst_uchar_node,
9415                                             fold_convert_loc (loc,
9416                                                               cst_uchar_ptr_node,
9417                                                               arg1)));
9418       tree ind2 = fold_convert_loc (loc, integer_type_node,
9419                                     build1 (INDIRECT_REF, cst_uchar_node,
9420                                             fold_convert_loc (loc,
9421                                                               cst_uchar_ptr_node,
9422                                                               arg2)));
9423       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9424     }
9425
9426   return NULL_TREE;
9427 }
9428
9429 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9430    ARG.  Return NULL_TREE if no simplification can be made.  */
9431
9432 static tree
9433 fold_builtin_signbit (location_t loc, tree arg, tree type)
9434 {
9435   if (!validate_arg (arg, REAL_TYPE))
9436     return NULL_TREE;
9437
9438   /* If ARG is a compile-time constant, determine the result.  */
9439   if (TREE_CODE (arg) == REAL_CST
9440       && !TREE_OVERFLOW (arg))
9441     {
9442       REAL_VALUE_TYPE c;
9443
9444       c = TREE_REAL_CST (arg);
9445       return (REAL_VALUE_NEGATIVE (c)
9446               ? build_one_cst (type)
9447               : build_zero_cst (type));
9448     }
9449
9450   /* If ARG is non-negative, the result is always zero.  */
9451   if (tree_expr_nonnegative_p (arg))
9452     return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9453
9454   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9455   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9456     return fold_convert (type,
9457                          fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
9458                         build_real (TREE_TYPE (arg), dconst0)));
9459
9460   return NULL_TREE;
9461 }
9462
9463 /* Fold function call to builtin copysign, copysignf or copysignl with
9464    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9465    be made.  */
9466
9467 static tree
9468 fold_builtin_copysign (location_t loc, tree fndecl,
9469                        tree arg1, tree arg2, tree type)
9470 {
9471   tree tem;
9472
9473   if (!validate_arg (arg1, REAL_TYPE)
9474       || !validate_arg (arg2, REAL_TYPE))
9475     return NULL_TREE;
9476
9477   /* copysign(X,X) is X.  */
9478   if (operand_equal_p (arg1, arg2, 0))
9479     return fold_convert_loc (loc, type, arg1);
9480
9481   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9482   if (TREE_CODE (arg1) == REAL_CST
9483       && TREE_CODE (arg2) == REAL_CST
9484       && !TREE_OVERFLOW (arg1)
9485       && !TREE_OVERFLOW (arg2))
9486     {
9487       REAL_VALUE_TYPE c1, c2;
9488
9489       c1 = TREE_REAL_CST (arg1);
9490       c2 = TREE_REAL_CST (arg2);
9491       /* c1.sign := c2.sign.  */
9492       real_copysign (&c1, &c2);
9493       return build_real (type, c1);
9494     }
9495
9496   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9497      Remember to evaluate Y for side-effects.  */
9498   if (tree_expr_nonnegative_p (arg2))
9499     return omit_one_operand_loc (loc, type,
9500                              fold_build1_loc (loc, ABS_EXPR, type, arg1),
9501                              arg2);
9502
9503   /* Strip sign changing operations for the first argument.  */
9504   tem = fold_strip_sign_ops (arg1);
9505   if (tem)
9506     return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9507
9508   return NULL_TREE;
9509 }
9510
9511 /* Fold a call to builtin isascii with argument ARG.  */
9512
9513 static tree
9514 fold_builtin_isascii (location_t loc, tree arg)
9515 {
9516   if (!validate_arg (arg, INTEGER_TYPE))
9517     return NULL_TREE;
9518   else
9519     {
9520       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9521       arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9522                          build_int_cst (integer_type_node,
9523                                         ~ (unsigned HOST_WIDE_INT) 0x7f));
9524       return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9525                               arg, integer_zero_node);
9526     }
9527 }
9528
9529 /* Fold a call to builtin toascii with argument ARG.  */
9530
9531 static tree
9532 fold_builtin_toascii (location_t loc, tree arg)
9533 {
9534   if (!validate_arg (arg, INTEGER_TYPE))
9535     return NULL_TREE;
9536
9537   /* Transform toascii(c) -> (c & 0x7f).  */
9538   return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9539                           build_int_cst (integer_type_node, 0x7f));
9540 }
9541
9542 /* Fold a call to builtin isdigit with argument ARG.  */
9543
9544 static tree
9545 fold_builtin_isdigit (location_t loc, tree arg)
9546 {
9547   if (!validate_arg (arg, INTEGER_TYPE))
9548     return NULL_TREE;
9549   else
9550     {
9551       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9552       /* According to the C standard, isdigit is unaffected by locale.
9553          However, it definitely is affected by the target character set.  */
9554       unsigned HOST_WIDE_INT target_digit0
9555         = lang_hooks.to_target_charset ('0');
9556
9557       if (target_digit0 == 0)
9558         return NULL_TREE;
9559
9560       arg = fold_convert_loc (loc, unsigned_type_node, arg);
9561       arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9562                          build_int_cst (unsigned_type_node, target_digit0));
9563       return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9564                           build_int_cst (unsigned_type_node, 9));
9565     }
9566 }
9567
9568 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9569
9570 static tree
9571 fold_builtin_fabs (location_t loc, tree arg, tree type)
9572 {
9573   if (!validate_arg (arg, REAL_TYPE))
9574     return NULL_TREE;
9575
9576   arg = fold_convert_loc (loc, type, arg);
9577   if (TREE_CODE (arg) == REAL_CST)
9578     return fold_abs_const (arg, type);
9579   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9580 }
9581
9582 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9583
9584 static tree
9585 fold_builtin_abs (location_t loc, tree arg, tree type)
9586 {
9587   if (!validate_arg (arg, INTEGER_TYPE))
9588     return NULL_TREE;
9589
9590   arg = fold_convert_loc (loc, type, arg);
9591   if (TREE_CODE (arg) == INTEGER_CST)
9592     return fold_abs_const (arg, type);
9593   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9594 }
9595
9596 /* Fold a fma operation with arguments ARG[012].  */
9597
9598 tree
9599 fold_fma (location_t loc ATTRIBUTE_UNUSED,
9600           tree type, tree arg0, tree arg1, tree arg2)
9601 {
9602   if (TREE_CODE (arg0) == REAL_CST
9603       && TREE_CODE (arg1) == REAL_CST
9604       && TREE_CODE (arg2) == REAL_CST)
9605     return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
9606
9607   return NULL_TREE;
9608 }
9609
9610 /* Fold a call to fma, fmaf, or fmal with arguments ARG[012].  */
9611
9612 static tree
9613 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
9614 {
9615   if (validate_arg (arg0, REAL_TYPE)
9616       && validate_arg(arg1, REAL_TYPE)
9617       && validate_arg(arg2, REAL_TYPE))
9618     {
9619       tree tem = fold_fma (loc, type, arg0, arg1, arg2);
9620       if (tem)
9621         return tem;
9622
9623       /* ??? Only expand to FMA_EXPR if it's directly supported.  */
9624       if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
9625         return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2);
9626     }
9627   return NULL_TREE;
9628 }
9629
9630 /* Fold a call to builtin fmin or fmax.  */
9631
9632 static tree
9633 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9634                         tree type, bool max)
9635 {
9636   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9637     {
9638       /* Calculate the result when the argument is a constant.  */
9639       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9640
9641       if (res)
9642         return res;
9643
9644       /* If either argument is NaN, return the other one.  Avoid the
9645          transformation if we get (and honor) a signalling NaN.  Using
9646          omit_one_operand() ensures we create a non-lvalue.  */
9647       if (TREE_CODE (arg0) == REAL_CST
9648           && real_isnan (&TREE_REAL_CST (arg0))
9649           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9650               || ! TREE_REAL_CST (arg0).signalling))
9651         return omit_one_operand_loc (loc, type, arg1, arg0);
9652       if (TREE_CODE (arg1) == REAL_CST
9653           && real_isnan (&TREE_REAL_CST (arg1))
9654           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9655               || ! TREE_REAL_CST (arg1).signalling))
9656         return omit_one_operand_loc (loc, type, arg0, arg1);
9657
9658       /* Transform fmin/fmax(x,x) -> x.  */
9659       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9660         return omit_one_operand_loc (loc, type, arg0, arg1);
9661
9662       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9663          functions to return the numeric arg if the other one is NaN.
9664          These tree codes don't honor that, so only transform if
9665          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9666          handled, so we don't have to worry about it either.  */
9667       if (flag_finite_math_only)
9668         return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9669                             fold_convert_loc (loc, type, arg0),
9670                             fold_convert_loc (loc, type, arg1));
9671     }
9672   return NULL_TREE;
9673 }
9674
9675 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9676
9677 static tree
9678 fold_builtin_carg (location_t loc, tree arg, tree type)
9679 {
9680   if (validate_arg (arg, COMPLEX_TYPE)
9681       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9682     {
9683       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9684
9685       if (atan2_fn)
9686         {
9687           tree new_arg = builtin_save_expr (arg);
9688           tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9689           tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9690           return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9691         }
9692     }
9693
9694   return NULL_TREE;
9695 }
9696
9697 /* Fold a call to builtin logb/ilogb.  */
9698
9699 static tree
9700 fold_builtin_logb (location_t loc, tree arg, tree rettype)
9701 {
9702   if (! validate_arg (arg, REAL_TYPE))
9703     return NULL_TREE;
9704
9705   STRIP_NOPS (arg);
9706
9707   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9708     {
9709       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9710
9711       switch (value->cl)
9712       {
9713       case rvc_nan:
9714       case rvc_inf:
9715         /* If arg is Inf or NaN and we're logb, return it.  */
9716         if (TREE_CODE (rettype) == REAL_TYPE)
9717           {
9718             /* For logb(-Inf) we have to return +Inf.  */
9719             if (real_isinf (value) && real_isneg (value))
9720               {
9721                 REAL_VALUE_TYPE tem;
9722                 real_inf (&tem);
9723                 return build_real (rettype, tem);
9724               }
9725             return fold_convert_loc (loc, rettype, arg);
9726           }
9727         /* Fall through... */
9728       case rvc_zero:
9729         /* Zero may set errno and/or raise an exception for logb, also
9730            for ilogb we don't know FP_ILOGB0.  */
9731         return NULL_TREE;
9732       case rvc_normal:
9733         /* For normal numbers, proceed iff radix == 2.  In GCC,
9734            normalized significands are in the range [0.5, 1.0).  We
9735            want the exponent as if they were [1.0, 2.0) so get the
9736            exponent and subtract 1.  */
9737         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9738           return fold_convert_loc (loc, rettype,
9739                                    build_int_cst (integer_type_node,
9740                                                   REAL_EXP (value)-1));
9741         break;
9742       }
9743     }
9744
9745   return NULL_TREE;
9746 }
9747
9748 /* Fold a call to builtin significand, if radix == 2.  */
9749
9750 static tree
9751 fold_builtin_significand (location_t loc, tree arg, tree rettype)
9752 {
9753   if (! validate_arg (arg, REAL_TYPE))
9754     return NULL_TREE;
9755
9756   STRIP_NOPS (arg);
9757
9758   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9759     {
9760       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9761
9762       switch (value->cl)
9763       {
9764       case rvc_zero:
9765       case rvc_nan:
9766       case rvc_inf:
9767         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9768         return fold_convert_loc (loc, rettype, arg);
9769       case rvc_normal:
9770         /* For normal numbers, proceed iff radix == 2.  */
9771         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9772           {
9773             REAL_VALUE_TYPE result = *value;
9774             /* In GCC, normalized significands are in the range [0.5,
9775                1.0).  We want them to be [1.0, 2.0) so set the
9776                exponent to 1.  */
9777             SET_REAL_EXP (&result, 1);
9778             return build_real (rettype, result);
9779           }
9780         break;
9781       }
9782     }
9783
9784   return NULL_TREE;
9785 }
9786
9787 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9788
9789 static tree
9790 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9791 {
9792   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9793     return NULL_TREE;
9794
9795   STRIP_NOPS (arg0);
9796
9797   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9798     return NULL_TREE;
9799
9800   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9801
9802   /* Proceed if a valid pointer type was passed in.  */
9803   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9804     {
9805       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9806       tree frac, exp;
9807
9808       switch (value->cl)
9809       {
9810       case rvc_zero:
9811         /* For +-0, return (*exp = 0, +-0).  */
9812         exp = integer_zero_node;
9813         frac = arg0;
9814         break;
9815       case rvc_nan:
9816       case rvc_inf:
9817         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9818         return omit_one_operand_loc (loc, rettype, arg0, arg1);
9819       case rvc_normal:
9820         {
9821           /* Since the frexp function always expects base 2, and in
9822              GCC normalized significands are already in the range
9823              [0.5, 1.0), we have exactly what frexp wants.  */
9824           REAL_VALUE_TYPE frac_rvt = *value;
9825           SET_REAL_EXP (&frac_rvt, 0);
9826           frac = build_real (rettype, frac_rvt);
9827           exp = build_int_cst (integer_type_node, REAL_EXP (value));
9828         }
9829         break;
9830       default:
9831         gcc_unreachable ();
9832       }
9833
9834       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9835       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9836       TREE_SIDE_EFFECTS (arg1) = 1;
9837       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9838     }
9839
9840   return NULL_TREE;
9841 }
9842
9843 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9844    then we can assume the base is two.  If it's false, then we have to
9845    check the mode of the TYPE parameter in certain cases.  */
9846
9847 static tree
9848 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9849                             tree type, bool ldexp)
9850 {
9851   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9852     {
9853       STRIP_NOPS (arg0);
9854       STRIP_NOPS (arg1);
9855
9856       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9857       if (real_zerop (arg0) || integer_zerop (arg1)
9858           || (TREE_CODE (arg0) == REAL_CST
9859               && !real_isfinite (&TREE_REAL_CST (arg0))))
9860         return omit_one_operand_loc (loc, type, arg0, arg1);
9861
9862       /* If both arguments are constant, then try to evaluate it.  */
9863       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9864           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9865           && host_integerp (arg1, 0))
9866         {
9867           /* Bound the maximum adjustment to twice the range of the
9868              mode's valid exponents.  Use abs to ensure the range is
9869              positive as a sanity check.  */
9870           const long max_exp_adj = 2 *
9871             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9872                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9873
9874           /* Get the user-requested adjustment.  */
9875           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9876
9877           /* The requested adjustment must be inside this range.  This
9878              is a preliminary cap to avoid things like overflow, we
9879              may still fail to compute the result for other reasons.  */
9880           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9881             {
9882               REAL_VALUE_TYPE initial_result;
9883
9884               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9885
9886               /* Ensure we didn't overflow.  */
9887               if (! real_isinf (&initial_result))
9888                 {
9889                   const REAL_VALUE_TYPE trunc_result
9890                     = real_value_truncate (TYPE_MODE (type), initial_result);
9891
9892                   /* Only proceed if the target mode can hold the
9893                      resulting value.  */
9894                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9895                     return build_real (type, trunc_result);
9896                 }
9897             }
9898         }
9899     }
9900
9901   return NULL_TREE;
9902 }
9903
9904 /* Fold a call to builtin modf.  */
9905
9906 static tree
9907 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9908 {
9909   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9910     return NULL_TREE;
9911
9912   STRIP_NOPS (arg0);
9913
9914   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9915     return NULL_TREE;
9916
9917   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9918
9919   /* Proceed if a valid pointer type was passed in.  */
9920   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9921     {
9922       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9923       REAL_VALUE_TYPE trunc, frac;
9924
9925       switch (value->cl)
9926       {
9927       case rvc_nan:
9928       case rvc_zero:
9929         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9930         trunc = frac = *value;
9931         break;
9932       case rvc_inf:
9933         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9934         frac = dconst0;
9935         frac.sign = value->sign;
9936         trunc = *value;
9937         break;
9938       case rvc_normal:
9939         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9940         real_trunc (&trunc, VOIDmode, value);
9941         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9942         /* If the original number was negative and already
9943            integral, then the fractional part is -0.0.  */
9944         if (value->sign && frac.cl == rvc_zero)
9945           frac.sign = value->sign;
9946         break;
9947       }
9948
9949       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9950       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9951                           build_real (rettype, trunc));
9952       TREE_SIDE_EFFECTS (arg1) = 1;
9953       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9954                           build_real (rettype, frac));
9955     }
9956
9957   return NULL_TREE;
9958 }
9959
9960 /* Given a location LOC, an interclass builtin function decl FNDECL
9961    and its single argument ARG, return an folded expression computing
9962    the same, or NULL_TREE if we either couldn't or didn't want to fold
9963    (the latter happen if there's an RTL instruction available).  */
9964
9965 static tree
9966 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9967 {
9968   enum machine_mode mode;
9969
9970   if (!validate_arg (arg, REAL_TYPE))
9971     return NULL_TREE;
9972
9973   if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9974     return NULL_TREE;
9975
9976   mode = TYPE_MODE (TREE_TYPE (arg));
9977
9978   /* If there is no optab, try generic code.  */
9979   switch (DECL_FUNCTION_CODE (fndecl))
9980     {
9981       tree result;
9982
9983     CASE_FLT_FN (BUILT_IN_ISINF):
9984       {
9985         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
9986         tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER);
9987         tree const type = TREE_TYPE (arg);
9988         REAL_VALUE_TYPE r;
9989         char buf[128];
9990
9991         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9992         real_from_string (&r, buf);
9993         result = build_call_expr (isgr_fn, 2,
9994                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9995                                   build_real (type, r));
9996         return result;
9997       }
9998     CASE_FLT_FN (BUILT_IN_FINITE):
9999     case BUILT_IN_ISFINITE:
10000       {
10001         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
10002         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
10003         tree const type = TREE_TYPE (arg);
10004         REAL_VALUE_TYPE r;
10005         char buf[128];
10006
10007         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
10008         real_from_string (&r, buf);
10009         result = build_call_expr (isle_fn, 2,
10010                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
10011                                   build_real (type, r));
10012         /*result = fold_build2_loc (loc, UNGT_EXPR,
10013                                   TREE_TYPE (TREE_TYPE (fndecl)),
10014                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
10015                                   build_real (type, r));
10016         result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
10017                                   TREE_TYPE (TREE_TYPE (fndecl)),
10018                                   result);*/
10019         return result;
10020       }
10021     case BUILT_IN_ISNORMAL:
10022       {
10023         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
10024            islessequal(fabs(x),DBL_MAX).  */
10025         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
10026         tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL);
10027         tree const type = TREE_TYPE (arg);
10028         REAL_VALUE_TYPE rmax, rmin;
10029         char buf[128];
10030
10031         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
10032         real_from_string (&rmax, buf);
10033         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10034         real_from_string (&rmin, buf);
10035         arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10036         result = build_call_expr (isle_fn, 2, arg,
10037                                   build_real (type, rmax));
10038         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
10039                               build_call_expr (isge_fn, 2, arg,
10040                                                build_real (type, rmin)));
10041         return result;
10042       }
10043     default:
10044       break;
10045     }
10046
10047   return NULL_TREE;
10048 }
10049
10050 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
10051    ARG is the argument for the call.  */
10052
10053 static tree
10054 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
10055 {
10056   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10057   REAL_VALUE_TYPE r;
10058
10059   if (!validate_arg (arg, REAL_TYPE))
10060     return NULL_TREE;
10061
10062   switch (builtin_index)
10063     {
10064     case BUILT_IN_ISINF:
10065       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10066         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10067
10068       if (TREE_CODE (arg) == REAL_CST)
10069         {
10070           r = TREE_REAL_CST (arg);
10071           if (real_isinf (&r))
10072             return real_compare (GT_EXPR, &r, &dconst0)
10073                    ? integer_one_node : integer_minus_one_node;
10074           else
10075             return integer_zero_node;
10076         }
10077
10078       return NULL_TREE;
10079
10080     case BUILT_IN_ISINF_SIGN:
10081       {
10082         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10083         /* In a boolean context, GCC will fold the inner COND_EXPR to
10084            1.  So e.g. "if (isinf_sign(x))" would be folded to just
10085            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10086         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10087         tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF);
10088         tree tmp = NULL_TREE;
10089
10090         arg = builtin_save_expr (arg);
10091
10092         if (signbit_fn && isinf_fn)
10093           {
10094             tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10095             tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
10096
10097             signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10098                                         signbit_call, integer_zero_node);
10099             isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10100                                       isinf_call, integer_zero_node);
10101
10102             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
10103                                integer_minus_one_node, integer_one_node);
10104             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10105                                isinf_call, tmp,
10106                                integer_zero_node);
10107           }
10108
10109         return tmp;
10110       }
10111
10112     case BUILT_IN_ISFINITE:
10113       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10114           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10115         return omit_one_operand_loc (loc, type, integer_one_node, arg);
10116
10117       if (TREE_CODE (arg) == REAL_CST)
10118         {
10119           r = TREE_REAL_CST (arg);
10120           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
10121         }
10122
10123       return NULL_TREE;
10124
10125     case BUILT_IN_ISNAN:
10126       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
10127         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10128
10129       if (TREE_CODE (arg) == REAL_CST)
10130         {
10131           r = TREE_REAL_CST (arg);
10132           return real_isnan (&r) ? integer_one_node : integer_zero_node;
10133         }
10134
10135       arg = builtin_save_expr (arg);
10136       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
10137
10138     default:
10139       gcc_unreachable ();
10140     }
10141 }
10142
10143 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10144    This builtin will generate code to return the appropriate floating
10145    point classification depending on the value of the floating point
10146    number passed in.  The possible return values must be supplied as
10147    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
10148    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
10149    one floating point argument which is "type generic".  */
10150
10151 static tree
10152 fold_builtin_fpclassify (location_t loc, tree exp)
10153 {
10154   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10155     arg, type, res, tmp;
10156   enum machine_mode mode;
10157   REAL_VALUE_TYPE r;
10158   char buf[128];
10159
10160   /* Verify the required arguments in the original call.  */
10161   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10162                          INTEGER_TYPE, INTEGER_TYPE,
10163                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10164     return NULL_TREE;
10165
10166   fp_nan = CALL_EXPR_ARG (exp, 0);
10167   fp_infinite = CALL_EXPR_ARG (exp, 1);
10168   fp_normal = CALL_EXPR_ARG (exp, 2);
10169   fp_subnormal = CALL_EXPR_ARG (exp, 3);
10170   fp_zero = CALL_EXPR_ARG (exp, 4);
10171   arg = CALL_EXPR_ARG (exp, 5);
10172   type = TREE_TYPE (arg);
10173   mode = TYPE_MODE (type);
10174   arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10175
10176   /* fpclassify(x) ->
10177        isnan(x) ? FP_NAN :
10178          (fabs(x) == Inf ? FP_INFINITE :
10179            (fabs(x) >= DBL_MIN ? FP_NORMAL :
10180              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
10181
10182   tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10183                      build_real (type, dconst0));
10184   res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10185                      tmp, fp_zero, fp_subnormal);
10186
10187   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10188   real_from_string (&r, buf);
10189   tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10190                      arg, build_real (type, r));
10191   res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
10192
10193   if (HONOR_INFINITIES (mode))
10194     {
10195       real_inf (&r);
10196       tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10197                          build_real (type, r));
10198       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10199                          fp_infinite, res);
10200     }
10201
10202   if (HONOR_NANS (mode))
10203     {
10204       tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10205       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
10206     }
10207
10208   return res;
10209 }
10210
10211 /* Fold a call to an unordered comparison function such as
10212    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
10213    being called and ARG0 and ARG1 are the arguments for the call.
10214    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10215    the opposite of the desired result.  UNORDERED_CODE is used
10216    for modes that can hold NaNs and ORDERED_CODE is used for
10217    the rest.  */
10218
10219 static tree
10220 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
10221                             enum tree_code unordered_code,
10222                             enum tree_code ordered_code)
10223 {
10224   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10225   enum tree_code code;
10226   tree type0, type1;
10227   enum tree_code code0, code1;
10228   tree cmp_type = NULL_TREE;
10229
10230   type0 = TREE_TYPE (arg0);
10231   type1 = TREE_TYPE (arg1);
10232
10233   code0 = TREE_CODE (type0);
10234   code1 = TREE_CODE (type1);
10235
10236   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10237     /* Choose the wider of two real types.  */
10238     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10239       ? type0 : type1;
10240   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10241     cmp_type = type0;
10242   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10243     cmp_type = type1;
10244
10245   arg0 = fold_convert_loc (loc, cmp_type, arg0);
10246   arg1 = fold_convert_loc (loc, cmp_type, arg1);
10247
10248   if (unordered_code == UNORDERED_EXPR)
10249     {
10250       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10251         return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10252       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
10253     }
10254
10255   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10256                                                    : ordered_code;
10257   return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10258                       fold_build2_loc (loc, code, type, arg0, arg1));
10259 }
10260
10261 /* Fold a call to built-in function FNDECL with 0 arguments.
10262    IGNORE is true if the result of the function call is ignored.  This
10263    function returns NULL_TREE if no simplification was possible.  */
10264
10265 static tree
10266 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10267 {
10268   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10269   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10270   switch (fcode)
10271     {
10272     CASE_FLT_FN (BUILT_IN_INF):
10273     case BUILT_IN_INFD32:
10274     case BUILT_IN_INFD64:
10275     case BUILT_IN_INFD128:
10276       return fold_builtin_inf (loc, type, true);
10277
10278     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10279       return fold_builtin_inf (loc, type, false);
10280
10281     case BUILT_IN_CLASSIFY_TYPE:
10282       return fold_builtin_classify_type (NULL_TREE);
10283
10284     default:
10285       break;
10286     }
10287   return NULL_TREE;
10288 }
10289
10290 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10291    IGNORE is true if the result of the function call is ignored.  This
10292    function returns NULL_TREE if no simplification was possible.  */
10293
10294 static tree
10295 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
10296 {
10297   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10298   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10299   switch (fcode)
10300     {
10301     case BUILT_IN_CONSTANT_P:
10302       {
10303         tree val = fold_builtin_constant_p (arg0);
10304
10305         /* Gimplification will pull the CALL_EXPR for the builtin out of
10306            an if condition.  When not optimizing, we'll not CSE it back.
10307            To avoid link error types of regressions, return false now.  */
10308         if (!val && !optimize)
10309           val = integer_zero_node;
10310
10311         return val;
10312       }
10313
10314     case BUILT_IN_CLASSIFY_TYPE:
10315       return fold_builtin_classify_type (arg0);
10316
10317     case BUILT_IN_STRLEN:
10318       return fold_builtin_strlen (loc, type, arg0);
10319
10320     CASE_FLT_FN (BUILT_IN_FABS):
10321       return fold_builtin_fabs (loc, arg0, type);
10322
10323     case BUILT_IN_ABS:
10324     case BUILT_IN_LABS:
10325     case BUILT_IN_LLABS:
10326     case BUILT_IN_IMAXABS:
10327       return fold_builtin_abs (loc, arg0, type);
10328
10329     CASE_FLT_FN (BUILT_IN_CONJ):
10330       if (validate_arg (arg0, COMPLEX_TYPE)
10331         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10332         return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
10333     break;
10334
10335     CASE_FLT_FN (BUILT_IN_CREAL):
10336       if (validate_arg (arg0, COMPLEX_TYPE)
10337         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10338         return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10339     break;
10340
10341     CASE_FLT_FN (BUILT_IN_CIMAG):
10342       if (validate_arg (arg0, COMPLEX_TYPE)
10343           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10344         return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10345     break;
10346
10347     CASE_FLT_FN (BUILT_IN_CCOS):
10348       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10349
10350     CASE_FLT_FN (BUILT_IN_CCOSH):
10351       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10352
10353     CASE_FLT_FN (BUILT_IN_CPROJ):
10354       return fold_builtin_cproj(loc, arg0, type);
10355
10356     CASE_FLT_FN (BUILT_IN_CSIN):
10357       if (validate_arg (arg0, COMPLEX_TYPE)
10358           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10359         return do_mpc_arg1 (arg0, type, mpc_sin);
10360     break;
10361
10362     CASE_FLT_FN (BUILT_IN_CSINH):
10363       if (validate_arg (arg0, COMPLEX_TYPE)
10364           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10365         return do_mpc_arg1 (arg0, type, mpc_sinh);
10366     break;
10367
10368     CASE_FLT_FN (BUILT_IN_CTAN):
10369       if (validate_arg (arg0, COMPLEX_TYPE)
10370           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10371         return do_mpc_arg1 (arg0, type, mpc_tan);
10372     break;
10373
10374     CASE_FLT_FN (BUILT_IN_CTANH):
10375       if (validate_arg (arg0, COMPLEX_TYPE)
10376           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10377         return do_mpc_arg1 (arg0, type, mpc_tanh);
10378     break;
10379
10380     CASE_FLT_FN (BUILT_IN_CLOG):
10381       if (validate_arg (arg0, COMPLEX_TYPE)
10382           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10383         return do_mpc_arg1 (arg0, type, mpc_log);
10384     break;
10385
10386     CASE_FLT_FN (BUILT_IN_CSQRT):
10387       if (validate_arg (arg0, COMPLEX_TYPE)
10388           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10389         return do_mpc_arg1 (arg0, type, mpc_sqrt);
10390     break;
10391
10392     CASE_FLT_FN (BUILT_IN_CASIN):
10393       if (validate_arg (arg0, COMPLEX_TYPE)
10394           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10395         return do_mpc_arg1 (arg0, type, mpc_asin);
10396     break;
10397
10398     CASE_FLT_FN (BUILT_IN_CACOS):
10399       if (validate_arg (arg0, COMPLEX_TYPE)
10400           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10401         return do_mpc_arg1 (arg0, type, mpc_acos);
10402     break;
10403
10404     CASE_FLT_FN (BUILT_IN_CATAN):
10405       if (validate_arg (arg0, COMPLEX_TYPE)
10406           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10407         return do_mpc_arg1 (arg0, type, mpc_atan);
10408     break;
10409
10410     CASE_FLT_FN (BUILT_IN_CASINH):
10411       if (validate_arg (arg0, COMPLEX_TYPE)
10412           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10413         return do_mpc_arg1 (arg0, type, mpc_asinh);
10414     break;
10415
10416     CASE_FLT_FN (BUILT_IN_CACOSH):
10417       if (validate_arg (arg0, COMPLEX_TYPE)
10418           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10419         return do_mpc_arg1 (arg0, type, mpc_acosh);
10420     break;
10421
10422     CASE_FLT_FN (BUILT_IN_CATANH):
10423       if (validate_arg (arg0, COMPLEX_TYPE)
10424           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10425         return do_mpc_arg1 (arg0, type, mpc_atanh);
10426     break;
10427
10428     CASE_FLT_FN (BUILT_IN_CABS):
10429       return fold_builtin_cabs (loc, arg0, type, fndecl);
10430
10431     CASE_FLT_FN (BUILT_IN_CARG):
10432       return fold_builtin_carg (loc, arg0, type);
10433
10434     CASE_FLT_FN (BUILT_IN_SQRT):
10435       return fold_builtin_sqrt (loc, arg0, type);
10436
10437     CASE_FLT_FN (BUILT_IN_CBRT):
10438       return fold_builtin_cbrt (loc, arg0, type);
10439
10440     CASE_FLT_FN (BUILT_IN_ASIN):
10441       if (validate_arg (arg0, REAL_TYPE))
10442         return do_mpfr_arg1 (arg0, type, mpfr_asin,
10443                              &dconstm1, &dconst1, true);
10444     break;
10445
10446     CASE_FLT_FN (BUILT_IN_ACOS):
10447       if (validate_arg (arg0, REAL_TYPE))
10448         return do_mpfr_arg1 (arg0, type, mpfr_acos,
10449                              &dconstm1, &dconst1, true);
10450     break;
10451
10452     CASE_FLT_FN (BUILT_IN_ATAN):
10453       if (validate_arg (arg0, REAL_TYPE))
10454         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10455     break;
10456
10457     CASE_FLT_FN (BUILT_IN_ASINH):
10458       if (validate_arg (arg0, REAL_TYPE))
10459         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10460     break;
10461
10462     CASE_FLT_FN (BUILT_IN_ACOSH):
10463       if (validate_arg (arg0, REAL_TYPE))
10464         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10465                              &dconst1, NULL, true);
10466     break;
10467
10468     CASE_FLT_FN (BUILT_IN_ATANH):
10469       if (validate_arg (arg0, REAL_TYPE))
10470         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10471                              &dconstm1, &dconst1, false);
10472     break;
10473
10474     CASE_FLT_FN (BUILT_IN_SIN):
10475       if (validate_arg (arg0, REAL_TYPE))
10476         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10477     break;
10478
10479     CASE_FLT_FN (BUILT_IN_COS):
10480       return fold_builtin_cos (loc, arg0, type, fndecl);
10481
10482     CASE_FLT_FN (BUILT_IN_TAN):
10483       return fold_builtin_tan (arg0, type);
10484
10485     CASE_FLT_FN (BUILT_IN_CEXP):
10486       return fold_builtin_cexp (loc, arg0, type);
10487
10488     CASE_FLT_FN (BUILT_IN_CEXPI):
10489       if (validate_arg (arg0, REAL_TYPE))
10490         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10491     break;
10492
10493     CASE_FLT_FN (BUILT_IN_SINH):
10494       if (validate_arg (arg0, REAL_TYPE))
10495         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10496     break;
10497
10498     CASE_FLT_FN (BUILT_IN_COSH):
10499       return fold_builtin_cosh (loc, arg0, type, fndecl);
10500
10501     CASE_FLT_FN (BUILT_IN_TANH):
10502       if (validate_arg (arg0, REAL_TYPE))
10503         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10504     break;
10505
10506     CASE_FLT_FN (BUILT_IN_ERF):
10507       if (validate_arg (arg0, REAL_TYPE))
10508         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10509     break;
10510
10511     CASE_FLT_FN (BUILT_IN_ERFC):
10512       if (validate_arg (arg0, REAL_TYPE))
10513         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10514     break;
10515
10516     CASE_FLT_FN (BUILT_IN_TGAMMA):
10517       if (validate_arg (arg0, REAL_TYPE))
10518         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10519     break;
10520
10521     CASE_FLT_FN (BUILT_IN_EXP):
10522       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10523
10524     CASE_FLT_FN (BUILT_IN_EXP2):
10525       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10526
10527     CASE_FLT_FN (BUILT_IN_EXP10):
10528     CASE_FLT_FN (BUILT_IN_POW10):
10529       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10530
10531     CASE_FLT_FN (BUILT_IN_EXPM1):
10532       if (validate_arg (arg0, REAL_TYPE))
10533         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10534     break;
10535
10536     CASE_FLT_FN (BUILT_IN_LOG):
10537     return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10538
10539     CASE_FLT_FN (BUILT_IN_LOG2):
10540       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10541
10542     CASE_FLT_FN (BUILT_IN_LOG10):
10543       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10544
10545     CASE_FLT_FN (BUILT_IN_LOG1P):
10546       if (validate_arg (arg0, REAL_TYPE))
10547         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10548                              &dconstm1, NULL, false);
10549     break;
10550
10551     CASE_FLT_FN (BUILT_IN_J0):
10552       if (validate_arg (arg0, REAL_TYPE))
10553         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10554                              NULL, NULL, 0);
10555     break;
10556
10557     CASE_FLT_FN (BUILT_IN_J1):
10558       if (validate_arg (arg0, REAL_TYPE))
10559         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10560                              NULL, NULL, 0);
10561     break;
10562
10563     CASE_FLT_FN (BUILT_IN_Y0):
10564       if (validate_arg (arg0, REAL_TYPE))
10565         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10566                              &dconst0, NULL, false);
10567     break;
10568
10569     CASE_FLT_FN (BUILT_IN_Y1):
10570       if (validate_arg (arg0, REAL_TYPE))
10571         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10572                              &dconst0, NULL, false);
10573     break;
10574
10575     CASE_FLT_FN (BUILT_IN_NAN):
10576     case BUILT_IN_NAND32:
10577     case BUILT_IN_NAND64:
10578     case BUILT_IN_NAND128:
10579       return fold_builtin_nan (arg0, type, true);
10580
10581     CASE_FLT_FN (BUILT_IN_NANS):
10582       return fold_builtin_nan (arg0, type, false);
10583
10584     CASE_FLT_FN (BUILT_IN_FLOOR):
10585       return fold_builtin_floor (loc, fndecl, arg0);
10586
10587     CASE_FLT_FN (BUILT_IN_CEIL):
10588       return fold_builtin_ceil (loc, fndecl, arg0);
10589
10590     CASE_FLT_FN (BUILT_IN_TRUNC):
10591       return fold_builtin_trunc (loc, fndecl, arg0);
10592
10593     CASE_FLT_FN (BUILT_IN_ROUND):
10594       return fold_builtin_round (loc, fndecl, arg0);
10595
10596     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10597     CASE_FLT_FN (BUILT_IN_RINT):
10598       return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10599
10600     CASE_FLT_FN (BUILT_IN_ICEIL):
10601     CASE_FLT_FN (BUILT_IN_LCEIL):
10602     CASE_FLT_FN (BUILT_IN_LLCEIL):
10603     CASE_FLT_FN (BUILT_IN_LFLOOR):
10604     CASE_FLT_FN (BUILT_IN_IFLOOR):
10605     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10606     CASE_FLT_FN (BUILT_IN_IROUND):
10607     CASE_FLT_FN (BUILT_IN_LROUND):
10608     CASE_FLT_FN (BUILT_IN_LLROUND):
10609       return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10610
10611     CASE_FLT_FN (BUILT_IN_IRINT):
10612     CASE_FLT_FN (BUILT_IN_LRINT):
10613     CASE_FLT_FN (BUILT_IN_LLRINT):
10614       return fold_fixed_mathfn (loc, fndecl, arg0);
10615
10616     case BUILT_IN_BSWAP16:
10617     case BUILT_IN_BSWAP32:
10618     case BUILT_IN_BSWAP64:
10619       return fold_builtin_bswap (fndecl, arg0);
10620
10621     CASE_INT_FN (BUILT_IN_FFS):
10622     CASE_INT_FN (BUILT_IN_CLZ):
10623     CASE_INT_FN (BUILT_IN_CTZ):
10624     CASE_INT_FN (BUILT_IN_CLRSB):
10625     CASE_INT_FN (BUILT_IN_POPCOUNT):
10626     CASE_INT_FN (BUILT_IN_PARITY):
10627       return fold_builtin_bitop (fndecl, arg0);
10628
10629     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10630       return fold_builtin_signbit (loc, arg0, type);
10631
10632     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10633       return fold_builtin_significand (loc, arg0, type);
10634
10635     CASE_FLT_FN (BUILT_IN_ILOGB):
10636     CASE_FLT_FN (BUILT_IN_LOGB):
10637       return fold_builtin_logb (loc, arg0, type);
10638
10639     case BUILT_IN_ISASCII:
10640       return fold_builtin_isascii (loc, arg0);
10641
10642     case BUILT_IN_TOASCII:
10643       return fold_builtin_toascii (loc, arg0);
10644
10645     case BUILT_IN_ISDIGIT:
10646       return fold_builtin_isdigit (loc, arg0);
10647
10648     CASE_FLT_FN (BUILT_IN_FINITE):
10649     case BUILT_IN_FINITED32:
10650     case BUILT_IN_FINITED64:
10651     case BUILT_IN_FINITED128:
10652     case BUILT_IN_ISFINITE:
10653       {
10654         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10655         if (ret)
10656           return ret;
10657         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10658       }
10659
10660     CASE_FLT_FN (BUILT_IN_ISINF):
10661     case BUILT_IN_ISINFD32:
10662     case BUILT_IN_ISINFD64:
10663     case BUILT_IN_ISINFD128:
10664       {
10665         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10666         if (ret)
10667           return ret;
10668         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10669       }
10670
10671     case BUILT_IN_ISNORMAL:
10672       return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10673
10674     case BUILT_IN_ISINF_SIGN:
10675       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10676
10677     CASE_FLT_FN (BUILT_IN_ISNAN):
10678     case BUILT_IN_ISNAND32:
10679     case BUILT_IN_ISNAND64:
10680     case BUILT_IN_ISNAND128:
10681       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10682
10683     case BUILT_IN_PRINTF:
10684     case BUILT_IN_PRINTF_UNLOCKED:
10685     case BUILT_IN_VPRINTF:
10686       return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10687
10688     case BUILT_IN_FREE:
10689       if (integer_zerop (arg0))
10690         return build_empty_stmt (loc);
10691       break;
10692
10693     default:
10694       break;
10695     }
10696
10697   return NULL_TREE;
10698
10699 }
10700
10701 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10702    IGNORE is true if the result of the function call is ignored.  This
10703    function returns NULL_TREE if no simplification was possible.  */
10704
10705 static tree
10706 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10707 {
10708   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10709   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10710
10711   switch (fcode)
10712     {
10713     CASE_FLT_FN (BUILT_IN_JN):
10714       if (validate_arg (arg0, INTEGER_TYPE)
10715           && validate_arg (arg1, REAL_TYPE))
10716         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10717     break;
10718
10719     CASE_FLT_FN (BUILT_IN_YN):
10720       if (validate_arg (arg0, INTEGER_TYPE)
10721           && validate_arg (arg1, REAL_TYPE))
10722         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10723                                  &dconst0, false);
10724     break;
10725
10726     CASE_FLT_FN (BUILT_IN_DREM):
10727     CASE_FLT_FN (BUILT_IN_REMAINDER):
10728       if (validate_arg (arg0, REAL_TYPE)
10729           && validate_arg(arg1, REAL_TYPE))
10730         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10731     break;
10732
10733     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10734     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10735       if (validate_arg (arg0, REAL_TYPE)
10736           && validate_arg(arg1, POINTER_TYPE))
10737         return do_mpfr_lgamma_r (arg0, arg1, type);
10738     break;
10739
10740     CASE_FLT_FN (BUILT_IN_ATAN2):
10741       if (validate_arg (arg0, REAL_TYPE)
10742           && validate_arg(arg1, REAL_TYPE))
10743         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10744     break;
10745
10746     CASE_FLT_FN (BUILT_IN_FDIM):
10747       if (validate_arg (arg0, REAL_TYPE)
10748           && validate_arg(arg1, REAL_TYPE))
10749         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10750     break;
10751
10752     CASE_FLT_FN (BUILT_IN_HYPOT):
10753       return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10754
10755     CASE_FLT_FN (BUILT_IN_CPOW):
10756       if (validate_arg (arg0, COMPLEX_TYPE)
10757           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10758           && validate_arg (arg1, COMPLEX_TYPE)
10759           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10760         return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10761     break;
10762
10763     CASE_FLT_FN (BUILT_IN_LDEXP):
10764       return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10765     CASE_FLT_FN (BUILT_IN_SCALBN):
10766     CASE_FLT_FN (BUILT_IN_SCALBLN):
10767       return fold_builtin_load_exponent (loc, arg0, arg1,
10768                                          type, /*ldexp=*/false);
10769
10770     CASE_FLT_FN (BUILT_IN_FREXP):
10771       return fold_builtin_frexp (loc, arg0, arg1, type);
10772
10773     CASE_FLT_FN (BUILT_IN_MODF):
10774       return fold_builtin_modf (loc, arg0, arg1, type);
10775
10776     case BUILT_IN_BZERO:
10777       return fold_builtin_bzero (loc, arg0, arg1, ignore);
10778
10779     case BUILT_IN_FPUTS:
10780       return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10781
10782     case BUILT_IN_FPUTS_UNLOCKED:
10783       return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10784
10785     case BUILT_IN_STRSTR:
10786       return fold_builtin_strstr (loc, arg0, arg1, type);
10787
10788     case BUILT_IN_STRCAT:
10789       return fold_builtin_strcat (loc, arg0, arg1);
10790
10791     case BUILT_IN_STRSPN:
10792       return fold_builtin_strspn (loc, arg0, arg1);
10793
10794     case BUILT_IN_STRCSPN:
10795       return fold_builtin_strcspn (loc, arg0, arg1);
10796
10797     case BUILT_IN_STRCHR:
10798     case BUILT_IN_INDEX:
10799       return fold_builtin_strchr (loc, arg0, arg1, type);
10800
10801     case BUILT_IN_STRRCHR:
10802     case BUILT_IN_RINDEX:
10803       return fold_builtin_strrchr (loc, arg0, arg1, type);
10804
10805     case BUILT_IN_STRCPY:
10806       return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10807
10808     case BUILT_IN_STPCPY:
10809       if (ignore)
10810         {
10811           tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
10812           if (!fn)
10813             break;
10814
10815           return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10816         }
10817       else
10818         return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10819       break;
10820
10821     case BUILT_IN_STRCMP:
10822       return fold_builtin_strcmp (loc, arg0, arg1);
10823
10824     case BUILT_IN_STRPBRK:
10825       return fold_builtin_strpbrk (loc, arg0, arg1, type);
10826
10827     case BUILT_IN_EXPECT:
10828       return fold_builtin_expect (loc, arg0, arg1);
10829
10830     CASE_FLT_FN (BUILT_IN_POW):
10831       return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10832
10833     CASE_FLT_FN (BUILT_IN_POWI):
10834       return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10835
10836     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10837       return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10838
10839     CASE_FLT_FN (BUILT_IN_FMIN):
10840       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10841
10842     CASE_FLT_FN (BUILT_IN_FMAX):
10843       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10844
10845     case BUILT_IN_ISGREATER:
10846       return fold_builtin_unordered_cmp (loc, fndecl,
10847                                          arg0, arg1, UNLE_EXPR, LE_EXPR);
10848     case BUILT_IN_ISGREATEREQUAL:
10849       return fold_builtin_unordered_cmp (loc, fndecl,
10850                                          arg0, arg1, UNLT_EXPR, LT_EXPR);
10851     case BUILT_IN_ISLESS:
10852       return fold_builtin_unordered_cmp (loc, fndecl,
10853                                          arg0, arg1, UNGE_EXPR, GE_EXPR);
10854     case BUILT_IN_ISLESSEQUAL:
10855       return fold_builtin_unordered_cmp (loc, fndecl,
10856                                          arg0, arg1, UNGT_EXPR, GT_EXPR);
10857     case BUILT_IN_ISLESSGREATER:
10858       return fold_builtin_unordered_cmp (loc, fndecl,
10859                                          arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10860     case BUILT_IN_ISUNORDERED:
10861       return fold_builtin_unordered_cmp (loc, fndecl,
10862                                          arg0, arg1, UNORDERED_EXPR,
10863                                          NOP_EXPR);
10864
10865       /* We do the folding for va_start in the expander.  */
10866     case BUILT_IN_VA_START:
10867       break;
10868
10869     case BUILT_IN_SPRINTF:
10870       return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10871
10872     case BUILT_IN_OBJECT_SIZE:
10873       return fold_builtin_object_size (arg0, arg1);
10874
10875     case BUILT_IN_PRINTF:
10876     case BUILT_IN_PRINTF_UNLOCKED:
10877     case BUILT_IN_VPRINTF:
10878       return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10879
10880     case BUILT_IN_PRINTF_CHK:
10881     case BUILT_IN_VPRINTF_CHK:
10882       if (!validate_arg (arg0, INTEGER_TYPE)
10883           || TREE_SIDE_EFFECTS (arg0))
10884         return NULL_TREE;
10885       else
10886         return fold_builtin_printf (loc, fndecl,
10887                                     arg1, NULL_TREE, ignore, fcode);
10888     break;
10889
10890     case BUILT_IN_FPRINTF:
10891     case BUILT_IN_FPRINTF_UNLOCKED:
10892     case BUILT_IN_VFPRINTF:
10893       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10894                                    ignore, fcode);
10895
10896     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
10897       return fold_builtin_atomic_always_lock_free (arg0, arg1);
10898
10899     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
10900       return fold_builtin_atomic_is_lock_free (arg0, arg1);
10901
10902     default:
10903       break;
10904     }
10905   return NULL_TREE;
10906 }
10907
10908 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10909    and ARG2.  IGNORE is true if the result of the function call is ignored.
10910    This function returns NULL_TREE if no simplification was possible.  */
10911
10912 static tree
10913 fold_builtin_3 (location_t loc, tree fndecl,
10914                 tree arg0, tree arg1, tree arg2, bool ignore)
10915 {
10916   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10917   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10918   switch (fcode)
10919     {
10920
10921     CASE_FLT_FN (BUILT_IN_SINCOS):
10922       return fold_builtin_sincos (loc, arg0, arg1, arg2);
10923
10924     CASE_FLT_FN (BUILT_IN_FMA):
10925       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
10926     break;
10927
10928     CASE_FLT_FN (BUILT_IN_REMQUO):
10929       if (validate_arg (arg0, REAL_TYPE)
10930           && validate_arg(arg1, REAL_TYPE)
10931           && validate_arg(arg2, POINTER_TYPE))
10932         return do_mpfr_remquo (arg0, arg1, arg2);
10933     break;
10934
10935     case BUILT_IN_MEMSET:
10936       return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10937
10938     case BUILT_IN_BCOPY:
10939       return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10940                                      void_type_node, true, /*endp=*/3);
10941
10942     case BUILT_IN_MEMCPY:
10943       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10944                                      type, ignore, /*endp=*/0);
10945
10946     case BUILT_IN_MEMPCPY:
10947       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10948                                      type, ignore, /*endp=*/1);
10949
10950     case BUILT_IN_MEMMOVE:
10951       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10952                                      type, ignore, /*endp=*/3);
10953
10954     case BUILT_IN_STRNCAT:
10955       return fold_builtin_strncat (loc, arg0, arg1, arg2);
10956
10957     case BUILT_IN_STRNCPY:
10958       return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10959
10960     case BUILT_IN_STRNCMP:
10961       return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10962
10963     case BUILT_IN_MEMCHR:
10964       return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10965
10966     case BUILT_IN_BCMP:
10967     case BUILT_IN_MEMCMP:
10968       return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10969
10970     case BUILT_IN_SPRINTF:
10971       return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10972
10973     case BUILT_IN_SNPRINTF:
10974       return fold_builtin_snprintf (loc, arg0, arg1, arg2, NULL_TREE, ignore);
10975
10976     case BUILT_IN_STRCPY_CHK:
10977     case BUILT_IN_STPCPY_CHK:
10978       return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10979                                       ignore, fcode);
10980
10981     case BUILT_IN_STRCAT_CHK:
10982       return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10983
10984     case BUILT_IN_PRINTF_CHK:
10985     case BUILT_IN_VPRINTF_CHK:
10986       if (!validate_arg (arg0, INTEGER_TYPE)
10987           || TREE_SIDE_EFFECTS (arg0))
10988         return NULL_TREE;
10989       else
10990         return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10991     break;
10992
10993     case BUILT_IN_FPRINTF:
10994     case BUILT_IN_FPRINTF_UNLOCKED:
10995     case BUILT_IN_VFPRINTF:
10996       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10997                                    ignore, fcode);
10998
10999     case BUILT_IN_FPRINTF_CHK:
11000     case BUILT_IN_VFPRINTF_CHK:
11001       if (!validate_arg (arg1, INTEGER_TYPE)
11002           || TREE_SIDE_EFFECTS (arg1))
11003         return NULL_TREE;
11004       else
11005         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
11006                                      ignore, fcode);
11007
11008     default:
11009       break;
11010     }
11011   return NULL_TREE;
11012 }
11013
11014 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
11015    ARG2, and ARG3.  IGNORE is true if the result of the function call is
11016    ignored.  This function returns NULL_TREE if no simplification was
11017    possible.  */
11018
11019 static tree
11020 fold_builtin_4 (location_t loc, tree fndecl,
11021                 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
11022 {
11023   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11024
11025   switch (fcode)
11026     {
11027     case BUILT_IN_MEMCPY_CHK:
11028     case BUILT_IN_MEMPCPY_CHK:
11029     case BUILT_IN_MEMMOVE_CHK:
11030     case BUILT_IN_MEMSET_CHK:
11031       return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
11032                                       NULL_TREE, ignore,
11033                                       DECL_FUNCTION_CODE (fndecl));
11034
11035     case BUILT_IN_STRNCPY_CHK:
11036     case BUILT_IN_STPNCPY_CHK:
11037       return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE,
11038                                        ignore, fcode);
11039
11040     case BUILT_IN_STRNCAT_CHK:
11041       return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
11042
11043     case BUILT_IN_SNPRINTF:
11044       return fold_builtin_snprintf (loc, arg0, arg1, arg2, arg3, ignore);
11045
11046     case BUILT_IN_FPRINTF_CHK:
11047     case BUILT_IN_VFPRINTF_CHK:
11048       if (!validate_arg (arg1, INTEGER_TYPE)
11049           || TREE_SIDE_EFFECTS (arg1))
11050         return NULL_TREE;
11051       else
11052         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
11053                                      ignore, fcode);
11054     break;
11055
11056     default:
11057       break;
11058     }
11059   return NULL_TREE;
11060 }
11061
11062 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
11063     arguments, where NARGS <= 4.  IGNORE is true if the result of the
11064     function call is ignored.  This function returns NULL_TREE if no
11065     simplification was possible.  Note that this only folds builtins with
11066     fixed argument patterns.  Foldings that do varargs-to-varargs
11067     transformations, or that match calls with more than 4 arguments,
11068     need to be handled with fold_builtin_varargs instead.  */
11069
11070 #define MAX_ARGS_TO_FOLD_BUILTIN 4
11071
11072 static tree
11073 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
11074 {
11075   tree ret = NULL_TREE;
11076
11077   switch (nargs)
11078     {
11079     case 0:
11080       ret = fold_builtin_0 (loc, fndecl, ignore);
11081       break;
11082     case 1:
11083       ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
11084       break;
11085     case 2:
11086       ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
11087       break;
11088     case 3:
11089       ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
11090       break;
11091     case 4:
11092       ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
11093                             ignore);
11094       break;
11095     default:
11096       break;
11097     }
11098   if (ret)
11099     {
11100       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11101       SET_EXPR_LOCATION (ret, loc);
11102       TREE_NO_WARNING (ret) = 1;
11103       return ret;
11104     }
11105   return NULL_TREE;
11106 }
11107
11108 /* Builtins with folding operations that operate on "..." arguments
11109    need special handling; we need to store the arguments in a convenient
11110    data structure before attempting any folding.  Fortunately there are
11111    only a few builtins that fall into this category.  FNDECL is the
11112    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11113    result of the function call is ignored.  */
11114
11115 static tree
11116 fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11117                       bool ignore ATTRIBUTE_UNUSED)
11118 {
11119   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11120   tree ret = NULL_TREE;
11121
11122   switch (fcode)
11123     {
11124     case BUILT_IN_SPRINTF_CHK:
11125     case BUILT_IN_VSPRINTF_CHK:
11126       ret = fold_builtin_sprintf_chk (loc, exp, fcode);
11127       break;
11128
11129     case BUILT_IN_SNPRINTF_CHK:
11130     case BUILT_IN_VSNPRINTF_CHK:
11131       ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
11132       break;
11133
11134     case BUILT_IN_FPCLASSIFY:
11135       ret = fold_builtin_fpclassify (loc, exp);
11136       break;
11137
11138     default:
11139       break;
11140     }
11141   if (ret)
11142     {
11143       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11144       SET_EXPR_LOCATION (ret, loc);
11145       TREE_NO_WARNING (ret) = 1;
11146       return ret;
11147     }
11148   return NULL_TREE;
11149 }
11150
11151 /* Return true if FNDECL shouldn't be folded right now.
11152    If a built-in function has an inline attribute always_inline
11153    wrapper, defer folding it after always_inline functions have
11154    been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11155    might not be performed.  */
11156
11157 bool
11158 avoid_folding_inline_builtin (tree fndecl)
11159 {
11160   return (DECL_DECLARED_INLINE_P (fndecl)
11161           && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11162           && cfun
11163           && !cfun->always_inline_functions_inlined
11164           && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11165 }
11166
11167 /* A wrapper function for builtin folding that prevents warnings for
11168    "statement without effect" and the like, caused by removing the
11169    call node earlier than the warning is generated.  */
11170
11171 tree
11172 fold_call_expr (location_t loc, tree exp, bool ignore)
11173 {
11174   tree ret = NULL_TREE;
11175   tree fndecl = get_callee_fndecl (exp);
11176   if (fndecl
11177       && TREE_CODE (fndecl) == FUNCTION_DECL
11178       && DECL_BUILT_IN (fndecl)
11179       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11180          yet.  Defer folding until we see all the arguments
11181          (after inlining).  */
11182       && !CALL_EXPR_VA_ARG_PACK (exp))
11183     {
11184       int nargs = call_expr_nargs (exp);
11185
11186       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11187          instead last argument is __builtin_va_arg_pack ().  Defer folding
11188          even in that case, until arguments are finalized.  */
11189       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11190         {
11191           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11192           if (fndecl2
11193               && TREE_CODE (fndecl2) == FUNCTION_DECL
11194               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11195               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11196             return NULL_TREE;
11197         }
11198
11199       if (avoid_folding_inline_builtin (fndecl))
11200         return NULL_TREE;
11201
11202       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11203         return targetm.fold_builtin (fndecl, call_expr_nargs (exp),
11204                                      CALL_EXPR_ARGP (exp), ignore);
11205       else
11206         {
11207           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11208             {
11209               tree *args = CALL_EXPR_ARGP (exp);
11210               ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
11211             }
11212           if (!ret)
11213             ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
11214           if (ret)
11215             return ret;
11216         }
11217     }
11218   return NULL_TREE;
11219 }
11220
11221 /* Conveniently construct a function call expression.  FNDECL names the
11222    function to be called and N arguments are passed in the array
11223    ARGARRAY.  */
11224
11225 tree
11226 build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
11227 {
11228   tree fntype = TREE_TYPE (fndecl);
11229   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11230  
11231   return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
11232 }
11233
11234 /* Conveniently construct a function call expression.  FNDECL names the
11235    function to be called and the arguments are passed in the vector
11236    VEC.  */
11237
11238 tree
11239 build_call_expr_loc_vec (location_t loc, tree fndecl, vec<tree, va_gc> *vec)
11240 {
11241   return build_call_expr_loc_array (loc, fndecl, vec_safe_length (vec),
11242                                     vec_safe_address (vec));
11243 }
11244
11245
11246 /* Conveniently construct a function call expression.  FNDECL names the
11247    function to be called, N is the number of arguments, and the "..."
11248    parameters are the argument expressions.  */
11249
11250 tree
11251 build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
11252 {
11253   va_list ap;
11254   tree *argarray = XALLOCAVEC (tree, n);
11255   int i;
11256
11257   va_start (ap, n);
11258   for (i = 0; i < n; i++)
11259     argarray[i] = va_arg (ap, tree);
11260   va_end (ap);
11261   return build_call_expr_loc_array (loc, fndecl, n, argarray);
11262 }
11263
11264 /* Like build_call_expr_loc (UNKNOWN_LOCATION, ...).  Duplicated because
11265    varargs macros aren't supported by all bootstrap compilers.  */
11266
11267 tree
11268 build_call_expr (tree fndecl, int n, ...)
11269 {
11270   va_list ap;
11271   tree *argarray = XALLOCAVEC (tree, n);
11272   int i;
11273
11274   va_start (ap, n);
11275   for (i = 0; i < n; i++)
11276     argarray[i] = va_arg (ap, tree);
11277   va_end (ap);
11278   return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
11279 }
11280
11281 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
11282    N arguments are passed in the array ARGARRAY.  */
11283
11284 tree
11285 fold_builtin_call_array (location_t loc, tree type,
11286                          tree fn,
11287                          int n,
11288                          tree *argarray)
11289 {
11290   tree ret = NULL_TREE;
11291    tree exp;
11292
11293   if (TREE_CODE (fn) == ADDR_EXPR)
11294   {
11295     tree fndecl = TREE_OPERAND (fn, 0);
11296     if (TREE_CODE (fndecl) == FUNCTION_DECL
11297         && DECL_BUILT_IN (fndecl))
11298       {
11299         /* If last argument is __builtin_va_arg_pack (), arguments to this
11300            function are not finalized yet.  Defer folding until they are.  */
11301         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11302           {
11303             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11304             if (fndecl2
11305                 && TREE_CODE (fndecl2) == FUNCTION_DECL
11306                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11307                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11308               return build_call_array_loc (loc, type, fn, n, argarray);
11309           }
11310         if (avoid_folding_inline_builtin (fndecl))
11311           return build_call_array_loc (loc, type, fn, n, argarray);
11312         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11313           {
11314             ret = targetm.fold_builtin (fndecl, n, argarray, false);
11315             if (ret)
11316               return ret;
11317
11318             return build_call_array_loc (loc, type, fn, n, argarray);
11319           }
11320         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11321           {
11322             /* First try the transformations that don't require consing up
11323                an exp.  */
11324             ret = fold_builtin_n (loc, fndecl, argarray, n, false);
11325             if (ret)
11326               return ret;
11327           }
11328
11329         /* If we got this far, we need to build an exp.  */
11330         exp = build_call_array_loc (loc, type, fn, n, argarray);
11331         ret = fold_builtin_varargs (loc, fndecl, exp, false);
11332         return ret ? ret : exp;
11333       }
11334   }
11335
11336   return build_call_array_loc (loc, type, fn, n, argarray);
11337 }
11338
11339 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11340    list ARGS along with N new arguments in NEWARGS.  SKIP is the number
11341    of arguments in ARGS to be omitted.  OLDNARGS is the number of
11342    elements in ARGS.  */
11343
11344 static tree
11345 rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
11346                           int skip, tree fndecl, int n, va_list newargs)
11347 {
11348   int nargs = oldnargs - skip + n;
11349   tree *buffer;
11350
11351   if (n > 0)
11352     {
11353       int i, j;
11354
11355       buffer = XALLOCAVEC (tree, nargs);
11356       for (i = 0; i < n; i++)
11357         buffer[i] = va_arg (newargs, tree);
11358       for (j = skip; j < oldnargs; j++, i++)
11359         buffer[i] = args[j];
11360     }
11361   else
11362     buffer = args + skip;
11363
11364   return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
11365 }
11366
11367 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11368    list ARGS along with N new arguments specified as the "..."
11369    parameters.  SKIP is the number of arguments in ARGS to be omitted.
11370    OLDNARGS is the number of elements in ARGS.  */
11371
11372 static tree
11373 rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
11374                          int skip, tree fndecl, int n, ...)
11375 {
11376   va_list ap;
11377   tree t;
11378
11379   va_start (ap, n);
11380   t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
11381   va_end (ap);
11382
11383   return t;
11384 }
11385
11386 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
11387    along with N new arguments specified as the "..." parameters.  SKIP
11388    is the number of arguments in EXP to be omitted.  This function is used
11389    to do varargs-to-varargs transformations.  */
11390
11391 static tree
11392 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
11393 {
11394   va_list ap;
11395   tree t;
11396
11397   va_start (ap, n);
11398   t = rewrite_call_expr_valist (loc, call_expr_nargs (exp),
11399                                 CALL_EXPR_ARGP (exp), skip, fndecl, n, ap);
11400   va_end (ap);
11401
11402   return t;
11403 }
11404
11405 /* Validate a single argument ARG against a tree code CODE representing
11406    a type.  */
11407
11408 static bool
11409 validate_arg (const_tree arg, enum tree_code code)
11410 {
11411   if (!arg)
11412     return false;
11413   else if (code == POINTER_TYPE)
11414     return POINTER_TYPE_P (TREE_TYPE (arg));
11415   else if (code == INTEGER_TYPE)
11416     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11417   return code == TREE_CODE (TREE_TYPE (arg));
11418 }
11419
11420 /* This function validates the types of a function call argument list
11421    against a specified list of tree_codes.  If the last specifier is a 0,
11422    that represents an ellipses, otherwise the last specifier must be a
11423    VOID_TYPE.
11424
11425    This is the GIMPLE version of validate_arglist.  Eventually we want to
11426    completely convert builtins.c to work from GIMPLEs and the tree based
11427    validate_arglist will then be removed.  */
11428
11429 bool
11430 validate_gimple_arglist (const_gimple call, ...)
11431 {
11432   enum tree_code code;
11433   bool res = 0;
11434   va_list ap;
11435   const_tree arg;
11436   size_t i;
11437
11438   va_start (ap, call);
11439   i = 0;
11440
11441   do
11442     {
11443       code = (enum tree_code) va_arg (ap, int);
11444       switch (code)
11445         {
11446         case 0:
11447           /* This signifies an ellipses, any further arguments are all ok.  */
11448           res = true;
11449           goto end;
11450         case VOID_TYPE:
11451           /* This signifies an endlink, if no arguments remain, return
11452              true, otherwise return false.  */
11453           res = (i == gimple_call_num_args (call));
11454           goto end;
11455         default:
11456           /* If no parameters remain or the parameter's code does not
11457              match the specified code, return false.  Otherwise continue
11458              checking any remaining arguments.  */
11459           arg = gimple_call_arg (call, i++);
11460           if (!validate_arg (arg, code))
11461             goto end;
11462           break;
11463         }
11464     }
11465   while (1);
11466
11467   /* We need gotos here since we can only have one VA_CLOSE in a
11468      function.  */
11469  end: ;
11470   va_end (ap);
11471
11472   return res;
11473 }
11474
11475 /* This function validates the types of a function call argument list
11476    against a specified list of tree_codes.  If the last specifier is a 0,
11477    that represents an ellipses, otherwise the last specifier must be a
11478    VOID_TYPE.  */
11479
11480 bool
11481 validate_arglist (const_tree callexpr, ...)
11482 {
11483   enum tree_code code;
11484   bool res = 0;
11485   va_list ap;
11486   const_call_expr_arg_iterator iter;
11487   const_tree arg;
11488
11489   va_start (ap, callexpr);
11490   init_const_call_expr_arg_iterator (callexpr, &iter);
11491
11492   do
11493     {
11494       code = (enum tree_code) va_arg (ap, int);
11495       switch (code)
11496         {
11497         case 0:
11498           /* This signifies an ellipses, any further arguments are all ok.  */
11499           res = true;
11500           goto end;
11501         case VOID_TYPE:
11502           /* This signifies an endlink, if no arguments remain, return
11503              true, otherwise return false.  */
11504           res = !more_const_call_expr_args_p (&iter);
11505           goto end;
11506         default:
11507           /* If no parameters remain or the parameter's code does not
11508              match the specified code, return false.  Otherwise continue
11509              checking any remaining arguments.  */
11510           arg = next_const_call_expr_arg (&iter);
11511           if (!validate_arg (arg, code))
11512             goto end;
11513           break;
11514         }
11515     }
11516   while (1);
11517
11518   /* We need gotos here since we can only have one VA_CLOSE in a
11519      function.  */
11520  end: ;
11521   va_end (ap);
11522
11523   return res;
11524 }
11525
11526 /* Default target-specific builtin expander that does nothing.  */
11527
11528 rtx
11529 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11530                         rtx target ATTRIBUTE_UNUSED,
11531                         rtx subtarget ATTRIBUTE_UNUSED,
11532                         enum machine_mode mode ATTRIBUTE_UNUSED,
11533                         int ignore ATTRIBUTE_UNUSED)
11534 {
11535   return NULL_RTX;
11536 }
11537
11538 /* Returns true is EXP represents data that would potentially reside
11539    in a readonly section.  */
11540
11541 static bool
11542 readonly_data_expr (tree exp)
11543 {
11544   STRIP_NOPS (exp);
11545
11546   if (TREE_CODE (exp) != ADDR_EXPR)
11547     return false;
11548
11549   exp = get_base_address (TREE_OPERAND (exp, 0));
11550   if (!exp)
11551     return false;
11552
11553   /* Make sure we call decl_readonly_section only for trees it
11554      can handle (since it returns true for everything it doesn't
11555      understand).  */
11556   if (TREE_CODE (exp) == STRING_CST
11557       || TREE_CODE (exp) == CONSTRUCTOR
11558       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11559     return decl_readonly_section (exp, 0);
11560   else
11561     return false;
11562 }
11563
11564 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11565    to the call, and TYPE is its return type.
11566
11567    Return NULL_TREE if no simplification was possible, otherwise return the
11568    simplified form of the call as a tree.
11569
11570    The simplified form may be a constant or other expression which
11571    computes the same value, but in a more efficient manner (including
11572    calls to other builtin functions).
11573
11574    The call may contain arguments which need to be evaluated, but
11575    which are not useful to determine the result of the call.  In
11576    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11577    COMPOUND_EXPR will be an argument which must be evaluated.
11578    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11579    COMPOUND_EXPR in the chain will contain the tree for the simplified
11580    form of the builtin function call.  */
11581
11582 static tree
11583 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11584 {
11585   if (!validate_arg (s1, POINTER_TYPE)
11586       || !validate_arg (s2, POINTER_TYPE))
11587     return NULL_TREE;
11588   else
11589     {
11590       tree fn;
11591       const char *p1, *p2;
11592
11593       p2 = c_getstr (s2);
11594       if (p2 == NULL)
11595         return NULL_TREE;
11596
11597       p1 = c_getstr (s1);
11598       if (p1 != NULL)
11599         {
11600           const char *r = strstr (p1, p2);
11601           tree tem;
11602
11603           if (r == NULL)
11604             return build_int_cst (TREE_TYPE (s1), 0);
11605
11606           /* Return an offset into the constant string argument.  */
11607           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11608           return fold_convert_loc (loc, type, tem);
11609         }
11610
11611       /* The argument is const char *, and the result is char *, so we need
11612          a type conversion here to avoid a warning.  */
11613       if (p2[0] == '\0')
11614         return fold_convert_loc (loc, type, s1);
11615
11616       if (p2[1] != '\0')
11617         return NULL_TREE;
11618
11619       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11620       if (!fn)
11621         return NULL_TREE;
11622
11623       /* New argument list transforming strstr(s1, s2) to
11624          strchr(s1, s2[0]).  */
11625       return build_call_expr_loc (loc, fn, 2, s1,
11626                                   build_int_cst (integer_type_node, p2[0]));
11627     }
11628 }
11629
11630 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11631    the call, and TYPE is its return type.
11632
11633    Return NULL_TREE if no simplification was possible, otherwise return the
11634    simplified form of the call as a tree.
11635
11636    The simplified form may be a constant or other expression which
11637    computes the same value, but in a more efficient manner (including
11638    calls to other builtin functions).
11639
11640    The call may contain arguments which need to be evaluated, but
11641    which are not useful to determine the result of the call.  In
11642    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11643    COMPOUND_EXPR will be an argument which must be evaluated.
11644    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11645    COMPOUND_EXPR in the chain will contain the tree for the simplified
11646    form of the builtin function call.  */
11647
11648 static tree
11649 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11650 {
11651   if (!validate_arg (s1, POINTER_TYPE)
11652       || !validate_arg (s2, INTEGER_TYPE))
11653     return NULL_TREE;
11654   else
11655     {
11656       const char *p1;
11657
11658       if (TREE_CODE (s2) != INTEGER_CST)
11659         return NULL_TREE;
11660
11661       p1 = c_getstr (s1);
11662       if (p1 != NULL)
11663         {
11664           char c;
11665           const char *r;
11666           tree tem;
11667
11668           if (target_char_cast (s2, &c))
11669             return NULL_TREE;
11670
11671           r = strchr (p1, c);
11672
11673           if (r == NULL)
11674             return build_int_cst (TREE_TYPE (s1), 0);
11675
11676           /* Return an offset into the constant string argument.  */
11677           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11678           return fold_convert_loc (loc, type, tem);
11679         }
11680       return NULL_TREE;
11681     }
11682 }
11683
11684 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11685    the call, and TYPE is its return type.
11686
11687    Return NULL_TREE if no simplification was possible, otherwise return the
11688    simplified form of the call as a tree.
11689
11690    The simplified form may be a constant or other expression which
11691    computes the same value, but in a more efficient manner (including
11692    calls to other builtin functions).
11693
11694    The call may contain arguments which need to be evaluated, but
11695    which are not useful to determine the result of the call.  In
11696    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11697    COMPOUND_EXPR will be an argument which must be evaluated.
11698    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11699    COMPOUND_EXPR in the chain will contain the tree for the simplified
11700    form of the builtin function call.  */
11701
11702 static tree
11703 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11704 {
11705   if (!validate_arg (s1, POINTER_TYPE)
11706       || !validate_arg (s2, INTEGER_TYPE))
11707     return NULL_TREE;
11708   else
11709     {
11710       tree fn;
11711       const char *p1;
11712
11713       if (TREE_CODE (s2) != INTEGER_CST)
11714         return NULL_TREE;
11715
11716       p1 = c_getstr (s1);
11717       if (p1 != NULL)
11718         {
11719           char c;
11720           const char *r;
11721           tree tem;
11722
11723           if (target_char_cast (s2, &c))
11724             return NULL_TREE;
11725
11726           r = strrchr (p1, c);
11727
11728           if (r == NULL)
11729             return build_int_cst (TREE_TYPE (s1), 0);
11730
11731           /* Return an offset into the constant string argument.  */
11732           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11733           return fold_convert_loc (loc, type, tem);
11734         }
11735
11736       if (! integer_zerop (s2))
11737         return NULL_TREE;
11738
11739       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11740       if (!fn)
11741         return NULL_TREE;
11742
11743       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11744       return build_call_expr_loc (loc, fn, 2, s1, s2);
11745     }
11746 }
11747
11748 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11749    to the call, and TYPE is its return type.
11750
11751    Return NULL_TREE if no simplification was possible, otherwise return the
11752    simplified form of the call as a tree.
11753
11754    The simplified form may be a constant or other expression which
11755    computes the same value, but in a more efficient manner (including
11756    calls to other builtin functions).
11757
11758    The call may contain arguments which need to be evaluated, but
11759    which are not useful to determine the result of the call.  In
11760    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11761    COMPOUND_EXPR will be an argument which must be evaluated.
11762    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11763    COMPOUND_EXPR in the chain will contain the tree for the simplified
11764    form of the builtin function call.  */
11765
11766 static tree
11767 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11768 {
11769   if (!validate_arg (s1, POINTER_TYPE)
11770       || !validate_arg (s2, POINTER_TYPE))
11771     return NULL_TREE;
11772   else
11773     {
11774       tree fn;
11775       const char *p1, *p2;
11776
11777       p2 = c_getstr (s2);
11778       if (p2 == NULL)
11779         return NULL_TREE;
11780
11781       p1 = c_getstr (s1);
11782       if (p1 != NULL)
11783         {
11784           const char *r = strpbrk (p1, p2);
11785           tree tem;
11786
11787           if (r == NULL)
11788             return build_int_cst (TREE_TYPE (s1), 0);
11789
11790           /* Return an offset into the constant string argument.  */
11791           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11792           return fold_convert_loc (loc, type, tem);
11793         }
11794
11795       if (p2[0] == '\0')
11796         /* strpbrk(x, "") == NULL.
11797            Evaluate and ignore s1 in case it had side-effects.  */
11798         return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11799
11800       if (p2[1] != '\0')
11801         return NULL_TREE;  /* Really call strpbrk.  */
11802
11803       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11804       if (!fn)
11805         return NULL_TREE;
11806
11807       /* New argument list transforming strpbrk(s1, s2) to
11808          strchr(s1, s2[0]).  */
11809       return build_call_expr_loc (loc, fn, 2, s1,
11810                                   build_int_cst (integer_type_node, p2[0]));
11811     }
11812 }
11813
11814 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11815    to the call.
11816
11817    Return NULL_TREE if no simplification was possible, otherwise return the
11818    simplified form of the call as a tree.
11819
11820    The simplified form may be a constant or other expression which
11821    computes the same value, but in a more efficient manner (including
11822    calls to other builtin functions).
11823
11824    The call may contain arguments which need to be evaluated, but
11825    which are not useful to determine the result of the call.  In
11826    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11827    COMPOUND_EXPR will be an argument which must be evaluated.
11828    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11829    COMPOUND_EXPR in the chain will contain the tree for the simplified
11830    form of the builtin function call.  */
11831
11832 static tree
11833 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11834 {
11835   if (!validate_arg (dst, POINTER_TYPE)
11836       || !validate_arg (src, POINTER_TYPE))
11837     return NULL_TREE;
11838   else
11839     {
11840       const char *p = c_getstr (src);
11841
11842       /* If the string length is zero, return the dst parameter.  */
11843       if (p && *p == '\0')
11844         return dst;
11845
11846       if (optimize_insn_for_speed_p ())
11847         {
11848           /* See if we can store by pieces into (dst + strlen(dst)).  */
11849           tree newdst, call;
11850           tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11851           tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
11852
11853           if (!strlen_fn || !strcpy_fn)
11854             return NULL_TREE;
11855
11856           /* If we don't have a movstr we don't want to emit an strcpy
11857              call.  We have to do that if the length of the source string
11858              isn't computable (in that case we can use memcpy probably
11859              later expanding to a sequence of mov instructions).  If we
11860              have movstr instructions we can emit strcpy calls.  */
11861           if (!HAVE_movstr)
11862             {
11863               tree len = c_strlen (src, 1);
11864               if (! len || TREE_SIDE_EFFECTS (len))
11865                 return NULL_TREE;
11866             }
11867
11868           /* Stabilize the argument list.  */
11869           dst = builtin_save_expr (dst);
11870
11871           /* Create strlen (dst).  */
11872           newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11873           /* Create (dst p+ strlen (dst)).  */
11874
11875           newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
11876           newdst = builtin_save_expr (newdst);
11877
11878           call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11879           return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11880         }
11881       return NULL_TREE;
11882     }
11883 }
11884
11885 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11886    arguments to the call.
11887
11888    Return NULL_TREE if no simplification was possible, otherwise return the
11889    simplified form of the call as a tree.
11890
11891    The simplified form may be a constant or other expression which
11892    computes the same value, but in a more efficient manner (including
11893    calls to other builtin functions).
11894
11895    The call may contain arguments which need to be evaluated, but
11896    which are not useful to determine the result of the call.  In
11897    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11898    COMPOUND_EXPR will be an argument which must be evaluated.
11899    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11900    COMPOUND_EXPR in the chain will contain the tree for the simplified
11901    form of the builtin function call.  */
11902
11903 static tree
11904 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11905 {
11906   if (!validate_arg (dst, POINTER_TYPE)
11907       || !validate_arg (src, POINTER_TYPE)
11908       || !validate_arg (len, INTEGER_TYPE))
11909     return NULL_TREE;
11910   else
11911     {
11912       const char *p = c_getstr (src);
11913
11914       /* If the requested length is zero, or the src parameter string
11915          length is zero, return the dst parameter.  */
11916       if (integer_zerop (len) || (p && *p == '\0'))
11917         return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11918
11919       /* If the requested len is greater than or equal to the string
11920          length, call strcat.  */
11921       if (TREE_CODE (len) == INTEGER_CST && p
11922           && compare_tree_int (len, strlen (p)) >= 0)
11923         {
11924           tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
11925
11926           /* If the replacement _DECL isn't initialized, don't do the
11927              transformation.  */
11928           if (!fn)
11929             return NULL_TREE;
11930
11931           return build_call_expr_loc (loc, fn, 2, dst, src);
11932         }
11933       return NULL_TREE;
11934     }
11935 }
11936
11937 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11938    to the call.
11939
11940    Return NULL_TREE if no simplification was possible, otherwise return the
11941    simplified form of the call as a tree.
11942
11943    The simplified form may be a constant or other expression which
11944    computes the same value, but in a more efficient manner (including
11945    calls to other builtin functions).
11946
11947    The call may contain arguments which need to be evaluated, but
11948    which are not useful to determine the result of the call.  In
11949    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11950    COMPOUND_EXPR will be an argument which must be evaluated.
11951    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11952    COMPOUND_EXPR in the chain will contain the tree for the simplified
11953    form of the builtin function call.  */
11954
11955 static tree
11956 fold_builtin_strspn (location_t loc, tree s1, tree s2)
11957 {
11958   if (!validate_arg (s1, POINTER_TYPE)
11959       || !validate_arg (s2, POINTER_TYPE))
11960     return NULL_TREE;
11961   else
11962     {
11963       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11964
11965       /* If both arguments are constants, evaluate at compile-time.  */
11966       if (p1 && p2)
11967         {
11968           const size_t r = strspn (p1, p2);
11969           return build_int_cst (size_type_node, r);
11970         }
11971
11972       /* If either argument is "", return NULL_TREE.  */
11973       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11974         /* Evaluate and ignore both arguments in case either one has
11975            side-effects.  */
11976         return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11977                                   s1, s2);
11978       return NULL_TREE;
11979     }
11980 }
11981
11982 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11983    to the call.
11984
11985    Return NULL_TREE if no simplification was possible, otherwise return the
11986    simplified form of the call as a tree.
11987
11988    The simplified form may be a constant or other expression which
11989    computes the same value, but in a more efficient manner (including
11990    calls to other builtin functions).
11991
11992    The call may contain arguments which need to be evaluated, but
11993    which are not useful to determine the result of the call.  In
11994    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11995    COMPOUND_EXPR will be an argument which must be evaluated.
11996    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11997    COMPOUND_EXPR in the chain will contain the tree for the simplified
11998    form of the builtin function call.  */
11999
12000 static tree
12001 fold_builtin_strcspn (location_t loc, tree s1, tree s2)
12002 {
12003   if (!validate_arg (s1, POINTER_TYPE)
12004       || !validate_arg (s2, POINTER_TYPE))
12005     return NULL_TREE;
12006   else
12007     {
12008       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
12009
12010       /* If both arguments are constants, evaluate at compile-time.  */
12011       if (p1 && p2)
12012         {
12013           const size_t r = strcspn (p1, p2);
12014           return build_int_cst (size_type_node, r);
12015         }
12016
12017       /* If the first argument is "", return NULL_TREE.  */
12018       if (p1 && *p1 == '\0')
12019         {
12020           /* Evaluate and ignore argument s2 in case it has
12021              side-effects.  */
12022           return omit_one_operand_loc (loc, size_type_node,
12023                                    size_zero_node, s2);
12024         }
12025
12026       /* If the second argument is "", return __builtin_strlen(s1).  */
12027       if (p2 && *p2 == '\0')
12028         {
12029           tree fn = builtin_decl_implicit (BUILT_IN_STRLEN);
12030
12031           /* If the replacement _DECL isn't initialized, don't do the
12032              transformation.  */
12033           if (!fn)
12034             return NULL_TREE;
12035
12036           return build_call_expr_loc (loc, fn, 1, s1);
12037         }
12038       return NULL_TREE;
12039     }
12040 }
12041
12042 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
12043    to the call.  IGNORE is true if the value returned
12044    by the builtin will be ignored.  UNLOCKED is true is true if this
12045    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
12046    the known length of the string.  Return NULL_TREE if no simplification
12047    was possible.  */
12048
12049 tree
12050 fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
12051                     bool ignore, bool unlocked, tree len)
12052 {
12053   /* If we're using an unlocked function, assume the other unlocked
12054      functions exist explicitly.  */
12055   tree const fn_fputc = (unlocked
12056                          ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
12057                          : builtin_decl_implicit (BUILT_IN_FPUTC));
12058   tree const fn_fwrite = (unlocked
12059                           ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
12060                           : builtin_decl_implicit (BUILT_IN_FWRITE));
12061
12062   /* If the return value is used, don't do the transformation.  */
12063   if (!ignore)
12064     return NULL_TREE;
12065
12066   /* Verify the arguments in the original call.  */
12067   if (!validate_arg (arg0, POINTER_TYPE)
12068       || !validate_arg (arg1, POINTER_TYPE))
12069     return NULL_TREE;
12070
12071   if (! len)
12072     len = c_strlen (arg0, 0);
12073
12074   /* Get the length of the string passed to fputs.  If the length
12075      can't be determined, punt.  */
12076   if (!len
12077       || TREE_CODE (len) != INTEGER_CST)
12078     return NULL_TREE;
12079
12080   switch (compare_tree_int (len, 1))
12081     {
12082     case -1: /* length is 0, delete the call entirely .  */
12083       return omit_one_operand_loc (loc, integer_type_node,
12084                                integer_zero_node, arg1);;
12085
12086     case 0: /* length is 1, call fputc.  */
12087       {
12088         const char *p = c_getstr (arg0);
12089
12090         if (p != NULL)
12091           {
12092             if (fn_fputc)
12093               return build_call_expr_loc (loc, fn_fputc, 2,
12094                                           build_int_cst
12095                                             (integer_type_node, p[0]), arg1);
12096             else
12097               return NULL_TREE;
12098           }
12099       }
12100       /* FALLTHROUGH */
12101     case 1: /* length is greater than 1, call fwrite.  */
12102       {
12103         /* If optimizing for size keep fputs.  */
12104         if (optimize_function_for_size_p (cfun))
12105           return NULL_TREE;
12106         /* New argument list transforming fputs(string, stream) to
12107            fwrite(string, 1, len, stream).  */
12108         if (fn_fwrite)
12109           return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12110                                   size_one_node, len, arg1);
12111         else
12112           return NULL_TREE;
12113       }
12114     default:
12115       gcc_unreachable ();
12116     }
12117   return NULL_TREE;
12118 }
12119
12120 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
12121    produced.  False otherwise.  This is done so that we don't output the error
12122    or warning twice or three times.  */
12123
12124 bool
12125 fold_builtin_next_arg (tree exp, bool va_start_p)
12126 {
12127   tree fntype = TREE_TYPE (current_function_decl);
12128   int nargs = call_expr_nargs (exp);
12129   tree arg;
12130   /* There is good chance the current input_location points inside the
12131      definition of the va_start macro (perhaps on the token for
12132      builtin) in a system header, so warnings will not be emitted.
12133      Use the location in real source code.  */
12134   source_location current_location =
12135     linemap_unwind_to_first_non_reserved_loc (line_table, input_location,
12136                                               NULL);
12137
12138   if (!stdarg_p (fntype))
12139     {
12140       error ("%<va_start%> used in function with fixed args");
12141       return true;
12142     }
12143
12144   if (va_start_p)
12145     {
12146       if (va_start_p && (nargs != 2))
12147         {
12148           error ("wrong number of arguments to function %<va_start%>");
12149           return true;
12150         }
12151       arg = CALL_EXPR_ARG (exp, 1);
12152     }
12153   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12154      when we checked the arguments and if needed issued a warning.  */
12155   else
12156     {
12157       if (nargs == 0)
12158         {
12159           /* Evidently an out of date version of <stdarg.h>; can't validate
12160              va_start's second argument, but can still work as intended.  */
12161           warning_at (current_location,
12162                       OPT_Wvarargs,
12163                    "%<__builtin_next_arg%> called without an argument");
12164           return true;
12165         }
12166       else if (nargs > 1)
12167         {
12168           error ("wrong number of arguments to function %<__builtin_next_arg%>");
12169           return true;
12170         }
12171       arg = CALL_EXPR_ARG (exp, 0);
12172     }
12173
12174   if (TREE_CODE (arg) == SSA_NAME)
12175     arg = SSA_NAME_VAR (arg);
12176
12177   /* We destructively modify the call to be __builtin_va_start (ap, 0)
12178      or __builtin_next_arg (0) the first time we see it, after checking
12179      the arguments and if needed issuing a warning.  */
12180   if (!integer_zerop (arg))
12181     {
12182       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
12183
12184       /* Strip off all nops for the sake of the comparison.  This
12185          is not quite the same as STRIP_NOPS.  It does more.
12186          We must also strip off INDIRECT_EXPR for C++ reference
12187          parameters.  */
12188       while (CONVERT_EXPR_P (arg)
12189              || TREE_CODE (arg) == INDIRECT_REF)
12190         arg = TREE_OPERAND (arg, 0);
12191       if (arg != last_parm)
12192         {
12193           /* FIXME: Sometimes with the tree optimizers we can get the
12194              not the last argument even though the user used the last
12195              argument.  We just warn and set the arg to be the last
12196              argument so that we will get wrong-code because of
12197              it.  */
12198           warning_at (current_location,
12199                       OPT_Wvarargs,
12200                       "second parameter of %<va_start%> not last named argument");
12201         }
12202
12203       /* Undefined by C99 7.15.1.4p4 (va_start):
12204          "If the parameter parmN is declared with the register storage
12205          class, with a function or array type, or with a type that is
12206          not compatible with the type that results after application of
12207          the default argument promotions, the behavior is undefined."
12208       */
12209       else if (DECL_REGISTER (arg))
12210         {
12211           warning_at (current_location,
12212                       OPT_Wvarargs,
12213                       "undefined behaviour when second parameter of "
12214                       "%<va_start%> is declared with %<register%> storage");
12215         }
12216
12217       /* We want to verify the second parameter just once before the tree
12218          optimizers are run and then avoid keeping it in the tree,
12219          as otherwise we could warn even for correct code like:
12220          void foo (int i, ...)
12221          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
12222       if (va_start_p)
12223         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12224       else
12225         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
12226     }
12227   return false;
12228 }
12229
12230
12231 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12232    ORIG may be null if this is a 2-argument call.  We don't attempt to
12233    simplify calls with more than 3 arguments.
12234
12235    Return NULL_TREE if no simplification was possible, otherwise return the
12236    simplified form of the call as a tree.  If IGNORED is true, it means that
12237    the caller does not use the returned value of the function.  */
12238
12239 static tree
12240 fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12241                       tree orig, int ignored)
12242 {
12243   tree call, retval;
12244   const char *fmt_str = NULL;
12245
12246   /* Verify the required arguments in the original call.  We deal with two
12247      types of sprintf() calls: 'sprintf (str, fmt)' and
12248      'sprintf (dest, "%s", orig)'.  */
12249   if (!validate_arg (dest, POINTER_TYPE)
12250       || !validate_arg (fmt, POINTER_TYPE))
12251     return NULL_TREE;
12252   if (orig && !validate_arg (orig, POINTER_TYPE))
12253     return NULL_TREE;
12254
12255   /* Check whether the format is a literal string constant.  */
12256   fmt_str = c_getstr (fmt);
12257   if (fmt_str == NULL)
12258     return NULL_TREE;
12259
12260   call = NULL_TREE;
12261   retval = NULL_TREE;
12262
12263   if (!init_target_chars ())
12264     return NULL_TREE;
12265
12266   /* If the format doesn't contain % args or %%, use strcpy.  */
12267   if (strchr (fmt_str, target_percent) == NULL)
12268     {
12269       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12270
12271       if (!fn)
12272         return NULL_TREE;
12273
12274       /* Don't optimize sprintf (buf, "abc", ptr++).  */
12275       if (orig)
12276         return NULL_TREE;
12277
12278       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12279          'format' is known to contain no % formats.  */
12280       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12281       if (!ignored)
12282         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12283     }
12284
12285   /* If the format is "%s", use strcpy if the result isn't used.  */
12286   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12287     {
12288       tree fn;
12289       fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12290
12291       if (!fn)
12292         return NULL_TREE;
12293
12294       /* Don't crash on sprintf (str1, "%s").  */
12295       if (!orig)
12296         return NULL_TREE;
12297
12298       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
12299       if (!ignored)
12300         {
12301           retval = c_strlen (orig, 1);
12302           if (!retval || TREE_CODE (retval) != INTEGER_CST)
12303             return NULL_TREE;
12304         }
12305       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12306     }
12307
12308   if (call && retval)
12309     {
12310       retval = fold_convert_loc
12311         (loc, TREE_TYPE (TREE_TYPE (builtin_decl_implicit (BUILT_IN_SPRINTF))),
12312          retval);
12313       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12314     }
12315   else
12316     return call;
12317 }
12318
12319 /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
12320    FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
12321    attempt to simplify calls with more than 4 arguments.
12322
12323    Return NULL_TREE if no simplification was possible, otherwise return the
12324    simplified form of the call as a tree.  If IGNORED is true, it means that
12325    the caller does not use the returned value of the function.  */
12326
12327 static tree
12328 fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
12329                        tree orig, int ignored)
12330 {
12331   tree call, retval;
12332   const char *fmt_str = NULL;
12333   unsigned HOST_WIDE_INT destlen;
12334
12335   /* Verify the required arguments in the original call.  We deal with two
12336      types of snprintf() calls: 'snprintf (str, cst, fmt)' and
12337      'snprintf (dest, cst, "%s", orig)'.  */
12338   if (!validate_arg (dest, POINTER_TYPE)
12339       || !validate_arg (destsize, INTEGER_TYPE)
12340       || !validate_arg (fmt, POINTER_TYPE))
12341     return NULL_TREE;
12342   if (orig && !validate_arg (orig, POINTER_TYPE))
12343     return NULL_TREE;
12344
12345   if (!host_integerp (destsize, 1))
12346     return NULL_TREE;
12347
12348   /* Check whether the format is a literal string constant.  */
12349   fmt_str = c_getstr (fmt);
12350   if (fmt_str == NULL)
12351     return NULL_TREE;
12352
12353   call = NULL_TREE;
12354   retval = NULL_TREE;
12355
12356   if (!init_target_chars ())
12357     return NULL_TREE;
12358
12359   destlen = tree_low_cst (destsize, 1);
12360
12361   /* If the format doesn't contain % args or %%, use strcpy.  */
12362   if (strchr (fmt_str, target_percent) == NULL)
12363     {
12364       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12365       size_t len = strlen (fmt_str);
12366
12367       /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
12368       if (orig)
12369         return NULL_TREE;
12370
12371       /* We could expand this as
12372          memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
12373          or to
12374          memcpy (str, fmt_with_nul_at_cstm1, cst);
12375          but in the former case that might increase code size
12376          and in the latter case grow .rodata section too much.
12377          So punt for now.  */
12378       if (len >= destlen)
12379         return NULL_TREE;
12380
12381       if (!fn)
12382         return NULL_TREE;
12383
12384       /* Convert snprintf (str, cst, fmt) into strcpy (str, fmt) when
12385          'format' is known to contain no % formats and
12386          strlen (fmt) < cst.  */
12387       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12388
12389       if (!ignored)
12390         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12391     }
12392
12393   /* If the format is "%s", use strcpy if the result isn't used.  */
12394   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12395     {
12396       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12397       unsigned HOST_WIDE_INT origlen;
12398
12399       /* Don't crash on snprintf (str1, cst, "%s").  */
12400       if (!orig)
12401         return NULL_TREE;
12402
12403       retval = c_strlen (orig, 1);
12404       if (!retval || !host_integerp (retval, 1))  
12405         return NULL_TREE;
12406
12407       origlen = tree_low_cst (retval, 1);
12408       /* We could expand this as
12409          memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
12410          or to
12411          memcpy (str1, str2_with_nul_at_cstm1, cst);
12412          but in the former case that might increase code size
12413          and in the latter case grow .rodata section too much.
12414          So punt for now.  */
12415       if (origlen >= destlen)
12416         return NULL_TREE;
12417
12418       /* Convert snprintf (str1, cst, "%s", str2) into
12419          strcpy (str1, str2) if strlen (str2) < cst.  */
12420       if (!fn)
12421         return NULL_TREE;
12422
12423       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12424
12425       if (ignored)
12426         retval = NULL_TREE;
12427     }
12428
12429   if (call && retval)
12430     {
12431       tree fn = builtin_decl_explicit (BUILT_IN_SNPRINTF);
12432       retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
12433       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12434     }
12435   else
12436     return call;
12437 }
12438
12439 /* Expand a call EXP to __builtin_object_size.  */
12440
12441 rtx
12442 expand_builtin_object_size (tree exp)
12443 {
12444   tree ost;
12445   int object_size_type;
12446   tree fndecl = get_callee_fndecl (exp);
12447
12448   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
12449     {
12450       error ("%Kfirst argument of %D must be a pointer, second integer constant",
12451              exp, fndecl);
12452       expand_builtin_trap ();
12453       return const0_rtx;
12454     }
12455
12456   ost = CALL_EXPR_ARG (exp, 1);
12457   STRIP_NOPS (ost);
12458
12459   if (TREE_CODE (ost) != INTEGER_CST
12460       || tree_int_cst_sgn (ost) < 0
12461       || compare_tree_int (ost, 3) > 0)
12462     {
12463       error ("%Klast argument of %D is not integer constant between 0 and 3",
12464              exp, fndecl);
12465       expand_builtin_trap ();
12466       return const0_rtx;
12467     }
12468
12469   object_size_type = tree_low_cst (ost, 0);
12470
12471   return object_size_type < 2 ? constm1_rtx : const0_rtx;
12472 }
12473
12474 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12475    FCODE is the BUILT_IN_* to use.
12476    Return NULL_RTX if we failed; the caller should emit a normal call,
12477    otherwise try to get the result in TARGET, if convenient (and in
12478    mode MODE if that's convenient).  */
12479
12480 static rtx
12481 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12482                            enum built_in_function fcode)
12483 {
12484   tree dest, src, len, size;
12485
12486   if (!validate_arglist (exp,
12487                          POINTER_TYPE,
12488                          fcode == BUILT_IN_MEMSET_CHK
12489                          ? INTEGER_TYPE : POINTER_TYPE,
12490                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
12491     return NULL_RTX;
12492
12493   dest = CALL_EXPR_ARG (exp, 0);
12494   src = CALL_EXPR_ARG (exp, 1);
12495   len = CALL_EXPR_ARG (exp, 2);
12496   size = CALL_EXPR_ARG (exp, 3);
12497
12498   if (! host_integerp (size, 1))
12499     return NULL_RTX;
12500
12501   if (host_integerp (len, 1) || integer_all_onesp (size))
12502     {
12503       tree fn;
12504
12505       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12506         {
12507           warning_at (tree_nonartificial_location (exp),
12508                       0, "%Kcall to %D will always overflow destination buffer",
12509                       exp, get_callee_fndecl (exp));
12510           return NULL_RTX;
12511         }
12512
12513       fn = NULL_TREE;
12514       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12515          mem{cpy,pcpy,move,set} is available.  */
12516       switch (fcode)
12517         {
12518         case BUILT_IN_MEMCPY_CHK:
12519           fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12520           break;
12521         case BUILT_IN_MEMPCPY_CHK:
12522           fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12523           break;
12524         case BUILT_IN_MEMMOVE_CHK:
12525           fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12526           break;
12527         case BUILT_IN_MEMSET_CHK:
12528           fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12529           break;
12530         default:
12531           break;
12532         }
12533
12534       if (! fn)
12535         return NULL_RTX;
12536
12537       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len);
12538       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12539       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12540       return expand_expr (fn, target, mode, EXPAND_NORMAL);
12541     }
12542   else if (fcode == BUILT_IN_MEMSET_CHK)
12543     return NULL_RTX;
12544   else
12545     {
12546       unsigned int dest_align = get_pointer_alignment (dest);
12547
12548       /* If DEST is not a pointer type, call the normal function.  */
12549       if (dest_align == 0)
12550         return NULL_RTX;
12551
12552       /* If SRC and DEST are the same (and not volatile), do nothing.  */
12553       if (operand_equal_p (src, dest, 0))
12554         {
12555           tree expr;
12556
12557           if (fcode != BUILT_IN_MEMPCPY_CHK)
12558             {
12559               /* Evaluate and ignore LEN in case it has side-effects.  */
12560               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12561               return expand_expr (dest, target, mode, EXPAND_NORMAL);
12562             }
12563
12564           expr = fold_build_pointer_plus (dest, len);
12565           return expand_expr (expr, target, mode, EXPAND_NORMAL);
12566         }
12567
12568       /* __memmove_chk special case.  */
12569       if (fcode == BUILT_IN_MEMMOVE_CHK)
12570         {
12571           unsigned int src_align = get_pointer_alignment (src);
12572
12573           if (src_align == 0)
12574             return NULL_RTX;
12575
12576           /* If src is categorized for a readonly section we can use
12577              normal __memcpy_chk.  */
12578           if (readonly_data_expr (src))
12579             {
12580               tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12581               if (!fn)
12582                 return NULL_RTX;
12583               fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
12584                                           dest, src, len, size);
12585               gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12586               CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12587               return expand_expr (fn, target, mode, EXPAND_NORMAL);
12588             }
12589         }
12590       return NULL_RTX;
12591     }
12592 }
12593
12594 /* Emit warning if a buffer overflow is detected at compile time.  */
12595
12596 static void
12597 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12598 {
12599   int is_strlen = 0;
12600   tree len, size;
12601   location_t loc = tree_nonartificial_location (exp);
12602
12603   switch (fcode)
12604     {
12605     case BUILT_IN_STRCPY_CHK:
12606     case BUILT_IN_STPCPY_CHK:
12607     /* For __strcat_chk the warning will be emitted only if overflowing
12608        by at least strlen (dest) + 1 bytes.  */
12609     case BUILT_IN_STRCAT_CHK:
12610       len = CALL_EXPR_ARG (exp, 1);
12611       size = CALL_EXPR_ARG (exp, 2);
12612       is_strlen = 1;
12613       break;
12614     case BUILT_IN_STRNCAT_CHK:
12615     case BUILT_IN_STRNCPY_CHK:
12616     case BUILT_IN_STPNCPY_CHK:
12617       len = CALL_EXPR_ARG (exp, 2);
12618       size = CALL_EXPR_ARG (exp, 3);
12619       break;
12620     case BUILT_IN_SNPRINTF_CHK:
12621     case BUILT_IN_VSNPRINTF_CHK:
12622       len = CALL_EXPR_ARG (exp, 1);
12623       size = CALL_EXPR_ARG (exp, 3);
12624       break;
12625     default:
12626       gcc_unreachable ();
12627     }
12628
12629   if (!len || !size)
12630     return;
12631
12632   if (! host_integerp (size, 1) || integer_all_onesp (size))
12633     return;
12634
12635   if (is_strlen)
12636     {
12637       len = c_strlen (len, 1);
12638       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12639         return;
12640     }
12641   else if (fcode == BUILT_IN_STRNCAT_CHK)
12642     {
12643       tree src = CALL_EXPR_ARG (exp, 1);
12644       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12645         return;
12646       src = c_strlen (src, 1);
12647       if (! src || ! host_integerp (src, 1))
12648         {
12649           warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12650                       exp, get_callee_fndecl (exp));
12651           return;
12652         }
12653       else if (tree_int_cst_lt (src, size))
12654         return;
12655     }
12656   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12657     return;
12658
12659   warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12660               exp, get_callee_fndecl (exp));
12661 }
12662
12663 /* Emit warning if a buffer overflow is detected at compile time
12664    in __sprintf_chk/__vsprintf_chk calls.  */
12665
12666 static void
12667 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12668 {
12669   tree size, len, fmt;
12670   const char *fmt_str;
12671   int nargs = call_expr_nargs (exp);
12672
12673   /* Verify the required arguments in the original call.  */
12674
12675   if (nargs < 4)
12676     return;
12677   size = CALL_EXPR_ARG (exp, 2);
12678   fmt = CALL_EXPR_ARG (exp, 3);
12679
12680   if (! host_integerp (size, 1) || integer_all_onesp (size))
12681     return;
12682
12683   /* Check whether the format is a literal string constant.  */
12684   fmt_str = c_getstr (fmt);
12685   if (fmt_str == NULL)
12686     return;
12687
12688   if (!init_target_chars ())
12689     return;
12690
12691   /* If the format doesn't contain % args or %%, we know its size.  */
12692   if (strchr (fmt_str, target_percent) == 0)
12693     len = build_int_cstu (size_type_node, strlen (fmt_str));
12694   /* If the format is "%s" and first ... argument is a string literal,
12695      we know it too.  */
12696   else if (fcode == BUILT_IN_SPRINTF_CHK
12697            && strcmp (fmt_str, target_percent_s) == 0)
12698     {
12699       tree arg;
12700
12701       if (nargs < 5)
12702         return;
12703       arg = CALL_EXPR_ARG (exp, 4);
12704       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12705         return;
12706
12707       len = c_strlen (arg, 1);
12708       if (!len || ! host_integerp (len, 1))
12709         return;
12710     }
12711   else
12712     return;
12713
12714   if (! tree_int_cst_lt (len, size))
12715     warning_at (tree_nonartificial_location (exp),
12716                 0, "%Kcall to %D will always overflow destination buffer",
12717                 exp, get_callee_fndecl (exp));
12718 }
12719
12720 /* Emit warning if a free is called with address of a variable.  */
12721
12722 static void
12723 maybe_emit_free_warning (tree exp)
12724 {
12725   tree arg = CALL_EXPR_ARG (exp, 0);
12726
12727   STRIP_NOPS (arg);
12728   if (TREE_CODE (arg) != ADDR_EXPR)
12729     return;
12730
12731   arg = get_base_address (TREE_OPERAND (arg, 0));
12732   if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF)
12733     return;
12734
12735   if (SSA_VAR_P (arg))
12736     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12737                 "%Kattempt to free a non-heap object %qD", exp, arg);
12738   else
12739     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12740                 "%Kattempt to free a non-heap object", exp);
12741 }
12742
12743 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12744    if possible.  */
12745
12746 tree
12747 fold_builtin_object_size (tree ptr, tree ost)
12748 {
12749   unsigned HOST_WIDE_INT bytes;
12750   int object_size_type;
12751
12752   if (!validate_arg (ptr, POINTER_TYPE)
12753       || !validate_arg (ost, INTEGER_TYPE))
12754     return NULL_TREE;
12755
12756   STRIP_NOPS (ost);
12757
12758   if (TREE_CODE (ost) != INTEGER_CST
12759       || tree_int_cst_sgn (ost) < 0
12760       || compare_tree_int (ost, 3) > 0)
12761     return NULL_TREE;
12762
12763   object_size_type = tree_low_cst (ost, 0);
12764
12765   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12766      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12767      and (size_t) 0 for types 2 and 3.  */
12768   if (TREE_SIDE_EFFECTS (ptr))
12769     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12770
12771   if (TREE_CODE (ptr) == ADDR_EXPR)
12772     {
12773       bytes = compute_builtin_object_size (ptr, object_size_type);
12774       if (double_int_fits_to_tree_p (size_type_node,
12775                                      double_int::from_uhwi (bytes)))
12776         return build_int_cstu (size_type_node, bytes);
12777     }
12778   else if (TREE_CODE (ptr) == SSA_NAME)
12779     {
12780       /* If object size is not known yet, delay folding until
12781        later.  Maybe subsequent passes will help determining
12782        it.  */
12783       bytes = compute_builtin_object_size (ptr, object_size_type);
12784       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
12785           && double_int_fits_to_tree_p (size_type_node,
12786                                         double_int::from_uhwi (bytes)))
12787         return build_int_cstu (size_type_node, bytes);
12788     }
12789
12790   return NULL_TREE;
12791 }
12792
12793 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12794    DEST, SRC, LEN, and SIZE are the arguments to the call.
12795    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12796    code of the builtin.  If MAXLEN is not NULL, it is maximum length
12797    passed as third argument.  */
12798
12799 tree
12800 fold_builtin_memory_chk (location_t loc, tree fndecl,
12801                          tree dest, tree src, tree len, tree size,
12802                          tree maxlen, bool ignore,
12803                          enum built_in_function fcode)
12804 {
12805   tree fn;
12806
12807   if (!validate_arg (dest, POINTER_TYPE)
12808       || !validate_arg (src,
12809                         (fcode == BUILT_IN_MEMSET_CHK
12810                          ? INTEGER_TYPE : POINTER_TYPE))
12811       || !validate_arg (len, INTEGER_TYPE)
12812       || !validate_arg (size, INTEGER_TYPE))
12813     return NULL_TREE;
12814
12815   /* If SRC and DEST are the same (and not volatile), return DEST
12816      (resp. DEST+LEN for __mempcpy_chk).  */
12817   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12818     {
12819       if (fcode != BUILT_IN_MEMPCPY_CHK)
12820         return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12821                                  dest, len);
12822       else
12823         {
12824           tree temp = fold_build_pointer_plus_loc (loc, dest, len);
12825           return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12826         }
12827     }
12828
12829   if (! host_integerp (size, 1))
12830     return NULL_TREE;
12831
12832   if (! integer_all_onesp (size))
12833     {
12834       if (! 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_MEMPCPY_CHK && ignore)
12842                 {
12843                   /* (void) __mempcpy_chk () can be optimized into
12844                      (void) __memcpy_chk ().  */
12845                   fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12846                   if (!fn)
12847                     return NULL_TREE;
12848
12849                   return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12850                 }
12851               return NULL_TREE;
12852             }
12853         }
12854       else
12855         maxlen = len;
12856
12857       if (tree_int_cst_lt (size, maxlen))
12858         return NULL_TREE;
12859     }
12860
12861   fn = NULL_TREE;
12862   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12863      mem{cpy,pcpy,move,set} is available.  */
12864   switch (fcode)
12865     {
12866     case BUILT_IN_MEMCPY_CHK:
12867       fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12868       break;
12869     case BUILT_IN_MEMPCPY_CHK:
12870       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12871       break;
12872     case BUILT_IN_MEMMOVE_CHK:
12873       fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12874       break;
12875     case BUILT_IN_MEMSET_CHK:
12876       fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12877       break;
12878     default:
12879       break;
12880     }
12881
12882   if (!fn)
12883     return NULL_TREE;
12884
12885   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12886 }
12887
12888 /* Fold a call to the __st[rp]cpy_chk builtin.
12889    DEST, SRC, and SIZE are the arguments to the call.
12890    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12891    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12892    strings passed as second argument.  */
12893
12894 tree
12895 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12896                          tree src, tree size,
12897                          tree maxlen, bool ignore,
12898                          enum built_in_function fcode)
12899 {
12900   tree len, fn;
12901
12902   if (!validate_arg (dest, POINTER_TYPE)
12903       || !validate_arg (src, POINTER_TYPE)
12904       || !validate_arg (size, INTEGER_TYPE))
12905     return NULL_TREE;
12906
12907   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12908   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12909     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12910
12911   if (! host_integerp (size, 1))
12912     return NULL_TREE;
12913
12914   if (! integer_all_onesp (size))
12915     {
12916       len = c_strlen (src, 1);
12917       if (! len || ! host_integerp (len, 1))
12918         {
12919           /* If LEN is not constant, try MAXLEN too.
12920              For MAXLEN only allow optimizing into non-_ocs function
12921              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12922           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12923             {
12924               if (fcode == BUILT_IN_STPCPY_CHK)
12925                 {
12926                   if (! ignore)
12927                     return NULL_TREE;
12928
12929                   /* If return value of __stpcpy_chk is ignored,
12930                      optimize into __strcpy_chk.  */
12931                   fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
12932                   if (!fn)
12933                     return NULL_TREE;
12934
12935                   return build_call_expr_loc (loc, fn, 3, dest, src, size);
12936                 }
12937
12938               if (! len || TREE_SIDE_EFFECTS (len))
12939                 return NULL_TREE;
12940
12941               /* If c_strlen returned something, but not a constant,
12942                  transform __strcpy_chk into __memcpy_chk.  */
12943               fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12944               if (!fn)
12945                 return NULL_TREE;
12946
12947               len = fold_convert_loc (loc, size_type_node, len);
12948               len = size_binop_loc (loc, PLUS_EXPR, len,
12949                                     build_int_cst (size_type_node, 1));
12950               return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12951                                        build_call_expr_loc (loc, fn, 4,
12952                                                         dest, src, len, size));
12953             }
12954         }
12955       else
12956         maxlen = len;
12957
12958       if (! tree_int_cst_lt (maxlen, size))
12959         return NULL_TREE;
12960     }
12961
12962   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12963   fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
12964                               ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
12965   if (!fn)
12966     return NULL_TREE;
12967
12968   return build_call_expr_loc (loc, fn, 2, dest, src);
12969 }
12970
12971 /* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12972    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12973    length passed as third argument. IGNORE is true if return value can be
12974    ignored. FCODE is the BUILT_IN_* code of the builtin. */
12975
12976 tree
12977 fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
12978                           tree len, tree size, tree maxlen, bool ignore,
12979                           enum built_in_function fcode)
12980 {
12981   tree fn;
12982
12983   if (!validate_arg (dest, POINTER_TYPE)
12984       || !validate_arg (src, POINTER_TYPE)
12985       || !validate_arg (len, INTEGER_TYPE)
12986       || !validate_arg (size, INTEGER_TYPE))
12987     return NULL_TREE;
12988
12989   if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
12990     {
12991        /* If return value of __stpncpy_chk is ignored,
12992           optimize into __strncpy_chk.  */
12993        fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
12994        if (fn)
12995          return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12996     }
12997
12998   if (! host_integerp (size, 1))
12999     return NULL_TREE;
13000
13001   if (! integer_all_onesp (size))
13002     {
13003       if (! host_integerp (len, 1))
13004         {
13005           /* If LEN is not constant, try MAXLEN too.
13006              For MAXLEN only allow optimizing into non-_ocs function
13007              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13008           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13009             return NULL_TREE;
13010         }
13011       else
13012         maxlen = len;
13013
13014       if (tree_int_cst_lt (size, maxlen))
13015         return NULL_TREE;
13016     }
13017
13018   /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
13019   fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
13020                               ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
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 to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
13028    are the arguments to the call.  */
13029
13030 static tree
13031 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
13032                          tree src, tree size)
13033 {
13034   tree fn;
13035   const char *p;
13036
13037   if (!validate_arg (dest, POINTER_TYPE)
13038       || !validate_arg (src, POINTER_TYPE)
13039       || !validate_arg (size, INTEGER_TYPE))
13040     return NULL_TREE;
13041
13042   p = c_getstr (src);
13043   /* If the SRC parameter is "", return DEST.  */
13044   if (p && *p == '\0')
13045     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
13046
13047   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
13048     return NULL_TREE;
13049
13050   /* If __builtin_strcat_chk is used, assume strcat is available.  */
13051   fn = builtin_decl_explicit (BUILT_IN_STRCAT);
13052   if (!fn)
13053     return NULL_TREE;
13054
13055   return build_call_expr_loc (loc, fn, 2, dest, src);
13056 }
13057
13058 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
13059    LEN, and SIZE.  */
13060
13061 static tree
13062 fold_builtin_strncat_chk (location_t loc, tree fndecl,
13063                           tree dest, tree src, tree len, tree size)
13064 {
13065   tree fn;
13066   const char *p;
13067
13068   if (!validate_arg (dest, POINTER_TYPE)
13069       || !validate_arg (src, POINTER_TYPE)
13070       || !validate_arg (size, INTEGER_TYPE)
13071       || !validate_arg (size, INTEGER_TYPE))
13072     return NULL_TREE;
13073
13074   p = c_getstr (src);
13075   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
13076   if (p && *p == '\0')
13077     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
13078   else if (integer_zerop (len))
13079     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
13080
13081   if (! host_integerp (size, 1))
13082     return NULL_TREE;
13083
13084   if (! integer_all_onesp (size))
13085     {
13086       tree src_len = c_strlen (src, 1);
13087       if (src_len
13088           && host_integerp (src_len, 1)
13089           && host_integerp (len, 1)
13090           && ! tree_int_cst_lt (len, src_len))
13091         {
13092           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
13093           fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
13094           if (!fn)
13095             return NULL_TREE;
13096
13097           return build_call_expr_loc (loc, fn, 3, dest, src, size);
13098         }
13099       return NULL_TREE;
13100     }
13101
13102   /* If __builtin_strncat_chk is used, assume strncat is available.  */
13103   fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
13104   if (!fn)
13105     return NULL_TREE;
13106
13107   return build_call_expr_loc (loc, fn, 3, dest, src, len);
13108 }
13109
13110 /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
13111    Return NULL_TREE if a normal call should be emitted rather than
13112    expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
13113    or BUILT_IN_VSPRINTF_CHK.  */
13114
13115 static tree
13116 fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
13117                             enum built_in_function fcode)
13118 {
13119   tree dest, size, len, fn, fmt, flag;
13120   const char *fmt_str;
13121
13122   /* Verify the required arguments in the original call.  */
13123   if (nargs < 4)
13124     return NULL_TREE;
13125   dest = args[0];
13126   if (!validate_arg (dest, POINTER_TYPE))
13127     return NULL_TREE;
13128   flag = args[1];
13129   if (!validate_arg (flag, INTEGER_TYPE))
13130     return NULL_TREE;
13131   size = args[2];
13132   if (!validate_arg (size, INTEGER_TYPE))
13133     return NULL_TREE;
13134   fmt = args[3];
13135   if (!validate_arg (fmt, POINTER_TYPE))
13136     return NULL_TREE;
13137
13138   if (! host_integerp (size, 1))
13139     return NULL_TREE;
13140
13141   len = NULL_TREE;
13142
13143   if (!init_target_chars ())
13144     return NULL_TREE;
13145
13146   /* Check whether the format is a literal string constant.  */
13147   fmt_str = c_getstr (fmt);
13148   if (fmt_str != NULL)
13149     {
13150       /* If the format doesn't contain % args or %%, we know the size.  */
13151       if (strchr (fmt_str, target_percent) == 0)
13152         {
13153           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13154             len = build_int_cstu (size_type_node, strlen (fmt_str));
13155         }
13156       /* If the format is "%s" and first ... argument is a string literal,
13157          we know the size too.  */
13158       else if (fcode == BUILT_IN_SPRINTF_CHK
13159                && strcmp (fmt_str, target_percent_s) == 0)
13160         {
13161           tree arg;
13162
13163           if (nargs == 5)
13164             {
13165               arg = args[4];
13166               if (validate_arg (arg, POINTER_TYPE))
13167                 {
13168                   len = c_strlen (arg, 1);
13169                   if (! len || ! host_integerp (len, 1))
13170                     len = NULL_TREE;
13171                 }
13172             }
13173         }
13174     }
13175
13176   if (! integer_all_onesp (size))
13177     {
13178       if (! len || ! tree_int_cst_lt (len, size))
13179         return NULL_TREE;
13180     }
13181
13182   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13183      or if format doesn't contain % chars or is "%s".  */
13184   if (! integer_zerop (flag))
13185     {
13186       if (fmt_str == NULL)
13187         return NULL_TREE;
13188       if (strchr (fmt_str, target_percent) != NULL
13189           && strcmp (fmt_str, target_percent_s))
13190         return NULL_TREE;
13191     }
13192
13193   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13194   fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
13195                               ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
13196   if (!fn)
13197     return NULL_TREE;
13198
13199   return rewrite_call_expr_array (loc, nargs, args, 4, fn, 2, dest, fmt);
13200 }
13201
13202 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
13203    a normal call should be emitted rather than expanding the function
13204    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13205
13206 static tree
13207 fold_builtin_sprintf_chk (location_t loc, tree exp,
13208                           enum built_in_function fcode)
13209 {
13210   return fold_builtin_sprintf_chk_1 (loc, call_expr_nargs (exp),
13211                                      CALL_EXPR_ARGP (exp), fcode);
13212 }
13213
13214 /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
13215    NULL_TREE if a normal call should be emitted rather than expanding
13216    the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13217    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13218    passed as second argument.  */
13219
13220 static tree
13221 fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
13222                              tree maxlen, enum built_in_function fcode)
13223 {
13224   tree dest, size, len, fn, fmt, flag;
13225   const char *fmt_str;
13226
13227   /* Verify the required arguments in the original call.  */
13228   if (nargs < 5)
13229     return NULL_TREE;
13230   dest = args[0];
13231   if (!validate_arg (dest, POINTER_TYPE))
13232     return NULL_TREE;
13233   len = args[1];
13234   if (!validate_arg (len, INTEGER_TYPE))
13235     return NULL_TREE;
13236   flag = args[2];
13237   if (!validate_arg (flag, INTEGER_TYPE))
13238     return NULL_TREE;
13239   size = args[3];
13240   if (!validate_arg (size, INTEGER_TYPE))
13241     return NULL_TREE;
13242   fmt = args[4];
13243   if (!validate_arg (fmt, POINTER_TYPE))
13244     return NULL_TREE;
13245
13246   if (! host_integerp (size, 1))
13247     return NULL_TREE;
13248
13249   if (! integer_all_onesp (size))
13250     {
13251       if (! host_integerp (len, 1))
13252         {
13253           /* If LEN is not constant, try MAXLEN too.
13254              For MAXLEN only allow optimizing into non-_ocs function
13255              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13256           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13257             return NULL_TREE;
13258         }
13259       else
13260         maxlen = len;
13261
13262       if (tree_int_cst_lt (size, maxlen))
13263         return NULL_TREE;
13264     }
13265
13266   if (!init_target_chars ())
13267     return NULL_TREE;
13268
13269   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13270      or if format doesn't contain % chars or is "%s".  */
13271   if (! integer_zerop (flag))
13272     {
13273       fmt_str = c_getstr (fmt);
13274       if (fmt_str == NULL)
13275         return NULL_TREE;
13276       if (strchr (fmt_str, target_percent) != NULL
13277           && strcmp (fmt_str, target_percent_s))
13278         return NULL_TREE;
13279     }
13280
13281   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13282      available.  */
13283   fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
13284                               ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
13285   if (!fn)
13286     return NULL_TREE;
13287
13288   return rewrite_call_expr_array (loc, nargs, args, 5, fn, 3, dest, len, fmt);
13289 }
13290
13291 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
13292    a normal call should be emitted rather than expanding the function
13293    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13294    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13295    passed as second argument.  */
13296
13297 tree
13298 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
13299                            enum built_in_function fcode)
13300 {
13301   return fold_builtin_snprintf_chk_1 (loc, call_expr_nargs (exp),
13302                                       CALL_EXPR_ARGP (exp), maxlen, fcode);
13303 }
13304
13305 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
13306    FMT and ARG are the arguments to the call; we don't fold cases with
13307    more than 2 arguments, and ARG may be null if this is a 1-argument case.
13308
13309    Return NULL_TREE if no simplification was possible, otherwise return the
13310    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13311    code of the function to be simplified.  */
13312
13313 static tree
13314 fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13315                      tree arg, bool ignore,
13316                      enum built_in_function fcode)
13317 {
13318   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
13319   const char *fmt_str = NULL;
13320
13321   /* If the return value is used, don't do the transformation.  */
13322   if (! ignore)
13323     return NULL_TREE;
13324
13325   /* Verify the required arguments in the original call.  */
13326   if (!validate_arg (fmt, POINTER_TYPE))
13327     return NULL_TREE;
13328
13329   /* Check whether the format is a literal string constant.  */
13330   fmt_str = c_getstr (fmt);
13331   if (fmt_str == NULL)
13332     return NULL_TREE;
13333
13334   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13335     {
13336       /* If we're using an unlocked function, assume the other
13337          unlocked functions exist explicitly.  */
13338       fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
13339       fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
13340     }
13341   else
13342     {
13343       fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
13344       fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
13345     }
13346
13347   if (!init_target_chars ())
13348     return NULL_TREE;
13349
13350   if (strcmp (fmt_str, target_percent_s) == 0
13351       || strchr (fmt_str, target_percent) == NULL)
13352     {
13353       const char *str;
13354
13355       if (strcmp (fmt_str, target_percent_s) == 0)
13356         {
13357           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13358             return NULL_TREE;
13359
13360           if (!arg || !validate_arg (arg, POINTER_TYPE))
13361             return NULL_TREE;
13362
13363           str = c_getstr (arg);
13364           if (str == NULL)
13365             return NULL_TREE;
13366         }
13367       else
13368         {
13369           /* The format specifier doesn't contain any '%' characters.  */
13370           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
13371               && arg)
13372             return NULL_TREE;
13373           str = fmt_str;
13374         }
13375
13376       /* If the string was "", printf does nothing.  */
13377       if (str[0] == '\0')
13378         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13379
13380       /* If the string has length of 1, call putchar.  */
13381       if (str[1] == '\0')
13382         {
13383           /* Given printf("c"), (where c is any one character,)
13384              convert "c"[0] to an int and pass that to the replacement
13385              function.  */
13386           newarg = build_int_cst (integer_type_node, str[0]);
13387           if (fn_putchar)
13388             call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
13389         }
13390       else
13391         {
13392           /* If the string was "string\n", call puts("string").  */
13393           size_t len = strlen (str);
13394           if ((unsigned char)str[len - 1] == target_newline
13395               && (size_t) (int) len == len
13396               && (int) len > 0)
13397             {
13398               char *newstr;
13399               tree offset_node, string_cst;
13400
13401               /* Create a NUL-terminated string that's one char shorter
13402                  than the original, stripping off the trailing '\n'.  */
13403               newarg = build_string_literal (len, str);
13404               string_cst = string_constant (newarg, &offset_node);
13405               gcc_checking_assert (string_cst
13406                                    && (TREE_STRING_LENGTH (string_cst)
13407                                        == (int) len)
13408                                    && integer_zerop (offset_node)
13409                                    && (unsigned char)
13410                                       TREE_STRING_POINTER (string_cst)[len - 1]
13411                                       == target_newline);
13412               /* build_string_literal creates a new STRING_CST,
13413                  modify it in place to avoid double copying.  */
13414               newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst));
13415               newstr[len - 1] = '\0';
13416               if (fn_puts)
13417                 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
13418             }
13419           else
13420             /* We'd like to arrange to call fputs(string,stdout) here,
13421                but we need stdout and don't have a way to get it yet.  */
13422             return NULL_TREE;
13423         }
13424     }
13425
13426   /* The other optimizations can be done only on the non-va_list variants.  */
13427   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13428     return NULL_TREE;
13429
13430   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
13431   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
13432     {
13433       if (!arg || !validate_arg (arg, POINTER_TYPE))
13434         return NULL_TREE;
13435       if (fn_puts)
13436         call = build_call_expr_loc (loc, fn_puts, 1, arg);
13437     }
13438
13439   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
13440   else if (strcmp (fmt_str, target_percent_c) == 0)
13441     {
13442       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13443         return NULL_TREE;
13444       if (fn_putchar)
13445         call = build_call_expr_loc (loc, fn_putchar, 1, arg);
13446     }
13447
13448   if (!call)
13449     return NULL_TREE;
13450
13451   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13452 }
13453
13454 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
13455    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
13456    more than 3 arguments, and ARG may be null in the 2-argument case.
13457
13458    Return NULL_TREE if no simplification was possible, otherwise return the
13459    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13460    code of the function to be simplified.  */
13461
13462 static tree
13463 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13464                       tree fmt, tree arg, bool ignore,
13465                       enum built_in_function fcode)
13466 {
13467   tree fn_fputc, fn_fputs, call = NULL_TREE;
13468   const char *fmt_str = NULL;
13469
13470   /* If the return value is used, don't do the transformation.  */
13471   if (! ignore)
13472     return NULL_TREE;
13473
13474   /* Verify the required arguments in the original call.  */
13475   if (!validate_arg (fp, POINTER_TYPE))
13476     return NULL_TREE;
13477   if (!validate_arg (fmt, POINTER_TYPE))
13478     return NULL_TREE;
13479
13480   /* Check whether the format is a literal string constant.  */
13481   fmt_str = c_getstr (fmt);
13482   if (fmt_str == NULL)
13483     return NULL_TREE;
13484
13485   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13486     {
13487       /* If we're using an unlocked function, assume the other
13488          unlocked functions exist explicitly.  */
13489       fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
13490       fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
13491     }
13492   else
13493     {
13494       fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
13495       fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
13496     }
13497
13498   if (!init_target_chars ())
13499     return NULL_TREE;
13500
13501   /* If the format doesn't contain % args or %%, use strcpy.  */
13502   if (strchr (fmt_str, target_percent) == NULL)
13503     {
13504       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
13505           && arg)
13506         return NULL_TREE;
13507
13508       /* If the format specifier was "", fprintf does nothing.  */
13509       if (fmt_str[0] == '\0')
13510         {
13511           /* If FP has side-effects, just wait until gimplification is
13512              done.  */
13513           if (TREE_SIDE_EFFECTS (fp))
13514             return NULL_TREE;
13515
13516           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13517         }
13518
13519       /* When "string" doesn't contain %, replace all cases of
13520          fprintf (fp, string) with fputs (string, fp).  The fputs
13521          builtin will take care of special cases like length == 1.  */
13522       if (fn_fputs)
13523         call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
13524     }
13525
13526   /* The other optimizations can be done only on the non-va_list variants.  */
13527   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
13528     return NULL_TREE;
13529
13530   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
13531   else if (strcmp (fmt_str, target_percent_s) == 0)
13532     {
13533       if (!arg || !validate_arg (arg, POINTER_TYPE))
13534         return NULL_TREE;
13535       if (fn_fputs)
13536         call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
13537     }
13538
13539   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
13540   else if (strcmp (fmt_str, target_percent_c) == 0)
13541     {
13542       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13543         return NULL_TREE;
13544       if (fn_fputc)
13545         call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
13546     }
13547
13548   if (!call)
13549     return NULL_TREE;
13550   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13551 }
13552
13553 /* Initialize format string characters in the target charset.  */
13554
13555 static bool
13556 init_target_chars (void)
13557 {
13558   static bool init;
13559   if (!init)
13560     {
13561       target_newline = lang_hooks.to_target_charset ('\n');
13562       target_percent = lang_hooks.to_target_charset ('%');
13563       target_c = lang_hooks.to_target_charset ('c');
13564       target_s = lang_hooks.to_target_charset ('s');
13565       if (target_newline == 0 || target_percent == 0 || target_c == 0
13566           || target_s == 0)
13567         return false;
13568
13569       target_percent_c[0] = target_percent;
13570       target_percent_c[1] = target_c;
13571       target_percent_c[2] = '\0';
13572
13573       target_percent_s[0] = target_percent;
13574       target_percent_s[1] = target_s;
13575       target_percent_s[2] = '\0';
13576
13577       target_percent_s_newline[0] = target_percent;
13578       target_percent_s_newline[1] = target_s;
13579       target_percent_s_newline[2] = target_newline;
13580       target_percent_s_newline[3] = '\0';
13581
13582       init = true;
13583     }
13584   return true;
13585 }
13586
13587 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13588    and no overflow/underflow occurred.  INEXACT is true if M was not
13589    exactly calculated.  TYPE is the tree type for the result.  This
13590    function assumes that you cleared the MPFR flags and then
13591    calculated M to see if anything subsequently set a flag prior to
13592    entering this function.  Return NULL_TREE if any checks fail.  */
13593
13594 static tree
13595 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13596 {
13597   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13598      overflow/underflow occurred.  If -frounding-math, proceed iff the
13599      result of calling FUNC was exact.  */
13600   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13601       && (!flag_rounding_math || !inexact))
13602     {
13603       REAL_VALUE_TYPE rr;
13604
13605       real_from_mpfr (&rr, m, type, GMP_RNDN);
13606       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13607          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13608          but the mpft_t is not, then we underflowed in the
13609          conversion.  */
13610       if (real_isfinite (&rr)
13611           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13612         {
13613           REAL_VALUE_TYPE rmode;
13614
13615           real_convert (&rmode, TYPE_MODE (type), &rr);
13616           /* Proceed iff the specified mode can hold the value.  */
13617           if (real_identical (&rmode, &rr))
13618             return build_real (type, rmode);
13619         }
13620     }
13621   return NULL_TREE;
13622 }
13623
13624 /* Helper function for do_mpc_arg*().  Ensure M is a normal complex
13625    number and no overflow/underflow occurred.  INEXACT is true if M
13626    was not exactly calculated.  TYPE is the tree type for the result.
13627    This function assumes that you cleared the MPFR flags and then
13628    calculated M to see if anything subsequently set a flag prior to
13629    entering this function.  Return NULL_TREE if any checks fail, if
13630    FORCE_CONVERT is true, then bypass the checks.  */
13631
13632 static tree
13633 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13634 {
13635   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13636      overflow/underflow occurred.  If -frounding-math, proceed iff the
13637      result of calling FUNC was exact.  */
13638   if (force_convert
13639       || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13640           && !mpfr_overflow_p () && !mpfr_underflow_p ()
13641           && (!flag_rounding_math || !inexact)))
13642     {
13643       REAL_VALUE_TYPE re, im;
13644
13645       real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN);
13646       real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN);
13647       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13648          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13649          but the mpft_t is not, then we underflowed in the
13650          conversion.  */
13651       if (force_convert
13652           || (real_isfinite (&re) && real_isfinite (&im)
13653               && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13654               && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13655         {
13656           REAL_VALUE_TYPE re_mode, im_mode;
13657
13658           real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13659           real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13660           /* Proceed iff the specified mode can hold the value.  */
13661           if (force_convert
13662               || (real_identical (&re_mode, &re)
13663                   && real_identical (&im_mode, &im)))
13664             return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13665                                   build_real (TREE_TYPE (type), im_mode));
13666         }
13667     }
13668   return NULL_TREE;
13669 }
13670
13671 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13672    FUNC on it and return the resulting value as a tree with type TYPE.
13673    If MIN and/or MAX are not NULL, then the supplied ARG must be
13674    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13675    acceptable values, otherwise they are not.  The mpfr precision is
13676    set to the precision of TYPE.  We assume that function FUNC returns
13677    zero if the result could be calculated exactly within the requested
13678    precision.  */
13679
13680 static tree
13681 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13682               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13683               bool inclusive)
13684 {
13685   tree result = NULL_TREE;
13686
13687   STRIP_NOPS (arg);
13688
13689   /* To proceed, MPFR must exactly represent the target floating point
13690      format, which only happens when the target base equals two.  */
13691   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13692       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13693     {
13694       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13695
13696       if (real_isfinite (ra)
13697           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13698           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13699         {
13700           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13701           const int prec = fmt->p;
13702           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13703           int inexact;
13704           mpfr_t m;
13705
13706           mpfr_init2 (m, prec);
13707           mpfr_from_real (m, ra, GMP_RNDN);
13708           mpfr_clear_flags ();
13709           inexact = func (m, m, rnd);
13710           result = do_mpfr_ckconv (m, type, inexact);
13711           mpfr_clear (m);
13712         }
13713     }
13714
13715   return result;
13716 }
13717
13718 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13719    FUNC on it and return the resulting value as a tree with type TYPE.
13720    The mpfr precision is set to the precision of TYPE.  We assume that
13721    function FUNC returns zero if the result could be calculated
13722    exactly within the requested precision.  */
13723
13724 static tree
13725 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13726               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13727 {
13728   tree result = NULL_TREE;
13729
13730   STRIP_NOPS (arg1);
13731   STRIP_NOPS (arg2);
13732
13733   /* To proceed, MPFR must exactly represent the target floating point
13734      format, which only happens when the target base equals two.  */
13735   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13736       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13737       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13738     {
13739       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13740       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13741
13742       if (real_isfinite (ra1) && real_isfinite (ra2))
13743         {
13744           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13745           const int prec = fmt->p;
13746           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13747           int inexact;
13748           mpfr_t m1, m2;
13749
13750           mpfr_inits2 (prec, m1, m2, NULL);
13751           mpfr_from_real (m1, ra1, GMP_RNDN);
13752           mpfr_from_real (m2, ra2, GMP_RNDN);
13753           mpfr_clear_flags ();
13754           inexact = func (m1, m1, m2, rnd);
13755           result = do_mpfr_ckconv (m1, type, inexact);
13756           mpfr_clears (m1, m2, NULL);
13757         }
13758     }
13759
13760   return result;
13761 }
13762
13763 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13764    FUNC on it and return the resulting value as a tree with type TYPE.
13765    The mpfr precision is set to the precision of TYPE.  We assume that
13766    function FUNC returns zero if the result could be calculated
13767    exactly within the requested precision.  */
13768
13769 static tree
13770 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13771               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13772 {
13773   tree result = NULL_TREE;
13774
13775   STRIP_NOPS (arg1);
13776   STRIP_NOPS (arg2);
13777   STRIP_NOPS (arg3);
13778
13779   /* To proceed, MPFR must exactly represent the target floating point
13780      format, which only happens when the target base equals two.  */
13781   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13782       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13783       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13784       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13785     {
13786       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13787       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13788       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13789
13790       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13791         {
13792           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13793           const int prec = fmt->p;
13794           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13795           int inexact;
13796           mpfr_t m1, m2, m3;
13797
13798           mpfr_inits2 (prec, m1, m2, m3, NULL);
13799           mpfr_from_real (m1, ra1, GMP_RNDN);
13800           mpfr_from_real (m2, ra2, GMP_RNDN);
13801           mpfr_from_real (m3, ra3, GMP_RNDN);
13802           mpfr_clear_flags ();
13803           inexact = func (m1, m1, m2, m3, rnd);
13804           result = do_mpfr_ckconv (m1, type, inexact);
13805           mpfr_clears (m1, m2, m3, NULL);
13806         }
13807     }
13808
13809   return result;
13810 }
13811
13812 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13813    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13814    If ARG_SINP and ARG_COSP are NULL then the result is returned
13815    as a complex value.
13816    The type is taken from the type of ARG and is used for setting the
13817    precision of the calculation and results.  */
13818
13819 static tree
13820 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13821 {
13822   tree const type = TREE_TYPE (arg);
13823   tree result = NULL_TREE;
13824
13825   STRIP_NOPS (arg);
13826
13827   /* To proceed, MPFR must exactly represent the target floating point
13828      format, which only happens when the target base equals two.  */
13829   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13830       && TREE_CODE (arg) == REAL_CST
13831       && !TREE_OVERFLOW (arg))
13832     {
13833       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13834
13835       if (real_isfinite (ra))
13836         {
13837           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13838           const int prec = fmt->p;
13839           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13840           tree result_s, result_c;
13841           int inexact;
13842           mpfr_t m, ms, mc;
13843
13844           mpfr_inits2 (prec, m, ms, mc, NULL);
13845           mpfr_from_real (m, ra, GMP_RNDN);
13846           mpfr_clear_flags ();
13847           inexact = mpfr_sin_cos (ms, mc, m, rnd);
13848           result_s = do_mpfr_ckconv (ms, type, inexact);
13849           result_c = do_mpfr_ckconv (mc, type, inexact);
13850           mpfr_clears (m, ms, mc, NULL);
13851           if (result_s && result_c)
13852             {
13853               /* If we are to return in a complex value do so.  */
13854               if (!arg_sinp && !arg_cosp)
13855                 return build_complex (build_complex_type (type),
13856                                       result_c, result_s);
13857
13858               /* Dereference the sin/cos pointer arguments.  */
13859               arg_sinp = build_fold_indirect_ref (arg_sinp);
13860               arg_cosp = build_fold_indirect_ref (arg_cosp);
13861               /* Proceed if valid pointer type were passed in.  */
13862               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13863                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13864                 {
13865                   /* Set the values. */
13866                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13867                                           result_s);
13868                   TREE_SIDE_EFFECTS (result_s) = 1;
13869                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13870                                           result_c);
13871                   TREE_SIDE_EFFECTS (result_c) = 1;
13872                   /* Combine the assignments into a compound expr.  */
13873                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13874                                                     result_s, result_c));
13875                 }
13876             }
13877         }
13878     }
13879   return result;
13880 }
13881
13882 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13883    two-argument mpfr order N Bessel function FUNC on them and return
13884    the resulting value as a tree with type TYPE.  The mpfr precision
13885    is set to the precision of TYPE.  We assume that function FUNC
13886    returns zero if the result could be calculated exactly within the
13887    requested precision.  */
13888 static tree
13889 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13890                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13891                   const REAL_VALUE_TYPE *min, bool inclusive)
13892 {
13893   tree result = NULL_TREE;
13894
13895   STRIP_NOPS (arg1);
13896   STRIP_NOPS (arg2);
13897
13898   /* To proceed, MPFR must exactly represent the target floating point
13899      format, which only happens when the target base equals two.  */
13900   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13901       && host_integerp (arg1, 0)
13902       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13903     {
13904       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13905       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13906
13907       if (n == (long)n
13908           && real_isfinite (ra)
13909           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13910         {
13911           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13912           const int prec = fmt->p;
13913           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13914           int inexact;
13915           mpfr_t m;
13916
13917           mpfr_init2 (m, prec);
13918           mpfr_from_real (m, ra, GMP_RNDN);
13919           mpfr_clear_flags ();
13920           inexact = func (m, n, m, rnd);
13921           result = do_mpfr_ckconv (m, type, inexact);
13922           mpfr_clear (m);
13923         }
13924     }
13925
13926   return result;
13927 }
13928
13929 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13930    the pointer *(ARG_QUO) and return the result.  The type is taken
13931    from the type of ARG0 and is used for setting the precision of the
13932    calculation and results.  */
13933
13934 static tree
13935 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13936 {
13937   tree const type = TREE_TYPE (arg0);
13938   tree result = NULL_TREE;
13939
13940   STRIP_NOPS (arg0);
13941   STRIP_NOPS (arg1);
13942
13943   /* To proceed, MPFR must exactly represent the target floating point
13944      format, which only happens when the target base equals two.  */
13945   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13946       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13947       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13948     {
13949       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13950       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13951
13952       if (real_isfinite (ra0) && real_isfinite (ra1))
13953         {
13954           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13955           const int prec = fmt->p;
13956           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13957           tree result_rem;
13958           long integer_quo;
13959           mpfr_t m0, m1;
13960
13961           mpfr_inits2 (prec, m0, m1, NULL);
13962           mpfr_from_real (m0, ra0, GMP_RNDN);
13963           mpfr_from_real (m1, ra1, GMP_RNDN);
13964           mpfr_clear_flags ();
13965           mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13966           /* Remquo is independent of the rounding mode, so pass
13967              inexact=0 to do_mpfr_ckconv().  */
13968           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13969           mpfr_clears (m0, m1, NULL);
13970           if (result_rem)
13971             {
13972               /* MPFR calculates quo in the host's long so it may
13973                  return more bits in quo than the target int can hold
13974                  if sizeof(host long) > sizeof(target int).  This can
13975                  happen even for native compilers in LP64 mode.  In
13976                  these cases, modulo the quo value with the largest
13977                  number that the target int can hold while leaving one
13978                  bit for the sign.  */
13979               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13980                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13981
13982               /* Dereference the quo pointer argument.  */
13983               arg_quo = build_fold_indirect_ref (arg_quo);
13984               /* Proceed iff a valid pointer type was passed in.  */
13985               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13986                 {
13987                   /* Set the value. */
13988                   tree result_quo
13989                     = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo,
13990                                    build_int_cst (TREE_TYPE (arg_quo),
13991                                                   integer_quo));
13992                   TREE_SIDE_EFFECTS (result_quo) = 1;
13993                   /* Combine the quo assignment with the rem.  */
13994                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13995                                                     result_quo, result_rem));
13996                 }
13997             }
13998         }
13999     }
14000   return result;
14001 }
14002
14003 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
14004    resulting value as a tree with type TYPE.  The mpfr precision is
14005    set to the precision of TYPE.  We assume that this mpfr function
14006    returns zero if the result could be calculated exactly within the
14007    requested precision.  In addition, the integer pointer represented
14008    by ARG_SG will be dereferenced and set to the appropriate signgam
14009    (-1,1) value.  */
14010
14011 static tree
14012 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
14013 {
14014   tree result = NULL_TREE;
14015
14016   STRIP_NOPS (arg);
14017
14018   /* To proceed, MPFR must exactly represent the target floating point
14019      format, which only happens when the target base equals two.  Also
14020      verify ARG is a constant and that ARG_SG is an int pointer.  */
14021   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
14022       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
14023       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
14024       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
14025     {
14026       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
14027
14028       /* In addition to NaN and Inf, the argument cannot be zero or a
14029          negative integer.  */
14030       if (real_isfinite (ra)
14031           && ra->cl != rvc_zero
14032           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
14033         {
14034           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
14035           const int prec = fmt->p;
14036           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
14037           int inexact, sg;
14038           mpfr_t m;
14039           tree result_lg;
14040
14041           mpfr_init2 (m, prec);
14042           mpfr_from_real (m, ra, GMP_RNDN);
14043           mpfr_clear_flags ();
14044           inexact = mpfr_lgamma (m, &sg, m, rnd);
14045           result_lg = do_mpfr_ckconv (m, type, inexact);
14046           mpfr_clear (m);
14047           if (result_lg)
14048             {
14049               tree result_sg;
14050
14051               /* Dereference the arg_sg pointer argument.  */
14052               arg_sg = build_fold_indirect_ref (arg_sg);
14053               /* Assign the signgam value into *arg_sg. */
14054               result_sg = fold_build2 (MODIFY_EXPR,
14055                                        TREE_TYPE (arg_sg), arg_sg,
14056                                        build_int_cst (TREE_TYPE (arg_sg), sg));
14057               TREE_SIDE_EFFECTS (result_sg) = 1;
14058               /* Combine the signgam assignment with the lgamma result.  */
14059               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
14060                                                 result_sg, result_lg));
14061             }
14062         }
14063     }
14064
14065   return result;
14066 }
14067
14068 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc
14069    function FUNC on it and return the resulting value as a tree with
14070    type TYPE.  The mpfr precision is set to the precision of TYPE.  We
14071    assume that function FUNC returns zero if the result could be
14072    calculated exactly within the requested precision.  */
14073
14074 static tree
14075 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
14076 {
14077   tree result = NULL_TREE;
14078
14079   STRIP_NOPS (arg);
14080
14081   /* To proceed, MPFR must exactly represent the target floating point
14082      format, which only happens when the target base equals two.  */
14083   if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
14084       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
14085       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
14086     {
14087       const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
14088       const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
14089
14090       if (real_isfinite (re) && real_isfinite (im))
14091         {
14092           const struct real_format *const fmt =
14093             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14094           const int prec = fmt->p;
14095           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14096           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14097           int inexact;
14098           mpc_t m;
14099
14100           mpc_init2 (m, prec);
14101           mpfr_from_real (mpc_realref(m), re, rnd);
14102           mpfr_from_real (mpc_imagref(m), im, rnd);
14103           mpfr_clear_flags ();
14104           inexact = func (m, m, crnd);
14105           result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
14106           mpc_clear (m);
14107         }
14108     }
14109
14110   return result;
14111 }
14112
14113 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
14114    mpc function FUNC on it and return the resulting value as a tree
14115    with type TYPE.  The mpfr precision is set to the precision of
14116    TYPE.  We assume that function FUNC returns zero if the result
14117    could be calculated exactly within the requested precision.  If
14118    DO_NONFINITE is true, then fold expressions containing Inf or NaN
14119    in the arguments and/or results.  */
14120
14121 tree
14122 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
14123              int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
14124 {
14125   tree result = NULL_TREE;
14126
14127   STRIP_NOPS (arg0);
14128   STRIP_NOPS (arg1);
14129
14130   /* To proceed, MPFR must exactly represent the target floating point
14131      format, which only happens when the target base equals two.  */
14132   if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
14133       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
14134       && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
14135       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
14136       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
14137     {
14138       const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
14139       const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
14140       const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
14141       const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
14142
14143       if (do_nonfinite
14144           || (real_isfinite (re0) && real_isfinite (im0)
14145               && real_isfinite (re1) && real_isfinite (im1)))
14146         {
14147           const struct real_format *const fmt =
14148             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14149           const int prec = fmt->p;
14150           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14151           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14152           int inexact;
14153           mpc_t m0, m1;
14154
14155           mpc_init2 (m0, prec);
14156           mpc_init2 (m1, prec);
14157           mpfr_from_real (mpc_realref(m0), re0, rnd);
14158           mpfr_from_real (mpc_imagref(m0), im0, rnd);
14159           mpfr_from_real (mpc_realref(m1), re1, rnd);
14160           mpfr_from_real (mpc_imagref(m1), im1, rnd);
14161           mpfr_clear_flags ();
14162           inexact = func (m0, m0, m1, crnd);
14163           result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
14164           mpc_clear (m0);
14165           mpc_clear (m1);
14166         }
14167     }
14168
14169   return result;
14170 }
14171
14172 /* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
14173    a normal call should be emitted rather than expanding the function
14174    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
14175
14176 static tree
14177 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
14178 {
14179   int nargs = gimple_call_num_args (stmt);
14180
14181   return fold_builtin_sprintf_chk_1 (gimple_location (stmt), nargs,
14182                                      (nargs > 0
14183                                       ? gimple_call_arg_ptr (stmt, 0)
14184                                       : &error_mark_node), fcode);
14185 }
14186
14187 /* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
14188    a normal call should be emitted rather than expanding the function
14189    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
14190    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
14191    passed as second argument.  */
14192
14193 tree
14194 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14195                                   enum built_in_function fcode)
14196 {
14197   int nargs = gimple_call_num_args (stmt);
14198
14199   return fold_builtin_snprintf_chk_1 (gimple_location (stmt), nargs,
14200                                       (nargs > 0
14201                                        ? gimple_call_arg_ptr (stmt, 0)
14202                                        : &error_mark_node), maxlen, fcode);
14203 }
14204
14205 /* Builtins with folding operations that operate on "..." arguments
14206    need special handling; we need to store the arguments in a convenient
14207    data structure before attempting any folding.  Fortunately there are
14208    only a few builtins that fall into this category.  FNDECL is the
14209    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14210    result of the function call is ignored.  */
14211
14212 static tree
14213 gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14214                              bool ignore ATTRIBUTE_UNUSED)
14215 {
14216   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14217   tree ret = NULL_TREE;
14218
14219   switch (fcode)
14220     {
14221     case BUILT_IN_SPRINTF_CHK:
14222     case BUILT_IN_VSPRINTF_CHK:
14223       ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14224       break;
14225
14226     case BUILT_IN_SNPRINTF_CHK:
14227     case BUILT_IN_VSNPRINTF_CHK:
14228       ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14229
14230     default:
14231       break;
14232     }
14233   if (ret)
14234     {
14235       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14236       TREE_NO_WARNING (ret) = 1;
14237       return ret;
14238     }
14239   return NULL_TREE;
14240 }
14241
14242 /* A wrapper function for builtin folding that prevents warnings for
14243    "statement without effect" and the like, caused by removing the
14244    call node earlier than the warning is generated.  */
14245
14246 tree
14247 fold_call_stmt (gimple stmt, bool ignore)
14248 {
14249   tree ret = NULL_TREE;
14250   tree fndecl = gimple_call_fndecl (stmt);
14251   location_t loc = gimple_location (stmt);
14252   if (fndecl
14253       && TREE_CODE (fndecl) == FUNCTION_DECL
14254       && DECL_BUILT_IN (fndecl)
14255       && !gimple_call_va_arg_pack_p (stmt))
14256     {
14257       int nargs = gimple_call_num_args (stmt);
14258       tree *args = (nargs > 0
14259                     ? gimple_call_arg_ptr (stmt, 0)
14260                     : &error_mark_node);
14261
14262       if (avoid_folding_inline_builtin (fndecl))
14263         return NULL_TREE;
14264       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14265         {
14266           return targetm.fold_builtin (fndecl, nargs, args, ignore);
14267         }
14268       else
14269         {
14270           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14271             ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
14272           if (!ret)
14273             ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14274           if (ret)
14275             {
14276               /* Propagate location information from original call to
14277                  expansion of builtin.  Otherwise things like
14278                  maybe_emit_chk_warning, that operate on the expansion
14279                  of a builtin, will use the wrong location information.  */
14280               if (gimple_has_location (stmt))
14281                 {
14282                   tree realret = ret;
14283                   if (TREE_CODE (ret) == NOP_EXPR)
14284                     realret = TREE_OPERAND (ret, 0);
14285                   if (CAN_HAVE_LOCATION_P (realret)
14286                       && !EXPR_HAS_LOCATION (realret))
14287                     SET_EXPR_LOCATION (realret, loc);
14288                   return realret;
14289                 }
14290               return ret;
14291             }
14292         }
14293     }
14294   return NULL_TREE;
14295 }
14296
14297 /* Look up the function in builtin_decl that corresponds to DECL
14298    and set ASMSPEC as its user assembler name.  DECL must be a
14299    function decl that declares a builtin.  */
14300
14301 void
14302 set_builtin_user_assembler_name (tree decl, const char *asmspec)
14303 {
14304   tree builtin;
14305   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
14306               && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
14307               && asmspec != 0);
14308
14309   builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
14310   set_user_assembler_name (builtin, asmspec);
14311   switch (DECL_FUNCTION_CODE (decl))
14312     {
14313     case BUILT_IN_MEMCPY:
14314       init_block_move_fn (asmspec);
14315       memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
14316       break;
14317     case BUILT_IN_MEMSET:
14318       init_block_clear_fn (asmspec);
14319       memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
14320       break;
14321     case BUILT_IN_MEMMOVE:
14322       memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
14323       break;
14324     case BUILT_IN_MEMCMP:
14325       memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
14326       break;
14327     case BUILT_IN_ABORT:
14328       abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
14329       break;
14330     case BUILT_IN_FFS:
14331       if (INT_TYPE_SIZE < BITS_PER_WORD)
14332         {
14333           set_user_assembler_libfunc ("ffs", asmspec);
14334           set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
14335                                                        MODE_INT, 0), "ffs");
14336         }
14337       break;
14338     default:
14339       break;
14340     }
14341 }
14342
14343 /* Return true if DECL is a builtin that expands to a constant or similarly
14344    simple code.  */
14345 bool
14346 is_simple_builtin (tree decl)
14347 {
14348   if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14349     switch (DECL_FUNCTION_CODE (decl))
14350       {
14351         /* Builtins that expand to constants.  */
14352       case BUILT_IN_CONSTANT_P:
14353       case BUILT_IN_EXPECT:
14354       case BUILT_IN_OBJECT_SIZE:
14355       case BUILT_IN_UNREACHABLE:
14356         /* Simple register moves or loads from stack.  */
14357       case BUILT_IN_ASSUME_ALIGNED:
14358       case BUILT_IN_RETURN_ADDRESS:
14359       case BUILT_IN_EXTRACT_RETURN_ADDR:
14360       case BUILT_IN_FROB_RETURN_ADDR:
14361       case BUILT_IN_RETURN:
14362       case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
14363       case BUILT_IN_FRAME_ADDRESS:
14364       case BUILT_IN_VA_END:
14365       case BUILT_IN_STACK_SAVE:
14366       case BUILT_IN_STACK_RESTORE:
14367         /* Exception state returns or moves registers around.  */
14368       case BUILT_IN_EH_FILTER:
14369       case BUILT_IN_EH_POINTER:
14370       case BUILT_IN_EH_COPY_VALUES:
14371         return true;
14372
14373       default:
14374         return false;
14375       }
14376
14377   return false;
14378 }
14379
14380 /* Return true if DECL is a builtin that is not expensive, i.e., they are
14381    most probably expanded inline into reasonably simple code.  This is a
14382    superset of is_simple_builtin.  */
14383 bool
14384 is_inexpensive_builtin (tree decl)
14385 {
14386   if (!decl)
14387     return false;
14388   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
14389     return true;
14390   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14391     switch (DECL_FUNCTION_CODE (decl))
14392       {
14393       case BUILT_IN_ABS:
14394       case BUILT_IN_ALLOCA:
14395       case BUILT_IN_ALLOCA_WITH_ALIGN:
14396       case BUILT_IN_BSWAP16:
14397       case BUILT_IN_BSWAP32:
14398       case BUILT_IN_BSWAP64:
14399       case BUILT_IN_CLZ:
14400       case BUILT_IN_CLZIMAX:
14401       case BUILT_IN_CLZL:
14402       case BUILT_IN_CLZLL:
14403       case BUILT_IN_CTZ:
14404       case BUILT_IN_CTZIMAX:
14405       case BUILT_IN_CTZL:
14406       case BUILT_IN_CTZLL:
14407       case BUILT_IN_FFS:
14408       case BUILT_IN_FFSIMAX:
14409       case BUILT_IN_FFSL:
14410       case BUILT_IN_FFSLL:
14411       case BUILT_IN_IMAXABS:
14412       case BUILT_IN_FINITE:
14413       case BUILT_IN_FINITEF:
14414       case BUILT_IN_FINITEL:
14415       case BUILT_IN_FINITED32:
14416       case BUILT_IN_FINITED64:
14417       case BUILT_IN_FINITED128:
14418       case BUILT_IN_FPCLASSIFY:
14419       case BUILT_IN_ISFINITE:
14420       case BUILT_IN_ISINF_SIGN:
14421       case BUILT_IN_ISINF:
14422       case BUILT_IN_ISINFF:
14423       case BUILT_IN_ISINFL:
14424       case BUILT_IN_ISINFD32:
14425       case BUILT_IN_ISINFD64:
14426       case BUILT_IN_ISINFD128:
14427       case BUILT_IN_ISNAN:
14428       case BUILT_IN_ISNANF:
14429       case BUILT_IN_ISNANL:
14430       case BUILT_IN_ISNAND32:
14431       case BUILT_IN_ISNAND64:
14432       case BUILT_IN_ISNAND128:
14433       case BUILT_IN_ISNORMAL:
14434       case BUILT_IN_ISGREATER:
14435       case BUILT_IN_ISGREATEREQUAL:
14436       case BUILT_IN_ISLESS:
14437       case BUILT_IN_ISLESSEQUAL:
14438       case BUILT_IN_ISLESSGREATER:
14439       case BUILT_IN_ISUNORDERED:
14440       case BUILT_IN_VA_ARG_PACK:
14441       case BUILT_IN_VA_ARG_PACK_LEN:
14442       case BUILT_IN_VA_COPY:
14443       case BUILT_IN_TRAP:
14444       case BUILT_IN_SAVEREGS:
14445       case BUILT_IN_POPCOUNTL:
14446       case BUILT_IN_POPCOUNTLL:
14447       case BUILT_IN_POPCOUNTIMAX:
14448       case BUILT_IN_POPCOUNT:
14449       case BUILT_IN_PARITYL:
14450       case BUILT_IN_PARITYLL:
14451       case BUILT_IN_PARITYIMAX:
14452       case BUILT_IN_PARITY:
14453       case BUILT_IN_LABS:
14454       case BUILT_IN_LLABS:
14455       case BUILT_IN_PREFETCH:
14456         return true;
14457
14458       default:
14459         return is_simple_builtin (decl);
14460       }
14461
14462   return false;
14463 }