builtins.c (expand_builtin_init_trampoline): Use set_mem_attributes.
[platform/upstream/gcc.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
4    2012 Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "realmpfr.h"
30 #include "gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
47 #include "basic-block.h"
48 #include "tree-mudflap.h"
49 #include "tree-flow.h"
50 #include "value-prof.h"
51 #include "diagnostic-core.h"
52 #include "builtins.h"
53
54
55 #ifndef PAD_VARARGS_DOWN
56 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
57 #endif
58 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
59
60 struct target_builtins default_target_builtins;
61 #if SWITCHABLE_TARGET
62 struct target_builtins *this_target_builtins = &default_target_builtins;
63 #endif
64
65 /* Define the names of the builtin function types and codes.  */
66 const char *const built_in_class_names[4]
67   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
69 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
70 const char * built_in_names[(int) END_BUILTINS] =
71 {
72 #include "builtins.def"
73 };
74 #undef DEF_BUILTIN
75
76 /* Setup an array of _DECL trees, make sure each element is
77    initialized to NULL_TREE.  */
78 builtin_info_type builtin_info;
79
80 static const char *c_getstr (tree);
81 static rtx c_readstr (const char *, enum machine_mode);
82 static int target_char_cast (tree, char *);
83 static rtx get_memory_rtx (tree, tree);
84 static int apply_args_size (void);
85 static int apply_result_size (void);
86 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
87 static rtx result_vector (int, rtx);
88 #endif
89 static void expand_builtin_update_setjmp_buf (rtx);
90 static void expand_builtin_prefetch (tree);
91 static rtx expand_builtin_apply_args (void);
92 static rtx expand_builtin_apply_args_1 (void);
93 static rtx expand_builtin_apply (rtx, rtx, rtx);
94 static void expand_builtin_return (rtx);
95 static enum type_class type_to_class (tree);
96 static rtx expand_builtin_classify_type (tree);
97 static void expand_errno_check (tree, rtx);
98 static rtx expand_builtin_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
101 static rtx expand_builtin_mathfn_ternary (tree, rtx, rtx);
102 static rtx expand_builtin_interclass_mathfn (tree, rtx);
103 static rtx expand_builtin_sincos (tree);
104 static rtx expand_builtin_cexpi (tree, rtx);
105 static rtx expand_builtin_int_roundingfn (tree, rtx);
106 static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
107 static rtx expand_builtin_next_arg (void);
108 static rtx expand_builtin_va_start (tree);
109 static rtx expand_builtin_va_end (tree);
110 static rtx expand_builtin_va_copy (tree);
111 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcmp (tree, rtx);
113 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
114 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
115 static rtx expand_builtin_memcpy (tree, rtx);
116 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx,
118                                         enum machine_mode, int);
119 static rtx expand_builtin_strcpy (tree, rtx);
120 static rtx expand_builtin_strcpy_args (tree, tree, rtx);
121 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_strncpy (tree, rtx);
123 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
124 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
125 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
126 static rtx expand_builtin_bzero (tree);
127 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_alloca (tree, bool);
129 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
130 static rtx expand_builtin_frame_address (tree, tree);
131 static tree stabilize_va_list_loc (location_t, tree, int);
132 static rtx expand_builtin_expect (tree, rtx);
133 static tree fold_builtin_constant_p (tree);
134 static tree fold_builtin_expect (location_t, tree, tree);
135 static tree fold_builtin_classify_type (tree);
136 static tree fold_builtin_strlen (location_t, tree, tree);
137 static tree fold_builtin_inf (location_t, tree, int);
138 static tree fold_builtin_nan (tree, tree, int);
139 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
140 static bool validate_arg (const_tree, enum tree_code code);
141 static bool integer_valued_real_p (tree);
142 static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
143 static bool readonly_data_expr (tree);
144 static rtx expand_builtin_fabs (tree, rtx, rtx);
145 static rtx expand_builtin_signbit (tree, rtx);
146 static tree fold_builtin_sqrt (location_t, tree, tree);
147 static tree fold_builtin_cbrt (location_t, tree, tree);
148 static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
149 static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
150 static tree fold_builtin_cos (location_t, tree, tree, tree);
151 static tree fold_builtin_cosh (location_t, tree, tree, tree);
152 static tree fold_builtin_tan (tree, tree);
153 static tree fold_builtin_trunc (location_t, tree, tree);
154 static tree fold_builtin_floor (location_t, tree, tree);
155 static tree fold_builtin_ceil (location_t, tree, tree);
156 static tree fold_builtin_round (location_t, tree, tree);
157 static tree fold_builtin_int_roundingfn (location_t, tree, tree);
158 static tree fold_builtin_bitop (tree, tree);
159 static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
160 static tree fold_builtin_strchr (location_t, tree, tree, tree);
161 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
162 static tree fold_builtin_memcmp (location_t, tree, tree, tree);
163 static tree fold_builtin_strcmp (location_t, tree, tree);
164 static tree fold_builtin_strncmp (location_t, tree, tree, tree);
165 static tree fold_builtin_signbit (location_t, tree, tree);
166 static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
167 static tree fold_builtin_isascii (location_t, tree);
168 static tree fold_builtin_toascii (location_t, tree);
169 static tree fold_builtin_isdigit (location_t, tree);
170 static tree fold_builtin_fabs (location_t, tree, tree);
171 static tree fold_builtin_abs (location_t, tree, tree);
172 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
173                                         enum tree_code);
174 static tree fold_builtin_n (location_t, tree, tree *, int, bool);
175 static tree fold_builtin_0 (location_t, tree, bool);
176 static tree fold_builtin_1 (location_t, tree, tree, bool);
177 static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
178 static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
179 static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
180 static tree fold_builtin_varargs (location_t, tree, tree, bool);
181
182 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
183 static tree fold_builtin_strstr (location_t, tree, tree, tree);
184 static tree fold_builtin_strrchr (location_t, tree, tree, tree);
185 static tree fold_builtin_strcat (location_t, tree, tree);
186 static tree fold_builtin_strncat (location_t, tree, tree, tree);
187 static tree fold_builtin_strspn (location_t, tree, tree);
188 static tree fold_builtin_strcspn (location_t, tree, tree);
189 static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
190 static tree fold_builtin_snprintf (location_t, tree, tree, tree, tree, int);
191
192 static rtx expand_builtin_object_size (tree);
193 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
194                                       enum built_in_function);
195 static void maybe_emit_chk_warning (tree, enum built_in_function);
196 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
197 static void maybe_emit_free_warning (tree);
198 static tree fold_builtin_object_size (tree, tree);
199 static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
200 static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
201 static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
202 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
203 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
204                                   enum built_in_function);
205 static bool init_target_chars (void);
206
207 static unsigned HOST_WIDE_INT target_newline;
208 static unsigned HOST_WIDE_INT target_percent;
209 static unsigned HOST_WIDE_INT target_c;
210 static unsigned HOST_WIDE_INT target_s;
211 static char target_percent_c[3];
212 static char target_percent_s[3];
213 static char target_percent_s_newline[4];
214 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
215                           const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
216 static tree do_mpfr_arg2 (tree, tree, tree,
217                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
218 static tree do_mpfr_arg3 (tree, tree, tree, tree,
219                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
220 static tree do_mpfr_sincos (tree, tree, tree);
221 static tree do_mpfr_bessel_n (tree, tree, tree,
222                               int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
223                               const REAL_VALUE_TYPE *, bool);
224 static tree do_mpfr_remquo (tree, tree, tree);
225 static tree do_mpfr_lgamma_r (tree, tree, tree);
226 static void expand_builtin_sync_synchronize (void);
227
228 /* Return true if NAME starts with __builtin_ or __sync_.  */
229
230 static bool
231 is_builtin_name (const char *name)
232 {
233   if (strncmp (name, "__builtin_", 10) == 0)
234     return true;
235   if (strncmp (name, "__sync_", 7) == 0)
236     return true;
237   if (strncmp (name, "__atomic_", 9) == 0)
238     return true;
239   return false;
240 }
241
242
243 /* Return true if DECL is a function symbol representing a built-in.  */
244
245 bool
246 is_builtin_fn (tree decl)
247 {
248   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
249 }
250
251
252 /* Return true if NODE should be considered for inline expansion regardless
253    of the optimization level.  This means whenever a function is invoked with
254    its "internal" name, which normally contains the prefix "__builtin".  */
255
256 static bool
257 called_as_built_in (tree node)
258 {
259   /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
260      we want the name used to call the function, not the name it
261      will have. */
262   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
263   return is_builtin_name (name);
264 }
265
266 /* Compute values M and N such that M divides (address of EXP - N) and such
267    that N < M.  If these numbers can be determined, store M in alignp and N in
268    *BITPOSP and return true.  Otherwise return false and store BITS_PER_UNIT to
269    *alignp and any bit-offset to *bitposp.
270
271    Note that the address (and thus the alignment) computed here is based
272    on the address to which a symbol resolves, whereas DECL_ALIGN is based
273    on the address at which an object is actually located.  These two
274    addresses are not always the same.  For example, on ARM targets,
275    the address &foo of a Thumb function foo() has the lowest bit set,
276    whereas foo() itself starts on an even address.
277
278    If ADDR_P is true we are taking the address of the memory reference EXP
279    and thus cannot rely on the access taking place.  */
280
281 static bool
282 get_object_alignment_2 (tree exp, unsigned int *alignp,
283                         unsigned HOST_WIDE_INT *bitposp, bool addr_p)
284 {
285   HOST_WIDE_INT bitsize, bitpos;
286   tree offset;
287   enum machine_mode mode;
288   int unsignedp, volatilep;
289   unsigned int inner, align = BITS_PER_UNIT;
290   bool known_alignment = false;
291
292   /* Get the innermost object and the constant (bitpos) and possibly
293      variable (offset) offset of the access.  */
294   exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
295                              &mode, &unsignedp, &volatilep, true);
296
297   /* Extract alignment information from the innermost object and
298      possibly adjust bitpos and offset.  */
299   if (TREE_CODE (exp) == FUNCTION_DECL)
300     {
301       /* Function addresses can encode extra information besides their
302          alignment.  However, if TARGET_PTRMEMFUNC_VBIT_LOCATION
303          allows the low bit to be used as a virtual bit, we know
304          that the address itself must be at least 2-byte aligned.  */
305       if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
306         align = 2 * BITS_PER_UNIT;
307     }
308   else if (TREE_CODE (exp) == LABEL_DECL)
309     ;
310   else if (TREE_CODE (exp) == CONST_DECL)
311     {
312       /* The alignment of a CONST_DECL is determined by its initializer.  */
313       exp = DECL_INITIAL (exp);
314       align = TYPE_ALIGN (TREE_TYPE (exp));
315 #ifdef CONSTANT_ALIGNMENT
316       if (CONSTANT_CLASS_P (exp))
317         align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
318 #endif
319       known_alignment = true;
320     }
321   else if (DECL_P (exp))
322     {
323       align = DECL_ALIGN (exp);
324       known_alignment = true;
325     }
326   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
327     {
328       align = TYPE_ALIGN (TREE_TYPE (exp));
329     }
330   else if (TREE_CODE (exp) == INDIRECT_REF
331            || TREE_CODE (exp) == MEM_REF
332            || TREE_CODE (exp) == TARGET_MEM_REF)
333     {
334       tree addr = TREE_OPERAND (exp, 0);
335       unsigned ptr_align;
336       unsigned HOST_WIDE_INT ptr_bitpos;
337
338       if (TREE_CODE (addr) == BIT_AND_EXPR
339           && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
340         {
341           align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
342                     & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
343           align *= BITS_PER_UNIT;
344           addr = TREE_OPERAND (addr, 0);
345         }
346
347       known_alignment
348         = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos);
349       align = MAX (ptr_align, align);
350
351       /* The alignment of the pointer operand in a TARGET_MEM_REF
352          has to take the variable offset parts into account.  */
353       if (TREE_CODE (exp) == TARGET_MEM_REF)
354         {
355           if (TMR_INDEX (exp))
356             {
357               unsigned HOST_WIDE_INT step = 1;
358               if (TMR_STEP (exp))
359                 step = TREE_INT_CST_LOW (TMR_STEP (exp));
360               align = MIN (align, (step & -step) * BITS_PER_UNIT);
361             }
362           if (TMR_INDEX2 (exp))
363             align = BITS_PER_UNIT;
364           known_alignment = false;
365         }
366
367       /* When EXP is an actual memory reference then we can use
368          TYPE_ALIGN of a pointer indirection to derive alignment.
369          Do so only if get_pointer_alignment_1 did not reveal absolute
370          alignment knowledge and if using that alignment would
371          improve the situation.  */
372       if (!addr_p && !known_alignment
373           && TYPE_ALIGN (TREE_TYPE (exp)) > align)
374         align = TYPE_ALIGN (TREE_TYPE (exp));
375       else
376         {
377           /* Else adjust bitpos accordingly.  */
378           bitpos += ptr_bitpos;
379           if (TREE_CODE (exp) == MEM_REF
380               || TREE_CODE (exp) == TARGET_MEM_REF)
381             bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
382         }
383     }
384   else if (TREE_CODE (exp) == STRING_CST)
385     {
386       /* STRING_CST are the only constant objects we allow to be not
387          wrapped inside a CONST_DECL.  */
388       align = TYPE_ALIGN (TREE_TYPE (exp));
389 #ifdef CONSTANT_ALIGNMENT
390       if (CONSTANT_CLASS_P (exp))
391         align = (unsigned) CONSTANT_ALIGNMENT (exp, align);
392 #endif
393       known_alignment = true;
394     }
395
396   /* If there is a non-constant offset part extract the maximum
397      alignment that can prevail.  */
398   inner = ~0U;
399   while (offset)
400     {
401       tree next_offset;
402
403       if (TREE_CODE (offset) == PLUS_EXPR)
404         {
405           next_offset = TREE_OPERAND (offset, 0);
406           offset = TREE_OPERAND (offset, 1);
407         }
408       else
409         next_offset = NULL;
410       if (host_integerp (offset, 1))
411         {
412           /* Any overflow in calculating offset_bits won't change
413              the alignment.  */
414           unsigned offset_bits
415             = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
416
417           if (offset_bits)
418             inner = MIN (inner, (offset_bits & -offset_bits));
419         }
420       else if (TREE_CODE (offset) == MULT_EXPR
421                && host_integerp (TREE_OPERAND (offset, 1), 1))
422         {
423           /* Any overflow in calculating offset_factor won't change
424              the alignment.  */
425           unsigned offset_factor
426             = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
427                * BITS_PER_UNIT);
428
429           if (offset_factor)
430             inner = MIN (inner, (offset_factor & -offset_factor));
431         }
432       else
433         {
434           inner = MIN (inner, BITS_PER_UNIT);
435           break;
436         }
437       offset = next_offset;
438     }
439   /* Alignment is innermost object alignment adjusted by the constant
440      and non-constant offset parts.  */
441   align = MIN (align, inner);
442
443   *alignp = align;
444   *bitposp = bitpos & (*alignp - 1);
445   return known_alignment;
446 }
447
448 /* For a memory reference expression EXP compute values M and N such that M
449    divides (&EXP - N) and such that N < M.  If these numbers can be determined,
450    store M in alignp and N in *BITPOSP and return true.  Otherwise return false
451    and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp.  */
452
453 bool
454 get_object_alignment_1 (tree exp, unsigned int *alignp,
455                         unsigned HOST_WIDE_INT *bitposp)
456 {
457   return get_object_alignment_2 (exp, alignp, bitposp, false);
458 }
459
460 /* Return the alignment in bits of EXP, an object.  */
461
462 unsigned int
463 get_object_alignment (tree exp)
464 {
465   unsigned HOST_WIDE_INT bitpos = 0;
466   unsigned int align;
467
468   get_object_alignment_1 (exp, &align, &bitpos);
469
470   /* align and bitpos now specify known low bits of the pointer.
471      ptr & (align - 1) == bitpos.  */
472
473   if (bitpos != 0)
474     align = (bitpos & -bitpos);
475   return align;
476 }
477
478 /* For a pointer valued expression EXP compute values M and N such that M
479    divides (EXP - N) and such that N < M.  If these numbers can be determined,
480    store M in alignp and N in *BITPOSP and return true.  Return false if
481    the results are just a conservative approximation.
482
483    If EXP is not a pointer, false is returned too.  */
484
485 bool
486 get_pointer_alignment_1 (tree exp, unsigned int *alignp,
487                          unsigned HOST_WIDE_INT *bitposp)
488 {
489   STRIP_NOPS (exp);
490
491   if (TREE_CODE (exp) == ADDR_EXPR)
492     return get_object_alignment_2 (TREE_OPERAND (exp, 0),
493                                    alignp, bitposp, true);
494   else if (TREE_CODE (exp) == SSA_NAME
495            && POINTER_TYPE_P (TREE_TYPE (exp)))
496     {
497       unsigned int ptr_align, ptr_misalign;
498       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
499
500       if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
501         {
502           *bitposp = ptr_misalign * BITS_PER_UNIT;
503           *alignp = ptr_align * BITS_PER_UNIT;
504           /* We cannot really tell whether this result is an approximation.  */
505           return true;
506         }
507       else
508         {
509           *bitposp = 0;
510           *alignp = BITS_PER_UNIT;
511           return false;
512         }
513     }
514   else if (TREE_CODE (exp) == INTEGER_CST)
515     {
516       *alignp = BIGGEST_ALIGNMENT;
517       *bitposp = ((TREE_INT_CST_LOW (exp) * BITS_PER_UNIT)
518                   & (BIGGEST_ALIGNMENT - 1));
519       return true;
520     }
521
522   *bitposp = 0;
523   *alignp = BITS_PER_UNIT;
524   return false;
525 }
526
527 /* Return the alignment in bits of EXP, a pointer valued expression.
528    The alignment returned is, by default, the alignment of the thing that
529    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
530
531    Otherwise, look at the expression to see if we can do better, i.e., if the
532    expression is actually pointing at an object whose alignment is tighter.  */
533
534 unsigned int
535 get_pointer_alignment (tree exp)
536 {
537   unsigned HOST_WIDE_INT bitpos = 0;
538   unsigned int align;
539
540   get_pointer_alignment_1 (exp, &align, &bitpos);
541
542   /* align and bitpos now specify known low bits of the pointer.
543      ptr & (align - 1) == bitpos.  */
544
545   if (bitpos != 0)
546     align = (bitpos & -bitpos);
547
548   return align;
549 }
550
551 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
552    way, because it could contain a zero byte in the middle.
553    TREE_STRING_LENGTH is the size of the character array, not the string.
554
555    ONLY_VALUE should be nonzero if the result is not going to be emitted
556    into the instruction stream and zero if it is going to be expanded.
557    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
558    is returned, otherwise NULL, since
559    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
560    evaluate the side-effects.
561
562    The value returned is of type `ssizetype'.
563
564    Unfortunately, string_constant can't access the values of const char
565    arrays with initializers, so neither can we do so here.  */
566
567 tree
568 c_strlen (tree src, int only_value)
569 {
570   tree offset_node;
571   HOST_WIDE_INT offset;
572   int max;
573   const char *ptr;
574   location_t loc;
575
576   STRIP_NOPS (src);
577   if (TREE_CODE (src) == COND_EXPR
578       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
579     {
580       tree len1, len2;
581
582       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
583       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
584       if (tree_int_cst_equal (len1, len2))
585         return len1;
586     }
587
588   if (TREE_CODE (src) == COMPOUND_EXPR
589       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
590     return c_strlen (TREE_OPERAND (src, 1), only_value);
591
592   loc = EXPR_LOC_OR_HERE (src);
593
594   src = string_constant (src, &offset_node);
595   if (src == 0)
596     return NULL_TREE;
597
598   max = TREE_STRING_LENGTH (src) - 1;
599   ptr = TREE_STRING_POINTER (src);
600
601   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
602     {
603       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
604          compute the offset to the following null if we don't know where to
605          start searching for it.  */
606       int i;
607
608       for (i = 0; i < max; i++)
609         if (ptr[i] == 0)
610           return NULL_TREE;
611
612       /* We don't know the starting offset, but we do know that the string
613          has no internal zero bytes.  We can assume that the offset falls
614          within the bounds of the string; otherwise, the programmer deserves
615          what he gets.  Subtract the offset from the length of the string,
616          and return that.  This would perhaps not be valid if we were dealing
617          with named arrays in addition to literal string constants.  */
618
619       return size_diffop_loc (loc, size_int (max), offset_node);
620     }
621
622   /* We have a known offset into the string.  Start searching there for
623      a null character if we can represent it as a single HOST_WIDE_INT.  */
624   if (offset_node == 0)
625     offset = 0;
626   else if (! host_integerp (offset_node, 0))
627     offset = -1;
628   else
629     offset = tree_low_cst (offset_node, 0);
630
631   /* If the offset is known to be out of bounds, warn, and call strlen at
632      runtime.  */
633   if (offset < 0 || offset > max)
634     {
635      /* Suppress multiple warnings for propagated constant strings.  */
636       if (! TREE_NO_WARNING (src))
637         {
638           warning_at (loc, 0, "offset outside bounds of constant string");
639           TREE_NO_WARNING (src) = 1;
640         }
641       return NULL_TREE;
642     }
643
644   /* Use strlen to search for the first zero byte.  Since any strings
645      constructed with build_string will have nulls appended, we win even
646      if we get handed something like (char[4])"abcd".
647
648      Since OFFSET is our starting index into the string, no further
649      calculation is needed.  */
650   return ssize_int (strlen (ptr + offset));
651 }
652
653 /* Return a char pointer for a C string if it is a string constant
654    or sum of string constant and integer constant.  */
655
656 static const char *
657 c_getstr (tree src)
658 {
659   tree offset_node;
660
661   src = string_constant (src, &offset_node);
662   if (src == 0)
663     return 0;
664
665   if (offset_node == 0)
666     return TREE_STRING_POINTER (src);
667   else if (!host_integerp (offset_node, 1)
668            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
669     return 0;
670
671   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
672 }
673
674 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
675    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
676
677 static rtx
678 c_readstr (const char *str, enum machine_mode mode)
679 {
680   HOST_WIDE_INT c[2];
681   HOST_WIDE_INT ch;
682   unsigned int i, j;
683
684   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
685
686   c[0] = 0;
687   c[1] = 0;
688   ch = 1;
689   for (i = 0; i < GET_MODE_SIZE (mode); i++)
690     {
691       j = i;
692       if (WORDS_BIG_ENDIAN)
693         j = GET_MODE_SIZE (mode) - i - 1;
694       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
695           && GET_MODE_SIZE (mode) >= UNITS_PER_WORD)
696         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
697       j *= BITS_PER_UNIT;
698       gcc_assert (j < HOST_BITS_PER_DOUBLE_INT);
699
700       if (ch)
701         ch = (unsigned char) str[i];
702       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
703     }
704   return immed_double_const (c[0], c[1], mode);
705 }
706
707 /* Cast a target constant CST to target CHAR and if that value fits into
708    host char type, return zero and put that value into variable pointed to by
709    P.  */
710
711 static int
712 target_char_cast (tree cst, char *p)
713 {
714   unsigned HOST_WIDE_INT val, hostval;
715
716   if (TREE_CODE (cst) != INTEGER_CST
717       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
718     return 1;
719
720   val = TREE_INT_CST_LOW (cst);
721   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
722     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
723
724   hostval = val;
725   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
726     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
727
728   if (val != hostval)
729     return 1;
730
731   *p = hostval;
732   return 0;
733 }
734
735 /* Similar to save_expr, but assumes that arbitrary code is not executed
736    in between the multiple evaluations.  In particular, we assume that a
737    non-addressable local variable will not be modified.  */
738
739 static tree
740 builtin_save_expr (tree exp)
741 {
742   if (TREE_CODE (exp) == SSA_NAME
743       || (TREE_ADDRESSABLE (exp) == 0
744           && (TREE_CODE (exp) == PARM_DECL
745               || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp)))))
746     return exp;
747
748   return save_expr (exp);
749 }
750
751 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
752    times to get the address of either a higher stack frame, or a return
753    address located within it (depending on FNDECL_CODE).  */
754
755 static rtx
756 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
757 {
758   int i;
759
760 #ifdef INITIAL_FRAME_ADDRESS_RTX
761   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
762 #else
763   rtx tem;
764
765   /* For a zero count with __builtin_return_address, we don't care what
766      frame address we return, because target-specific definitions will
767      override us.  Therefore frame pointer elimination is OK, and using
768      the soft frame pointer is OK.
769
770      For a nonzero count, or a zero count with __builtin_frame_address,
771      we require a stable offset from the current frame pointer to the
772      previous one, so we must use the hard frame pointer, and
773      we must disable frame pointer elimination.  */
774   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
775     tem = frame_pointer_rtx;
776   else
777     {
778       tem = hard_frame_pointer_rtx;
779
780       /* Tell reload not to eliminate the frame pointer.  */
781       crtl->accesses_prior_frames = 1;
782     }
783 #endif
784
785   /* Some machines need special handling before we can access
786      arbitrary frames.  For example, on the SPARC, we must first flush
787      all register windows to the stack.  */
788 #ifdef SETUP_FRAME_ADDRESSES
789   if (count > 0)
790     SETUP_FRAME_ADDRESSES ();
791 #endif
792
793   /* On the SPARC, the return address is not in the frame, it is in a
794      register.  There is no way to access it off of the current frame
795      pointer, but it can be accessed off the previous frame pointer by
796      reading the value from the register window save area.  */
797 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
798   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
799     count--;
800 #endif
801
802   /* Scan back COUNT frames to the specified frame.  */
803   for (i = 0; i < count; i++)
804     {
805       /* Assume the dynamic chain pointer is in the word that the
806          frame address points to, unless otherwise specified.  */
807 #ifdef DYNAMIC_CHAIN_ADDRESS
808       tem = DYNAMIC_CHAIN_ADDRESS (tem);
809 #endif
810       tem = memory_address (Pmode, tem);
811       tem = gen_frame_mem (Pmode, tem);
812       tem = copy_to_reg (tem);
813     }
814
815   /* For __builtin_frame_address, return what we've got.  But, on
816      the SPARC for example, we may have to add a bias.  */
817   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
818 #ifdef FRAME_ADDR_RTX
819     return FRAME_ADDR_RTX (tem);
820 #else
821     return tem;
822 #endif
823
824   /* For __builtin_return_address, get the return address from that frame.  */
825 #ifdef RETURN_ADDR_RTX
826   tem = RETURN_ADDR_RTX (count, tem);
827 #else
828   tem = memory_address (Pmode,
829                         plus_constant (Pmode, tem, GET_MODE_SIZE (Pmode)));
830   tem = gen_frame_mem (Pmode, tem);
831 #endif
832   return tem;
833 }
834
835 /* Alias set used for setjmp buffer.  */
836 static alias_set_type setjmp_alias_set = -1;
837
838 /* Construct the leading half of a __builtin_setjmp call.  Control will
839    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
840    exception handling code.  */
841
842 void
843 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
844 {
845   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
846   rtx stack_save;
847   rtx mem;
848
849   if (setjmp_alias_set == -1)
850     setjmp_alias_set = new_alias_set ();
851
852   buf_addr = convert_memory_address (Pmode, buf_addr);
853
854   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
855
856   /* We store the frame pointer and the address of receiver_label in
857      the buffer and use the rest of it for the stack save area, which
858      is machine-dependent.  */
859
860   mem = gen_rtx_MEM (Pmode, buf_addr);
861   set_mem_alias_set (mem, setjmp_alias_set);
862   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
863
864   mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
865                                            GET_MODE_SIZE (Pmode))),
866   set_mem_alias_set (mem, setjmp_alias_set);
867
868   emit_move_insn (validize_mem (mem),
869                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
870
871   stack_save = gen_rtx_MEM (sa_mode,
872                             plus_constant (Pmode, buf_addr,
873                                            2 * GET_MODE_SIZE (Pmode)));
874   set_mem_alias_set (stack_save, setjmp_alias_set);
875   emit_stack_save (SAVE_NONLOCAL, &stack_save);
876
877   /* If there is further processing to do, do it.  */
878 #ifdef HAVE_builtin_setjmp_setup
879   if (HAVE_builtin_setjmp_setup)
880     emit_insn (gen_builtin_setjmp_setup (buf_addr));
881 #endif
882
883   /* We have a nonlocal label.   */
884   cfun->has_nonlocal_label = 1;
885 }
886
887 /* Construct the trailing part of a __builtin_setjmp call.  This is
888    also called directly by the SJLJ exception handling code.  */
889
890 void
891 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
892 {
893   rtx chain;
894
895   /* Clobber the FP when we get here, so we have to make sure it's
896      marked as used by this function.  */
897   emit_use (hard_frame_pointer_rtx);
898
899   /* Mark the static chain as clobbered here so life information
900      doesn't get messed up for it.  */
901   chain = targetm.calls.static_chain (current_function_decl, true);
902   if (chain && REG_P (chain))
903     emit_clobber (chain);
904
905   /* Now put in the code to restore the frame pointer, and argument
906      pointer, if needed.  */
907 #ifdef HAVE_nonlocal_goto
908   if (! HAVE_nonlocal_goto)
909 #endif
910     {
911       emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
912       /* This might change the hard frame pointer in ways that aren't
913          apparent to early optimization passes, so force a clobber.  */
914       emit_clobber (hard_frame_pointer_rtx);
915     }
916
917 #if !HARD_FRAME_POINTER_IS_ARG_POINTER
918   if (fixed_regs[ARG_POINTER_REGNUM])
919     {
920 #ifdef ELIMINABLE_REGS
921       size_t i;
922       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
923
924       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
925         if (elim_regs[i].from == ARG_POINTER_REGNUM
926             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
927           break;
928
929       if (i == ARRAY_SIZE (elim_regs))
930 #endif
931         {
932           /* Now restore our arg pointer from the address at which it
933              was saved in our stack frame.  */
934           emit_move_insn (crtl->args.internal_arg_pointer,
935                           copy_to_reg (get_arg_pointer_save_area ()));
936         }
937     }
938 #endif
939
940 #ifdef HAVE_builtin_setjmp_receiver
941   if (HAVE_builtin_setjmp_receiver)
942     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
943   else
944 #endif
945 #ifdef HAVE_nonlocal_goto_receiver
946     if (HAVE_nonlocal_goto_receiver)
947       emit_insn (gen_nonlocal_goto_receiver ());
948     else
949 #endif
950       { /* Nothing */ }
951
952   /* We must not allow the code we just generated to be reordered by
953      scheduling.  Specifically, the update of the frame pointer must
954      happen immediately, not later.  Similarly, we must block
955      (frame-related) register values to be used across this code.  */
956   emit_insn (gen_blockage ());
957 }
958
959 /* __builtin_longjmp is passed a pointer to an array of five words (not
960    all will be used on all machines).  It operates similarly to the C
961    library function of the same name, but is more efficient.  Much of
962    the code below is copied from the handling of non-local gotos.  */
963
964 static void
965 expand_builtin_longjmp (rtx buf_addr, rtx value)
966 {
967   rtx fp, lab, stack, insn, last;
968   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
969
970   /* DRAP is needed for stack realign if longjmp is expanded to current
971      function  */
972   if (SUPPORTS_STACK_ALIGNMENT)
973     crtl->need_drap = true;
974
975   if (setjmp_alias_set == -1)
976     setjmp_alias_set = new_alias_set ();
977
978   buf_addr = convert_memory_address (Pmode, buf_addr);
979
980   buf_addr = force_reg (Pmode, buf_addr);
981
982   /* We require that the user must pass a second argument of 1, because
983      that is what builtin_setjmp will return.  */
984   gcc_assert (value == const1_rtx);
985
986   last = get_last_insn ();
987 #ifdef HAVE_builtin_longjmp
988   if (HAVE_builtin_longjmp)
989     emit_insn (gen_builtin_longjmp (buf_addr));
990   else
991 #endif
992     {
993       fp = gen_rtx_MEM (Pmode, buf_addr);
994       lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, buf_addr,
995                                                GET_MODE_SIZE (Pmode)));
996
997       stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, buf_addr,
998                                                    2 * GET_MODE_SIZE (Pmode)));
999       set_mem_alias_set (fp, setjmp_alias_set);
1000       set_mem_alias_set (lab, setjmp_alias_set);
1001       set_mem_alias_set (stack, setjmp_alias_set);
1002
1003       /* Pick up FP, label, and SP from the block and jump.  This code is
1004          from expand_goto in stmt.c; see there for detailed comments.  */
1005 #ifdef HAVE_nonlocal_goto
1006       if (HAVE_nonlocal_goto)
1007         /* We have to pass a value to the nonlocal_goto pattern that will
1008            get copied into the static_chain pointer, but it does not matter
1009            what that value is, because builtin_setjmp does not use it.  */
1010         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
1011       else
1012 #endif
1013         {
1014           lab = copy_to_reg (lab);
1015
1016           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1017           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1018
1019           emit_move_insn (hard_frame_pointer_rtx, fp);
1020           emit_stack_restore (SAVE_NONLOCAL, stack);
1021
1022           emit_use (hard_frame_pointer_rtx);
1023           emit_use (stack_pointer_rtx);
1024           emit_indirect_jump (lab);
1025         }
1026     }
1027
1028   /* Search backwards and mark the jump insn as a non-local goto.
1029      Note that this precludes the use of __builtin_longjmp to a
1030      __builtin_setjmp target in the same function.  However, we've
1031      already cautioned the user that these functions are for
1032      internal exception handling use only.  */
1033   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1034     {
1035       gcc_assert (insn != last);
1036
1037       if (JUMP_P (insn))
1038         {
1039           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1040           break;
1041         }
1042       else if (CALL_P (insn))
1043         break;
1044     }
1045 }
1046
1047 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
1048    and the address of the save area.  */
1049
1050 static rtx
1051 expand_builtin_nonlocal_goto (tree exp)
1052 {
1053   tree t_label, t_save_area;
1054   rtx r_label, r_save_area, r_fp, r_sp, insn;
1055
1056   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
1057     return NULL_RTX;
1058
1059   t_label = CALL_EXPR_ARG (exp, 0);
1060   t_save_area = CALL_EXPR_ARG (exp, 1);
1061
1062   r_label = expand_normal (t_label);
1063   r_label = convert_memory_address (Pmode, r_label);
1064   r_save_area = expand_normal (t_save_area);
1065   r_save_area = convert_memory_address (Pmode, r_save_area);
1066   /* Copy the address of the save location to a register just in case it was
1067      based on the frame pointer.   */
1068   r_save_area = copy_to_reg (r_save_area);
1069   r_fp = gen_rtx_MEM (Pmode, r_save_area);
1070   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
1071                       plus_constant (Pmode, r_save_area,
1072                                      GET_MODE_SIZE (Pmode)));
1073
1074   crtl->has_nonlocal_goto = 1;
1075
1076 #ifdef HAVE_nonlocal_goto
1077   /* ??? We no longer need to pass the static chain value, afaik.  */
1078   if (HAVE_nonlocal_goto)
1079     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
1080   else
1081 #endif
1082     {
1083       r_label = copy_to_reg (r_label);
1084
1085       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
1086       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
1087
1088       /* Restore frame pointer for containing function.  */
1089       emit_move_insn (hard_frame_pointer_rtx, r_fp);
1090       emit_stack_restore (SAVE_NONLOCAL, r_sp);
1091
1092       /* USE of hard_frame_pointer_rtx added for consistency;
1093          not clear if really needed.  */
1094       emit_use (hard_frame_pointer_rtx);
1095       emit_use (stack_pointer_rtx);
1096
1097       /* If the architecture is using a GP register, we must
1098          conservatively assume that the target function makes use of it.
1099          The prologue of functions with nonlocal gotos must therefore
1100          initialize the GP register to the appropriate value, and we
1101          must then make sure that this value is live at the point
1102          of the jump.  (Note that this doesn't necessarily apply
1103          to targets with a nonlocal_goto pattern; they are free
1104          to implement it in their own way.  Note also that this is
1105          a no-op if the GP register is a global invariant.)  */
1106       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
1107           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
1108         emit_use (pic_offset_table_rtx);
1109
1110       emit_indirect_jump (r_label);
1111     }
1112
1113   /* Search backwards to the jump insn and mark it as a
1114      non-local goto.  */
1115   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
1116     {
1117       if (JUMP_P (insn))
1118         {
1119           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
1120           break;
1121         }
1122       else if (CALL_P (insn))
1123         break;
1124     }
1125
1126   return const0_rtx;
1127 }
1128
1129 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
1130    (not all will be used on all machines) that was passed to __builtin_setjmp.
1131    It updates the stack pointer in that block to correspond to the current
1132    stack pointer.  */
1133
1134 static void
1135 expand_builtin_update_setjmp_buf (rtx buf_addr)
1136 {
1137   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1138   rtx stack_save
1139     = gen_rtx_MEM (sa_mode,
1140                    memory_address
1141                    (sa_mode,
1142                     plus_constant (Pmode, buf_addr,
1143                                    2 * GET_MODE_SIZE (Pmode))));
1144
1145   emit_stack_save (SAVE_NONLOCAL, &stack_save);
1146 }
1147
1148 /* Expand a call to __builtin_prefetch.  For a target that does not support
1149    data prefetch, evaluate the memory address argument in case it has side
1150    effects.  */
1151
1152 static void
1153 expand_builtin_prefetch (tree exp)
1154 {
1155   tree arg0, arg1, arg2;
1156   int nargs;
1157   rtx op0, op1, op2;
1158
1159   if (!validate_arglist (exp, POINTER_TYPE, 0))
1160     return;
1161
1162   arg0 = CALL_EXPR_ARG (exp, 0);
1163
1164   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1165      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1166      locality).  */
1167   nargs = call_expr_nargs (exp);
1168   if (nargs > 1)
1169     arg1 = CALL_EXPR_ARG (exp, 1);
1170   else
1171     arg1 = integer_zero_node;
1172   if (nargs > 2)
1173     arg2 = CALL_EXPR_ARG (exp, 2);
1174   else
1175     arg2 = integer_three_node;
1176
1177   /* Argument 0 is an address.  */
1178   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1179
1180   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1181   if (TREE_CODE (arg1) != INTEGER_CST)
1182     {
1183       error ("second argument to %<__builtin_prefetch%> must be a constant");
1184       arg1 = integer_zero_node;
1185     }
1186   op1 = expand_normal (arg1);
1187   /* Argument 1 must be either zero or one.  */
1188   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1189     {
1190       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1191                " using zero");
1192       op1 = const0_rtx;
1193     }
1194
1195   /* Argument 2 (locality) must be a compile-time constant int.  */
1196   if (TREE_CODE (arg2) != INTEGER_CST)
1197     {
1198       error ("third argument to %<__builtin_prefetch%> must be a constant");
1199       arg2 = integer_zero_node;
1200     }
1201   op2 = expand_normal (arg2);
1202   /* Argument 2 must be 0, 1, 2, or 3.  */
1203   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1204     {
1205       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1206       op2 = const0_rtx;
1207     }
1208
1209 #ifdef HAVE_prefetch
1210   if (HAVE_prefetch)
1211     {
1212       struct expand_operand ops[3];
1213
1214       create_address_operand (&ops[0], op0);
1215       create_integer_operand (&ops[1], INTVAL (op1));
1216       create_integer_operand (&ops[2], INTVAL (op2));
1217       if (maybe_expand_insn (CODE_FOR_prefetch, 3, ops))
1218         return;
1219     }
1220 #endif
1221
1222   /* Don't do anything with direct references to volatile memory, but
1223      generate code to handle other side effects.  */
1224   if (!MEM_P (op0) && side_effects_p (op0))
1225     emit_insn (op0);
1226 }
1227
1228 /* Get a MEM rtx for expression EXP which is the address of an operand
1229    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1230    the maximum length of the block of memory that might be accessed or
1231    NULL if unknown.  */
1232
1233 static rtx
1234 get_memory_rtx (tree exp, tree len)
1235 {
1236   tree orig_exp = exp;
1237   rtx addr, mem;
1238
1239   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1240      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1241   if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1242     exp = TREE_OPERAND (exp, 0);
1243
1244   addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1245   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1246
1247   /* Get an expression we can use to find the attributes to assign to MEM.
1248      First remove any nops.  */
1249   while (CONVERT_EXPR_P (exp)
1250          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1251     exp = TREE_OPERAND (exp, 0);
1252
1253   /* Build a MEM_REF representing the whole accessed area as a byte blob,
1254      (as builtin stringops may alias with anything).  */
1255   exp = fold_build2 (MEM_REF,
1256                      build_array_type (char_type_node,
1257                                        build_range_type (sizetype,
1258                                                          size_one_node, len)),
1259                      exp, build_int_cst (ptr_type_node, 0));
1260
1261   /* If the MEM_REF has no acceptable address, try to get the base object
1262      from the original address we got, and build an all-aliasing
1263      unknown-sized access to that one.  */
1264   if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0)))
1265     set_mem_attributes (mem, exp, 0);
1266   else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1267            && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0),
1268                                                      0))))
1269     {
1270       exp = build_fold_addr_expr (exp);
1271       exp = fold_build2 (MEM_REF,
1272                          build_array_type (char_type_node,
1273                                            build_range_type (sizetype,
1274                                                              size_zero_node,
1275                                                              NULL)),
1276                          exp, build_int_cst (ptr_type_node, 0));
1277       set_mem_attributes (mem, exp, 0);
1278     }
1279   set_mem_alias_set (mem, 0);
1280   return mem;
1281 }
1282 \f
1283 /* Built-in functions to perform an untyped call and return.  */
1284
1285 #define apply_args_mode \
1286   (this_target_builtins->x_apply_args_mode)
1287 #define apply_result_mode \
1288   (this_target_builtins->x_apply_result_mode)
1289
1290 /* Return the size required for the block returned by __builtin_apply_args,
1291    and initialize apply_args_mode.  */
1292
1293 static int
1294 apply_args_size (void)
1295 {
1296   static int size = -1;
1297   int align;
1298   unsigned int regno;
1299   enum machine_mode mode;
1300
1301   /* The values computed by this function never change.  */
1302   if (size < 0)
1303     {
1304       /* The first value is the incoming arg-pointer.  */
1305       size = GET_MODE_SIZE (Pmode);
1306
1307       /* The second value is the structure value address unless this is
1308          passed as an "invisible" first argument.  */
1309       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1310         size += GET_MODE_SIZE (Pmode);
1311
1312       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1313         if (FUNCTION_ARG_REGNO_P (regno))
1314           {
1315             mode = targetm.calls.get_raw_arg_mode (regno);
1316
1317             gcc_assert (mode != VOIDmode);
1318
1319             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1320             if (size % align != 0)
1321               size = CEIL (size, align) * align;
1322             size += GET_MODE_SIZE (mode);
1323             apply_args_mode[regno] = mode;
1324           }
1325         else
1326           {
1327             apply_args_mode[regno] = VOIDmode;
1328           }
1329     }
1330   return size;
1331 }
1332
1333 /* Return the size required for the block returned by __builtin_apply,
1334    and initialize apply_result_mode.  */
1335
1336 static int
1337 apply_result_size (void)
1338 {
1339   static int size = -1;
1340   int align, regno;
1341   enum machine_mode mode;
1342
1343   /* The values computed by this function never change.  */
1344   if (size < 0)
1345     {
1346       size = 0;
1347
1348       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1349         if (targetm.calls.function_value_regno_p (regno))
1350           {
1351             mode = targetm.calls.get_raw_result_mode (regno);
1352
1353             gcc_assert (mode != VOIDmode);
1354
1355             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1356             if (size % align != 0)
1357               size = CEIL (size, align) * align;
1358             size += GET_MODE_SIZE (mode);
1359             apply_result_mode[regno] = mode;
1360           }
1361         else
1362           apply_result_mode[regno] = VOIDmode;
1363
1364       /* Allow targets that use untyped_call and untyped_return to override
1365          the size so that machine-specific information can be stored here.  */
1366 #ifdef APPLY_RESULT_SIZE
1367       size = APPLY_RESULT_SIZE;
1368 #endif
1369     }
1370   return size;
1371 }
1372
1373 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1374 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1375    the result block is used to save the values; otherwise it is used to
1376    restore the values.  */
1377
1378 static rtx
1379 result_vector (int savep, rtx result)
1380 {
1381   int regno, size, align, nelts;
1382   enum machine_mode mode;
1383   rtx reg, mem;
1384   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1385
1386   size = nelts = 0;
1387   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1388     if ((mode = apply_result_mode[regno]) != VOIDmode)
1389       {
1390         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1391         if (size % align != 0)
1392           size = CEIL (size, align) * align;
1393         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1394         mem = adjust_address (result, mode, size);
1395         savevec[nelts++] = (savep
1396                             ? gen_rtx_SET (VOIDmode, mem, reg)
1397                             : gen_rtx_SET (VOIDmode, reg, mem));
1398         size += GET_MODE_SIZE (mode);
1399       }
1400   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1401 }
1402 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1403
1404 /* Save the state required to perform an untyped call with the same
1405    arguments as were passed to the current function.  */
1406
1407 static rtx
1408 expand_builtin_apply_args_1 (void)
1409 {
1410   rtx registers, tem;
1411   int size, align, regno;
1412   enum machine_mode mode;
1413   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1414
1415   /* Create a block where the arg-pointer, structure value address,
1416      and argument registers can be saved.  */
1417   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1418
1419   /* Walk past the arg-pointer and structure value address.  */
1420   size = GET_MODE_SIZE (Pmode);
1421   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1422     size += GET_MODE_SIZE (Pmode);
1423
1424   /* Save each register used in calling a function to the block.  */
1425   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1426     if ((mode = apply_args_mode[regno]) != VOIDmode)
1427       {
1428         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1429         if (size % align != 0)
1430           size = CEIL (size, align) * align;
1431
1432         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1433
1434         emit_move_insn (adjust_address (registers, mode, size), tem);
1435         size += GET_MODE_SIZE (mode);
1436       }
1437
1438   /* Save the arg pointer to the block.  */
1439   tem = copy_to_reg (crtl->args.internal_arg_pointer);
1440 #ifdef STACK_GROWS_DOWNWARD
1441   /* We need the pointer as the caller actually passed them to us, not
1442      as we might have pretended they were passed.  Make sure it's a valid
1443      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1444   tem
1445     = force_operand (plus_constant (Pmode, tem, crtl->args.pretend_args_size),
1446                      NULL_RTX);
1447 #endif
1448   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1449
1450   size = GET_MODE_SIZE (Pmode);
1451
1452   /* Save the structure value address unless this is passed as an
1453      "invisible" first argument.  */
1454   if (struct_incoming_value)
1455     {
1456       emit_move_insn (adjust_address (registers, Pmode, size),
1457                       copy_to_reg (struct_incoming_value));
1458       size += GET_MODE_SIZE (Pmode);
1459     }
1460
1461   /* Return the address of the block.  */
1462   return copy_addr_to_reg (XEXP (registers, 0));
1463 }
1464
1465 /* __builtin_apply_args returns block of memory allocated on
1466    the stack into which is stored the arg pointer, structure
1467    value address, static chain, and all the registers that might
1468    possibly be used in performing a function call.  The code is
1469    moved to the start of the function so the incoming values are
1470    saved.  */
1471
1472 static rtx
1473 expand_builtin_apply_args (void)
1474 {
1475   /* Don't do __builtin_apply_args more than once in a function.
1476      Save the result of the first call and reuse it.  */
1477   if (apply_args_value != 0)
1478     return apply_args_value;
1479   {
1480     /* When this function is called, it means that registers must be
1481        saved on entry to this function.  So we migrate the
1482        call to the first insn of this function.  */
1483     rtx temp;
1484     rtx seq;
1485
1486     start_sequence ();
1487     temp = expand_builtin_apply_args_1 ();
1488     seq = get_insns ();
1489     end_sequence ();
1490
1491     apply_args_value = temp;
1492
1493     /* Put the insns after the NOTE that starts the function.
1494        If this is inside a start_sequence, make the outer-level insn
1495        chain current, so the code is placed at the start of the
1496        function.  If internal_arg_pointer is a non-virtual pseudo,
1497        it needs to be placed after the function that initializes
1498        that pseudo.  */
1499     push_topmost_sequence ();
1500     if (REG_P (crtl->args.internal_arg_pointer)
1501         && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1502       emit_insn_before (seq, parm_birth_insn);
1503     else
1504       emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1505     pop_topmost_sequence ();
1506     return temp;
1507   }
1508 }
1509
1510 /* Perform an untyped call and save the state required to perform an
1511    untyped return of whatever value was returned by the given function.  */
1512
1513 static rtx
1514 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1515 {
1516   int size, align, regno;
1517   enum machine_mode mode;
1518   rtx incoming_args, result, reg, dest, src, call_insn;
1519   rtx old_stack_level = 0;
1520   rtx call_fusage = 0;
1521   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1522
1523   arguments = convert_memory_address (Pmode, arguments);
1524
1525   /* Create a block where the return registers can be saved.  */
1526   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1527
1528   /* Fetch the arg pointer from the ARGUMENTS block.  */
1529   incoming_args = gen_reg_rtx (Pmode);
1530   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1531 #ifndef STACK_GROWS_DOWNWARD
1532   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1533                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1534 #endif
1535
1536   /* Push a new argument block and copy the arguments.  Do not allow
1537      the (potential) memcpy call below to interfere with our stack
1538      manipulations.  */
1539   do_pending_stack_adjust ();
1540   NO_DEFER_POP;
1541
1542   /* Save the stack with nonlocal if available.  */
1543 #ifdef HAVE_save_stack_nonlocal
1544   if (HAVE_save_stack_nonlocal)
1545     emit_stack_save (SAVE_NONLOCAL, &old_stack_level);
1546   else
1547 #endif
1548     emit_stack_save (SAVE_BLOCK, &old_stack_level);
1549
1550   /* Allocate a block of memory onto the stack and copy the memory
1551      arguments to the outgoing arguments address.  We can pass TRUE
1552      as the 4th argument because we just saved the stack pointer
1553      and will restore it right after the call.  */
1554   allocate_dynamic_stack_space (argsize, 0, BIGGEST_ALIGNMENT, true);
1555
1556   /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1557      may have already set current_function_calls_alloca to true.
1558      current_function_calls_alloca won't be set if argsize is zero,
1559      so we have to guarantee need_drap is true here.  */
1560   if (SUPPORTS_STACK_ALIGNMENT)
1561     crtl->need_drap = true;
1562
1563   dest = virtual_outgoing_args_rtx;
1564 #ifndef STACK_GROWS_DOWNWARD
1565   if (CONST_INT_P (argsize))
1566     dest = plus_constant (Pmode, dest, -INTVAL (argsize));
1567   else
1568     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1569 #endif
1570   dest = gen_rtx_MEM (BLKmode, dest);
1571   set_mem_align (dest, PARM_BOUNDARY);
1572   src = gen_rtx_MEM (BLKmode, incoming_args);
1573   set_mem_align (src, PARM_BOUNDARY);
1574   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1575
1576   /* Refer to the argument block.  */
1577   apply_args_size ();
1578   arguments = gen_rtx_MEM (BLKmode, arguments);
1579   set_mem_align (arguments, PARM_BOUNDARY);
1580
1581   /* Walk past the arg-pointer and structure value address.  */
1582   size = GET_MODE_SIZE (Pmode);
1583   if (struct_value)
1584     size += GET_MODE_SIZE (Pmode);
1585
1586   /* Restore each of the registers previously saved.  Make USE insns
1587      for each of these registers for use in making the call.  */
1588   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1589     if ((mode = apply_args_mode[regno]) != VOIDmode)
1590       {
1591         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1592         if (size % align != 0)
1593           size = CEIL (size, align) * align;
1594         reg = gen_rtx_REG (mode, regno);
1595         emit_move_insn (reg, adjust_address (arguments, mode, size));
1596         use_reg (&call_fusage, reg);
1597         size += GET_MODE_SIZE (mode);
1598       }
1599
1600   /* Restore the structure value address unless this is passed as an
1601      "invisible" first argument.  */
1602   size = GET_MODE_SIZE (Pmode);
1603   if (struct_value)
1604     {
1605       rtx value = gen_reg_rtx (Pmode);
1606       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1607       emit_move_insn (struct_value, value);
1608       if (REG_P (struct_value))
1609         use_reg (&call_fusage, struct_value);
1610       size += GET_MODE_SIZE (Pmode);
1611     }
1612
1613   /* All arguments and registers used for the call are set up by now!  */
1614   function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1615
1616   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1617      and we don't want to load it into a register as an optimization,
1618      because prepare_call_address already did it if it should be done.  */
1619   if (GET_CODE (function) != SYMBOL_REF)
1620     function = memory_address (FUNCTION_MODE, function);
1621
1622   /* Generate the actual call instruction and save the return value.  */
1623 #ifdef HAVE_untyped_call
1624   if (HAVE_untyped_call)
1625     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1626                                       result, result_vector (1, result)));
1627   else
1628 #endif
1629 #ifdef HAVE_call_value
1630   if (HAVE_call_value)
1631     {
1632       rtx valreg = 0;
1633
1634       /* Locate the unique return register.  It is not possible to
1635          express a call that sets more than one return register using
1636          call_value; use untyped_call for that.  In fact, untyped_call
1637          only needs to save the return registers in the given block.  */
1638       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1639         if ((mode = apply_result_mode[regno]) != VOIDmode)
1640           {
1641             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1642
1643             valreg = gen_rtx_REG (mode, regno);
1644           }
1645
1646       emit_call_insn (GEN_CALL_VALUE (valreg,
1647                                       gen_rtx_MEM (FUNCTION_MODE, function),
1648                                       const0_rtx, NULL_RTX, const0_rtx));
1649
1650       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1651     }
1652   else
1653 #endif
1654     gcc_unreachable ();
1655
1656   /* Find the CALL insn we just emitted, and attach the register usage
1657      information.  */
1658   call_insn = last_call_insn ();
1659   add_function_usage_to (call_insn, call_fusage);
1660
1661   /* Restore the stack.  */
1662 #ifdef HAVE_save_stack_nonlocal
1663   if (HAVE_save_stack_nonlocal)
1664     emit_stack_restore (SAVE_NONLOCAL, old_stack_level);
1665   else
1666 #endif
1667     emit_stack_restore (SAVE_BLOCK, old_stack_level);
1668   fixup_args_size_notes (call_insn, get_last_insn(), 0);
1669
1670   OK_DEFER_POP;
1671
1672   /* Return the address of the result block.  */
1673   result = copy_addr_to_reg (XEXP (result, 0));
1674   return convert_memory_address (ptr_mode, result);
1675 }
1676
1677 /* Perform an untyped return.  */
1678
1679 static void
1680 expand_builtin_return (rtx result)
1681 {
1682   int size, align, regno;
1683   enum machine_mode mode;
1684   rtx reg;
1685   rtx call_fusage = 0;
1686
1687   result = convert_memory_address (Pmode, result);
1688
1689   apply_result_size ();
1690   result = gen_rtx_MEM (BLKmode, result);
1691
1692 #ifdef HAVE_untyped_return
1693   if (HAVE_untyped_return)
1694     {
1695       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1696       emit_barrier ();
1697       return;
1698     }
1699 #endif
1700
1701   /* Restore the return value and note that each value is used.  */
1702   size = 0;
1703   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1704     if ((mode = apply_result_mode[regno]) != VOIDmode)
1705       {
1706         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1707         if (size % align != 0)
1708           size = CEIL (size, align) * align;
1709         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1710         emit_move_insn (reg, adjust_address (result, mode, size));
1711
1712         push_to_sequence (call_fusage);
1713         emit_use (reg);
1714         call_fusage = get_insns ();
1715         end_sequence ();
1716         size += GET_MODE_SIZE (mode);
1717       }
1718
1719   /* Put the USE insns before the return.  */
1720   emit_insn (call_fusage);
1721
1722   /* Return whatever values was restored by jumping directly to the end
1723      of the function.  */
1724   expand_naked_return ();
1725 }
1726
1727 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1728
1729 static enum type_class
1730 type_to_class (tree type)
1731 {
1732   switch (TREE_CODE (type))
1733     {
1734     case VOID_TYPE:        return void_type_class;
1735     case INTEGER_TYPE:     return integer_type_class;
1736     case ENUMERAL_TYPE:    return enumeral_type_class;
1737     case BOOLEAN_TYPE:     return boolean_type_class;
1738     case POINTER_TYPE:     return pointer_type_class;
1739     case REFERENCE_TYPE:   return reference_type_class;
1740     case OFFSET_TYPE:      return offset_type_class;
1741     case REAL_TYPE:        return real_type_class;
1742     case COMPLEX_TYPE:     return complex_type_class;
1743     case FUNCTION_TYPE:    return function_type_class;
1744     case METHOD_TYPE:      return method_type_class;
1745     case RECORD_TYPE:      return record_type_class;
1746     case UNION_TYPE:
1747     case QUAL_UNION_TYPE:  return union_type_class;
1748     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1749                                    ? string_type_class : array_type_class);
1750     case LANG_TYPE:        return lang_type_class;
1751     default:               return no_type_class;
1752     }
1753 }
1754
1755 /* Expand a call EXP to __builtin_classify_type.  */
1756
1757 static rtx
1758 expand_builtin_classify_type (tree exp)
1759 {
1760   if (call_expr_nargs (exp))
1761     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1762   return GEN_INT (no_type_class);
1763 }
1764
1765 /* This helper macro, meant to be used in mathfn_built_in below,
1766    determines which among a set of three builtin math functions is
1767    appropriate for a given type mode.  The `F' and `L' cases are
1768    automatically generated from the `double' case.  */
1769 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1770   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1771   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1772   fcodel = BUILT_IN_MATHFN##L ; break;
1773 /* Similar to above, but appends _R after any F/L suffix.  */
1774 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1775   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1776   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1777   fcodel = BUILT_IN_MATHFN##L_R ; break;
1778
1779 /* Return mathematic function equivalent to FN but operating directly on TYPE,
1780    if available.  If IMPLICIT is true use the implicit builtin declaration,
1781    otherwise use the explicit declaration.  If we can't do the conversion,
1782    return zero.  */
1783
1784 static tree
1785 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit_p)
1786 {
1787   enum built_in_function fcode, fcodef, fcodel, fcode2;
1788
1789   switch (fn)
1790     {
1791       CASE_MATHFN (BUILT_IN_ACOS)
1792       CASE_MATHFN (BUILT_IN_ACOSH)
1793       CASE_MATHFN (BUILT_IN_ASIN)
1794       CASE_MATHFN (BUILT_IN_ASINH)
1795       CASE_MATHFN (BUILT_IN_ATAN)
1796       CASE_MATHFN (BUILT_IN_ATAN2)
1797       CASE_MATHFN (BUILT_IN_ATANH)
1798       CASE_MATHFN (BUILT_IN_CBRT)
1799       CASE_MATHFN (BUILT_IN_CEIL)
1800       CASE_MATHFN (BUILT_IN_CEXPI)
1801       CASE_MATHFN (BUILT_IN_COPYSIGN)
1802       CASE_MATHFN (BUILT_IN_COS)
1803       CASE_MATHFN (BUILT_IN_COSH)
1804       CASE_MATHFN (BUILT_IN_DREM)
1805       CASE_MATHFN (BUILT_IN_ERF)
1806       CASE_MATHFN (BUILT_IN_ERFC)
1807       CASE_MATHFN (BUILT_IN_EXP)
1808       CASE_MATHFN (BUILT_IN_EXP10)
1809       CASE_MATHFN (BUILT_IN_EXP2)
1810       CASE_MATHFN (BUILT_IN_EXPM1)
1811       CASE_MATHFN (BUILT_IN_FABS)
1812       CASE_MATHFN (BUILT_IN_FDIM)
1813       CASE_MATHFN (BUILT_IN_FLOOR)
1814       CASE_MATHFN (BUILT_IN_FMA)
1815       CASE_MATHFN (BUILT_IN_FMAX)
1816       CASE_MATHFN (BUILT_IN_FMIN)
1817       CASE_MATHFN (BUILT_IN_FMOD)
1818       CASE_MATHFN (BUILT_IN_FREXP)
1819       CASE_MATHFN (BUILT_IN_GAMMA)
1820       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1821       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1822       CASE_MATHFN (BUILT_IN_HYPOT)
1823       CASE_MATHFN (BUILT_IN_ILOGB)
1824       CASE_MATHFN (BUILT_IN_ICEIL)
1825       CASE_MATHFN (BUILT_IN_IFLOOR)
1826       CASE_MATHFN (BUILT_IN_INF)
1827       CASE_MATHFN (BUILT_IN_IRINT)
1828       CASE_MATHFN (BUILT_IN_IROUND)
1829       CASE_MATHFN (BUILT_IN_ISINF)
1830       CASE_MATHFN (BUILT_IN_J0)
1831       CASE_MATHFN (BUILT_IN_J1)
1832       CASE_MATHFN (BUILT_IN_JN)
1833       CASE_MATHFN (BUILT_IN_LCEIL)
1834       CASE_MATHFN (BUILT_IN_LDEXP)
1835       CASE_MATHFN (BUILT_IN_LFLOOR)
1836       CASE_MATHFN (BUILT_IN_LGAMMA)
1837       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1838       CASE_MATHFN (BUILT_IN_LLCEIL)
1839       CASE_MATHFN (BUILT_IN_LLFLOOR)
1840       CASE_MATHFN (BUILT_IN_LLRINT)
1841       CASE_MATHFN (BUILT_IN_LLROUND)
1842       CASE_MATHFN (BUILT_IN_LOG)
1843       CASE_MATHFN (BUILT_IN_LOG10)
1844       CASE_MATHFN (BUILT_IN_LOG1P)
1845       CASE_MATHFN (BUILT_IN_LOG2)
1846       CASE_MATHFN (BUILT_IN_LOGB)
1847       CASE_MATHFN (BUILT_IN_LRINT)
1848       CASE_MATHFN (BUILT_IN_LROUND)
1849       CASE_MATHFN (BUILT_IN_MODF)
1850       CASE_MATHFN (BUILT_IN_NAN)
1851       CASE_MATHFN (BUILT_IN_NANS)
1852       CASE_MATHFN (BUILT_IN_NEARBYINT)
1853       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1854       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1855       CASE_MATHFN (BUILT_IN_POW)
1856       CASE_MATHFN (BUILT_IN_POWI)
1857       CASE_MATHFN (BUILT_IN_POW10)
1858       CASE_MATHFN (BUILT_IN_REMAINDER)
1859       CASE_MATHFN (BUILT_IN_REMQUO)
1860       CASE_MATHFN (BUILT_IN_RINT)
1861       CASE_MATHFN (BUILT_IN_ROUND)
1862       CASE_MATHFN (BUILT_IN_SCALB)
1863       CASE_MATHFN (BUILT_IN_SCALBLN)
1864       CASE_MATHFN (BUILT_IN_SCALBN)
1865       CASE_MATHFN (BUILT_IN_SIGNBIT)
1866       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1867       CASE_MATHFN (BUILT_IN_SIN)
1868       CASE_MATHFN (BUILT_IN_SINCOS)
1869       CASE_MATHFN (BUILT_IN_SINH)
1870       CASE_MATHFN (BUILT_IN_SQRT)
1871       CASE_MATHFN (BUILT_IN_TAN)
1872       CASE_MATHFN (BUILT_IN_TANH)
1873       CASE_MATHFN (BUILT_IN_TGAMMA)
1874       CASE_MATHFN (BUILT_IN_TRUNC)
1875       CASE_MATHFN (BUILT_IN_Y0)
1876       CASE_MATHFN (BUILT_IN_Y1)
1877       CASE_MATHFN (BUILT_IN_YN)
1878
1879       default:
1880         return NULL_TREE;
1881       }
1882
1883   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1884     fcode2 = fcode;
1885   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1886     fcode2 = fcodef;
1887   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1888     fcode2 = fcodel;
1889   else
1890     return NULL_TREE;
1891
1892   if (implicit_p && !builtin_decl_implicit_p (fcode2))
1893     return NULL_TREE;
1894
1895   return builtin_decl_explicit (fcode2);
1896 }
1897
1898 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1899
1900 tree
1901 mathfn_built_in (tree type, enum built_in_function fn)
1902 {
1903   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1904 }
1905
1906 /* If errno must be maintained, expand the RTL to check if the result,
1907    TARGET, of a built-in function call, EXP, is NaN, and if so set
1908    errno to EDOM.  */
1909
1910 static void
1911 expand_errno_check (tree exp, rtx target)
1912 {
1913   rtx lab = gen_label_rtx ();
1914
1915   /* Test the result; if it is NaN, set errno=EDOM because
1916      the argument was not in the domain.  */
1917   do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1918                            NULL_RTX, NULL_RTX, lab,
1919                            /* The jump is very likely.  */
1920                            REG_BR_PROB_BASE - (REG_BR_PROB_BASE / 2000 - 1));
1921
1922 #ifdef TARGET_EDOM
1923   /* If this built-in doesn't throw an exception, set errno directly.  */
1924   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1925     {
1926 #ifdef GEN_ERRNO_RTX
1927       rtx errno_rtx = GEN_ERRNO_RTX;
1928 #else
1929       rtx errno_rtx
1930           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1931 #endif
1932       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1933       emit_label (lab);
1934       return;
1935     }
1936 #endif
1937
1938   /* Make sure the library call isn't expanded as a tail call.  */
1939   CALL_EXPR_TAILCALL (exp) = 0;
1940
1941   /* We can't set errno=EDOM directly; let the library call do it.
1942      Pop the arguments right away in case the call gets deleted.  */
1943   NO_DEFER_POP;
1944   expand_call (exp, target, 0);
1945   OK_DEFER_POP;
1946   emit_label (lab);
1947 }
1948
1949 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1950    Return NULL_RTX if a normal call should be emitted rather than expanding
1951    the function in-line.  EXP is the expression that is a call to the builtin
1952    function; if convenient, the result should be placed in TARGET.
1953    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1954
1955 static rtx
1956 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1957 {
1958   optab builtin_optab;
1959   rtx op0, insns;
1960   tree fndecl = get_callee_fndecl (exp);
1961   enum machine_mode mode;
1962   bool errno_set = false;
1963   tree arg;
1964
1965   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1966     return NULL_RTX;
1967
1968   arg = CALL_EXPR_ARG (exp, 0);
1969
1970   switch (DECL_FUNCTION_CODE (fndecl))
1971     {
1972     CASE_FLT_FN (BUILT_IN_SQRT):
1973       errno_set = ! tree_expr_nonnegative_p (arg);
1974       builtin_optab = sqrt_optab;
1975       break;
1976     CASE_FLT_FN (BUILT_IN_EXP):
1977       errno_set = true; builtin_optab = exp_optab; break;
1978     CASE_FLT_FN (BUILT_IN_EXP10):
1979     CASE_FLT_FN (BUILT_IN_POW10):
1980       errno_set = true; builtin_optab = exp10_optab; break;
1981     CASE_FLT_FN (BUILT_IN_EXP2):
1982       errno_set = true; builtin_optab = exp2_optab; break;
1983     CASE_FLT_FN (BUILT_IN_EXPM1):
1984       errno_set = true; builtin_optab = expm1_optab; break;
1985     CASE_FLT_FN (BUILT_IN_LOGB):
1986       errno_set = true; builtin_optab = logb_optab; break;
1987     CASE_FLT_FN (BUILT_IN_LOG):
1988       errno_set = true; builtin_optab = log_optab; break;
1989     CASE_FLT_FN (BUILT_IN_LOG10):
1990       errno_set = true; builtin_optab = log10_optab; break;
1991     CASE_FLT_FN (BUILT_IN_LOG2):
1992       errno_set = true; builtin_optab = log2_optab; break;
1993     CASE_FLT_FN (BUILT_IN_LOG1P):
1994       errno_set = true; builtin_optab = log1p_optab; break;
1995     CASE_FLT_FN (BUILT_IN_ASIN):
1996       builtin_optab = asin_optab; break;
1997     CASE_FLT_FN (BUILT_IN_ACOS):
1998       builtin_optab = acos_optab; break;
1999     CASE_FLT_FN (BUILT_IN_TAN):
2000       builtin_optab = tan_optab; break;
2001     CASE_FLT_FN (BUILT_IN_ATAN):
2002       builtin_optab = atan_optab; break;
2003     CASE_FLT_FN (BUILT_IN_FLOOR):
2004       builtin_optab = floor_optab; break;
2005     CASE_FLT_FN (BUILT_IN_CEIL):
2006       builtin_optab = ceil_optab; break;
2007     CASE_FLT_FN (BUILT_IN_TRUNC):
2008       builtin_optab = btrunc_optab; break;
2009     CASE_FLT_FN (BUILT_IN_ROUND):
2010       builtin_optab = round_optab; break;
2011     CASE_FLT_FN (BUILT_IN_NEARBYINT):
2012       builtin_optab = nearbyint_optab;
2013       if (flag_trapping_math)
2014         break;
2015       /* Else fallthrough and expand as rint.  */
2016     CASE_FLT_FN (BUILT_IN_RINT):
2017       builtin_optab = rint_optab; break;
2018     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
2019       builtin_optab = significand_optab; break;
2020     default:
2021       gcc_unreachable ();
2022     }
2023
2024   /* Make a suitable register to place result in.  */
2025   mode = TYPE_MODE (TREE_TYPE (exp));
2026
2027   if (! flag_errno_math || ! HONOR_NANS (mode))
2028     errno_set = false;
2029
2030   /* Before working hard, check whether the instruction is available.  */
2031   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing
2032       && (!errno_set || !optimize_insn_for_size_p ()))
2033     {
2034       rtx result = gen_reg_rtx (mode);
2035
2036       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2037          need to expand the argument again.  This way, we will not perform
2038          side-effects more the once.  */
2039       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2040
2041       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2042
2043       start_sequence ();
2044
2045       /* Compute into RESULT.
2046          Set RESULT to wherever the result comes back.  */
2047       result = expand_unop (mode, builtin_optab, op0, result, 0);
2048
2049       if (result != 0)
2050         {
2051           if (errno_set)
2052             expand_errno_check (exp, result);
2053
2054           /* Output the entire sequence.  */
2055           insns = get_insns ();
2056           end_sequence ();
2057           emit_insn (insns);
2058           return result;
2059         }
2060
2061       /* If we were unable to expand via the builtin, stop the sequence
2062          (without outputting the insns) and call to the library function
2063          with the stabilized argument list.  */
2064       end_sequence ();
2065     }
2066
2067   return expand_call (exp, target, target == const0_rtx);
2068 }
2069
2070 /* Expand a call to the builtin binary math functions (pow and atan2).
2071    Return NULL_RTX if a normal call should be emitted rather than expanding the
2072    function in-line.  EXP is the expression that is a call to the builtin
2073    function; if convenient, the result should be placed in TARGET.
2074    SUBTARGET may be used as the target for computing one of EXP's
2075    operands.  */
2076
2077 static rtx
2078 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2079 {
2080   optab builtin_optab;
2081   rtx op0, op1, insns, result;
2082   int op1_type = REAL_TYPE;
2083   tree fndecl = get_callee_fndecl (exp);
2084   tree arg0, arg1;
2085   enum machine_mode mode;
2086   bool errno_set = true;
2087
2088   switch (DECL_FUNCTION_CODE (fndecl))
2089     {
2090     CASE_FLT_FN (BUILT_IN_SCALBN):
2091     CASE_FLT_FN (BUILT_IN_SCALBLN):
2092     CASE_FLT_FN (BUILT_IN_LDEXP):
2093       op1_type = INTEGER_TYPE;
2094     default:
2095       break;
2096     }
2097
2098   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2099     return NULL_RTX;
2100
2101   arg0 = CALL_EXPR_ARG (exp, 0);
2102   arg1 = CALL_EXPR_ARG (exp, 1);
2103
2104   switch (DECL_FUNCTION_CODE (fndecl))
2105     {
2106     CASE_FLT_FN (BUILT_IN_POW):
2107       builtin_optab = pow_optab; break;
2108     CASE_FLT_FN (BUILT_IN_ATAN2):
2109       builtin_optab = atan2_optab; break;
2110     CASE_FLT_FN (BUILT_IN_SCALB):
2111       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2112         return 0;
2113       builtin_optab = scalb_optab; break;
2114     CASE_FLT_FN (BUILT_IN_SCALBN):
2115     CASE_FLT_FN (BUILT_IN_SCALBLN):
2116       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2117         return 0;
2118     /* Fall through... */
2119     CASE_FLT_FN (BUILT_IN_LDEXP):
2120       builtin_optab = ldexp_optab; break;
2121     CASE_FLT_FN (BUILT_IN_FMOD):
2122       builtin_optab = fmod_optab; break;
2123     CASE_FLT_FN (BUILT_IN_REMAINDER):
2124     CASE_FLT_FN (BUILT_IN_DREM):
2125       builtin_optab = remainder_optab; break;
2126     default:
2127       gcc_unreachable ();
2128     }
2129
2130   /* Make a suitable register to place result in.  */
2131   mode = TYPE_MODE (TREE_TYPE (exp));
2132
2133   /* Before working hard, check whether the instruction is available.  */
2134   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2135     return NULL_RTX;
2136
2137   result = gen_reg_rtx (mode);
2138
2139   if (! flag_errno_math || ! HONOR_NANS (mode))
2140     errno_set = false;
2141
2142   if (errno_set && optimize_insn_for_size_p ())
2143     return 0;
2144
2145   /* Always stabilize the argument list.  */
2146   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2147   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2148
2149   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2150   op1 = expand_normal (arg1);
2151
2152   start_sequence ();
2153
2154   /* Compute into RESULT.
2155      Set RESULT to wherever the result comes back.  */
2156   result = expand_binop (mode, builtin_optab, op0, op1,
2157                          result, 0, OPTAB_DIRECT);
2158
2159   /* If we were unable to expand via the builtin, stop the sequence
2160      (without outputting the insns) and call to the library function
2161      with the stabilized argument list.  */
2162   if (result == 0)
2163     {
2164       end_sequence ();
2165       return expand_call (exp, target, target == const0_rtx);
2166     }
2167
2168   if (errno_set)
2169     expand_errno_check (exp, result);
2170
2171   /* Output the entire sequence.  */
2172   insns = get_insns ();
2173   end_sequence ();
2174   emit_insn (insns);
2175
2176   return result;
2177 }
2178
2179 /* Expand a call to the builtin trinary math functions (fma).
2180    Return NULL_RTX if a normal call should be emitted rather than expanding the
2181    function in-line.  EXP is the expression that is a call to the builtin
2182    function; if convenient, the result should be placed in TARGET.
2183    SUBTARGET may be used as the target for computing one of EXP's
2184    operands.  */
2185
2186 static rtx
2187 expand_builtin_mathfn_ternary (tree exp, rtx target, rtx subtarget)
2188 {
2189   optab builtin_optab;
2190   rtx op0, op1, op2, insns, result;
2191   tree fndecl = get_callee_fndecl (exp);
2192   tree arg0, arg1, arg2;
2193   enum machine_mode mode;
2194
2195   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2196     return NULL_RTX;
2197
2198   arg0 = CALL_EXPR_ARG (exp, 0);
2199   arg1 = CALL_EXPR_ARG (exp, 1);
2200   arg2 = CALL_EXPR_ARG (exp, 2);
2201
2202   switch (DECL_FUNCTION_CODE (fndecl))
2203     {
2204     CASE_FLT_FN (BUILT_IN_FMA):
2205       builtin_optab = fma_optab; break;
2206     default:
2207       gcc_unreachable ();
2208     }
2209
2210   /* Make a suitable register to place result in.  */
2211   mode = TYPE_MODE (TREE_TYPE (exp));
2212
2213   /* Before working hard, check whether the instruction is available.  */
2214   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2215     return NULL_RTX;
2216
2217   result = gen_reg_rtx (mode);
2218
2219   /* Always stabilize the argument list.  */
2220   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2221   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2222   CALL_EXPR_ARG (exp, 2) = arg2 = builtin_save_expr (arg2);
2223
2224   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2225   op1 = expand_normal (arg1);
2226   op2 = expand_normal (arg2);
2227
2228   start_sequence ();
2229
2230   /* Compute into RESULT.
2231      Set RESULT to wherever the result comes back.  */
2232   result = expand_ternary_op (mode, builtin_optab, op0, op1, op2,
2233                               result, 0);
2234
2235   /* If we were unable to expand via the builtin, stop the sequence
2236      (without outputting the insns) and call to the library function
2237      with the stabilized argument list.  */
2238   if (result == 0)
2239     {
2240       end_sequence ();
2241       return expand_call (exp, target, target == const0_rtx);
2242     }
2243
2244   /* Output the entire sequence.  */
2245   insns = get_insns ();
2246   end_sequence ();
2247   emit_insn (insns);
2248
2249   return result;
2250 }
2251
2252 /* Expand a call to the builtin sin and cos math functions.
2253    Return NULL_RTX if a normal call should be emitted rather than expanding the
2254    function in-line.  EXP is the expression that is a call to the builtin
2255    function; if convenient, the result should be placed in TARGET.
2256    SUBTARGET may be used as the target for computing one of EXP's
2257    operands.  */
2258
2259 static rtx
2260 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2261 {
2262   optab builtin_optab;
2263   rtx op0, insns;
2264   tree fndecl = get_callee_fndecl (exp);
2265   enum machine_mode mode;
2266   tree arg;
2267
2268   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2269     return NULL_RTX;
2270
2271   arg = CALL_EXPR_ARG (exp, 0);
2272
2273   switch (DECL_FUNCTION_CODE (fndecl))
2274     {
2275     CASE_FLT_FN (BUILT_IN_SIN):
2276     CASE_FLT_FN (BUILT_IN_COS):
2277       builtin_optab = sincos_optab; break;
2278     default:
2279       gcc_unreachable ();
2280     }
2281
2282   /* Make a suitable register to place result in.  */
2283   mode = TYPE_MODE (TREE_TYPE (exp));
2284
2285   /* Check if sincos insn is available, otherwise fallback
2286      to sin or cos insn.  */
2287   if (optab_handler (builtin_optab, mode) == CODE_FOR_nothing)
2288     switch (DECL_FUNCTION_CODE (fndecl))
2289       {
2290       CASE_FLT_FN (BUILT_IN_SIN):
2291         builtin_optab = sin_optab; break;
2292       CASE_FLT_FN (BUILT_IN_COS):
2293         builtin_optab = cos_optab; break;
2294       default:
2295         gcc_unreachable ();
2296       }
2297
2298   /* Before working hard, check whether the instruction is available.  */
2299   if (optab_handler (builtin_optab, mode) != CODE_FOR_nothing)
2300     {
2301       rtx result = gen_reg_rtx (mode);
2302
2303       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2304          need to expand the argument again.  This way, we will not perform
2305          side-effects more the once.  */
2306       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2307
2308       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2309
2310       start_sequence ();
2311
2312       /* Compute into RESULT.
2313          Set RESULT to wherever the result comes back.  */
2314       if (builtin_optab == sincos_optab)
2315         {
2316           int ok;
2317
2318           switch (DECL_FUNCTION_CODE (fndecl))
2319             {
2320             CASE_FLT_FN (BUILT_IN_SIN):
2321               ok = expand_twoval_unop (builtin_optab, op0, 0, result, 0);
2322               break;
2323             CASE_FLT_FN (BUILT_IN_COS):
2324               ok = expand_twoval_unop (builtin_optab, op0, result, 0, 0);
2325               break;
2326             default:
2327               gcc_unreachable ();
2328             }
2329           gcc_assert (ok);
2330         }
2331       else
2332         result = expand_unop (mode, builtin_optab, op0, result, 0);
2333
2334       if (result != 0)
2335         {
2336           /* Output the entire sequence.  */
2337           insns = get_insns ();
2338           end_sequence ();
2339           emit_insn (insns);
2340           return result;
2341         }
2342
2343       /* If we were unable to expand via the builtin, stop the sequence
2344          (without outputting the insns) and call to the library function
2345          with the stabilized argument list.  */
2346       end_sequence ();
2347     }
2348
2349   return expand_call (exp, target, target == const0_rtx);
2350 }
2351
2352 /* Given an interclass math builtin decl FNDECL and it's argument ARG
2353    return an RTL instruction code that implements the functionality.
2354    If that isn't possible or available return CODE_FOR_nothing.  */
2355
2356 static enum insn_code
2357 interclass_mathfn_icode (tree arg, tree fndecl)
2358 {
2359   bool errno_set = false;
2360   optab builtin_optab = unknown_optab;
2361   enum machine_mode mode;
2362
2363   switch (DECL_FUNCTION_CODE (fndecl))
2364     {
2365     CASE_FLT_FN (BUILT_IN_ILOGB):
2366       errno_set = true; builtin_optab = ilogb_optab; break;
2367     CASE_FLT_FN (BUILT_IN_ISINF):
2368       builtin_optab = isinf_optab; break;
2369     case BUILT_IN_ISNORMAL:
2370     case BUILT_IN_ISFINITE:
2371     CASE_FLT_FN (BUILT_IN_FINITE):
2372     case BUILT_IN_FINITED32:
2373     case BUILT_IN_FINITED64:
2374     case BUILT_IN_FINITED128:
2375     case BUILT_IN_ISINFD32:
2376     case BUILT_IN_ISINFD64:
2377     case BUILT_IN_ISINFD128:
2378       /* These builtins have no optabs (yet).  */
2379       break;
2380     default:
2381       gcc_unreachable ();
2382     }
2383
2384   /* There's no easy way to detect the case we need to set EDOM.  */
2385   if (flag_errno_math && errno_set)
2386     return CODE_FOR_nothing;
2387
2388   /* Optab mode depends on the mode of the input argument.  */
2389   mode = TYPE_MODE (TREE_TYPE (arg));
2390
2391   if (builtin_optab)
2392     return optab_handler (builtin_optab, mode);
2393   return CODE_FOR_nothing;
2394 }
2395
2396 /* Expand a call to one of the builtin math functions that operate on
2397    floating point argument and output an integer result (ilogb, isinf,
2398    isnan, etc).
2399    Return 0 if a normal call should be emitted rather than expanding the
2400    function in-line.  EXP is the expression that is a call to the builtin
2401    function; if convenient, the result should be placed in TARGET.  */
2402
2403 static rtx
2404 expand_builtin_interclass_mathfn (tree exp, rtx target)
2405 {
2406   enum insn_code icode = CODE_FOR_nothing;
2407   rtx op0;
2408   tree fndecl = get_callee_fndecl (exp);
2409   enum machine_mode mode;
2410   tree arg;
2411
2412   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2413     return NULL_RTX;
2414
2415   arg = CALL_EXPR_ARG (exp, 0);
2416   icode = interclass_mathfn_icode (arg, fndecl);
2417   mode = TYPE_MODE (TREE_TYPE (arg));
2418
2419   if (icode != CODE_FOR_nothing)
2420     {
2421       struct expand_operand ops[1];
2422       rtx last = get_last_insn ();
2423       tree orig_arg = arg;
2424
2425       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2426          need to expand the argument again.  This way, we will not perform
2427          side-effects more the once.  */
2428       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2429
2430       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2431
2432       if (mode != GET_MODE (op0))
2433         op0 = convert_to_mode (mode, op0, 0);
2434
2435       create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp)));
2436       if (maybe_legitimize_operands (icode, 0, 1, ops)
2437           && maybe_emit_unop_insn (icode, ops[0].value, op0, UNKNOWN))
2438         return ops[0].value;
2439
2440       delete_insns_since (last);
2441       CALL_EXPR_ARG (exp, 0) = orig_arg;
2442     }
2443
2444   return NULL_RTX;
2445 }
2446
2447 /* Expand a call to the builtin sincos math function.
2448    Return NULL_RTX if a normal call should be emitted rather than expanding the
2449    function in-line.  EXP is the expression that is a call to the builtin
2450    function.  */
2451
2452 static rtx
2453 expand_builtin_sincos (tree exp)
2454 {
2455   rtx op0, op1, op2, target1, target2;
2456   enum machine_mode mode;
2457   tree arg, sinp, cosp;
2458   int result;
2459   location_t loc = EXPR_LOCATION (exp);
2460   tree alias_type, alias_off;
2461
2462   if (!validate_arglist (exp, REAL_TYPE,
2463                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2464     return NULL_RTX;
2465
2466   arg = CALL_EXPR_ARG (exp, 0);
2467   sinp = CALL_EXPR_ARG (exp, 1);
2468   cosp = CALL_EXPR_ARG (exp, 2);
2469
2470   /* Make a suitable register to place result in.  */
2471   mode = TYPE_MODE (TREE_TYPE (arg));
2472
2473   /* Check if sincos insn is available, otherwise emit the call.  */
2474   if (optab_handler (sincos_optab, mode) == CODE_FOR_nothing)
2475     return NULL_RTX;
2476
2477   target1 = gen_reg_rtx (mode);
2478   target2 = gen_reg_rtx (mode);
2479
2480   op0 = expand_normal (arg);
2481   alias_type = build_pointer_type_for_mode (TREE_TYPE (arg), ptr_mode, true);
2482   alias_off = build_int_cst (alias_type, 0);
2483   op1 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2484                                         sinp, alias_off));
2485   op2 = expand_normal (fold_build2_loc (loc, MEM_REF, TREE_TYPE (arg),
2486                                         cosp, alias_off));
2487
2488   /* Compute into target1 and target2.
2489      Set TARGET to wherever the result comes back.  */
2490   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2491   gcc_assert (result);
2492
2493   /* Move target1 and target2 to the memory locations indicated
2494      by op1 and op2.  */
2495   emit_move_insn (op1, target1);
2496   emit_move_insn (op2, target2);
2497
2498   return const0_rtx;
2499 }
2500
2501 /* Expand a call to the internal cexpi builtin to the sincos math function.
2502    EXP is the expression that is a call to the builtin function; if convenient,
2503    the result should be placed in TARGET.  */
2504
2505 static rtx
2506 expand_builtin_cexpi (tree exp, rtx target)
2507 {
2508   tree fndecl = get_callee_fndecl (exp);
2509   tree arg, type;
2510   enum machine_mode mode;
2511   rtx op0, op1, op2;
2512   location_t loc = EXPR_LOCATION (exp);
2513
2514   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2515     return NULL_RTX;
2516
2517   arg = CALL_EXPR_ARG (exp, 0);
2518   type = TREE_TYPE (arg);
2519   mode = TYPE_MODE (TREE_TYPE (arg));
2520
2521   /* Try expanding via a sincos optab, fall back to emitting a libcall
2522      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2523      is only generated from sincos, cexp or if we have either of them.  */
2524   if (optab_handler (sincos_optab, mode) != CODE_FOR_nothing)
2525     {
2526       op1 = gen_reg_rtx (mode);
2527       op2 = gen_reg_rtx (mode);
2528
2529       op0 = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
2530
2531       /* Compute into op1 and op2.  */
2532       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2533     }
2534   else if (TARGET_HAS_SINCOS)
2535     {
2536       tree call, fn = NULL_TREE;
2537       tree top1, top2;
2538       rtx op1a, op2a;
2539
2540       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2541         fn = builtin_decl_explicit (BUILT_IN_SINCOSF);
2542       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2543         fn = builtin_decl_explicit (BUILT_IN_SINCOS);
2544       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2545         fn = builtin_decl_explicit (BUILT_IN_SINCOSL);
2546       else
2547         gcc_unreachable ();
2548
2549       op1 = assign_temp (TREE_TYPE (arg), 1, 1);
2550       op2 = assign_temp (TREE_TYPE (arg), 1, 1);
2551       op1a = copy_addr_to_reg (XEXP (op1, 0));
2552       op2a = copy_addr_to_reg (XEXP (op2, 0));
2553       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2554       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2555
2556       /* Make sure not to fold the sincos call again.  */
2557       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2558       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2559                                       call, 3, arg, top1, top2));
2560     }
2561   else
2562     {
2563       tree call, fn = NULL_TREE, narg;
2564       tree ctype = build_complex_type (type);
2565
2566       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2567         fn = builtin_decl_explicit (BUILT_IN_CEXPF);
2568       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2569         fn = builtin_decl_explicit (BUILT_IN_CEXP);
2570       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2571         fn = builtin_decl_explicit (BUILT_IN_CEXPL);
2572       else
2573         gcc_unreachable ();
2574
2575       /* If we don't have a decl for cexp create one.  This is the
2576          friendliest fallback if the user calls __builtin_cexpi
2577          without full target C99 function support.  */
2578       if (fn == NULL_TREE)
2579         {
2580           tree fntype;
2581           const char *name = NULL;
2582
2583           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2584             name = "cexpf";
2585           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2586             name = "cexp";
2587           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2588             name = "cexpl";
2589
2590           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2591           fn = build_fn_decl (name, fntype);
2592         }
2593
2594       narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2595                           build_real (type, dconst0), arg);
2596
2597       /* Make sure not to fold the cexp call again.  */
2598       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2599       return expand_expr (build_call_nary (ctype, call, 1, narg),
2600                           target, VOIDmode, EXPAND_NORMAL);
2601     }
2602
2603   /* Now build the proper return type.  */
2604   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2605                               make_tree (TREE_TYPE (arg), op2),
2606                               make_tree (TREE_TYPE (arg), op1)),
2607                       target, VOIDmode, EXPAND_NORMAL);
2608 }
2609
2610 /* Conveniently construct a function call expression.  FNDECL names the
2611    function to be called, N is the number of arguments, and the "..."
2612    parameters are the argument expressions.  Unlike build_call_exr
2613    this doesn't fold the call, hence it will always return a CALL_EXPR.  */
2614
2615 static tree
2616 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2617 {
2618   va_list ap;
2619   tree fntype = TREE_TYPE (fndecl);
2620   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2621
2622   va_start (ap, n);
2623   fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2624   va_end (ap);
2625   SET_EXPR_LOCATION (fn, loc);
2626   return fn;
2627 }
2628
2629 /* Expand a call to one of the builtin rounding functions gcc defines
2630    as an extension (lfloor and lceil).  As these are gcc extensions we
2631    do not need to worry about setting errno to EDOM.
2632    If expanding via optab fails, lower expression to (int)(floor(x)).
2633    EXP is the expression that is a call to the builtin function;
2634    if convenient, the result should be placed in TARGET.  */
2635
2636 static rtx
2637 expand_builtin_int_roundingfn (tree exp, rtx target)
2638 {
2639   convert_optab builtin_optab;
2640   rtx op0, insns, tmp;
2641   tree fndecl = get_callee_fndecl (exp);
2642   enum built_in_function fallback_fn;
2643   tree fallback_fndecl;
2644   enum machine_mode mode;
2645   tree arg;
2646
2647   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2648     gcc_unreachable ();
2649
2650   arg = CALL_EXPR_ARG (exp, 0);
2651
2652   switch (DECL_FUNCTION_CODE (fndecl))
2653     {
2654     CASE_FLT_FN (BUILT_IN_ICEIL):
2655     CASE_FLT_FN (BUILT_IN_LCEIL):
2656     CASE_FLT_FN (BUILT_IN_LLCEIL):
2657       builtin_optab = lceil_optab;
2658       fallback_fn = BUILT_IN_CEIL;
2659       break;
2660
2661     CASE_FLT_FN (BUILT_IN_IFLOOR):
2662     CASE_FLT_FN (BUILT_IN_LFLOOR):
2663     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2664       builtin_optab = lfloor_optab;
2665       fallback_fn = BUILT_IN_FLOOR;
2666       break;
2667
2668     default:
2669       gcc_unreachable ();
2670     }
2671
2672   /* Make a suitable register to place result in.  */
2673   mode = TYPE_MODE (TREE_TYPE (exp));
2674
2675   target = gen_reg_rtx (mode);
2676
2677   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2678      need to expand the argument again.  This way, we will not perform
2679      side-effects more the once.  */
2680   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2681
2682   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2683
2684   start_sequence ();
2685
2686   /* Compute into TARGET.  */
2687   if (expand_sfix_optab (target, op0, builtin_optab))
2688     {
2689       /* Output the entire sequence.  */
2690       insns = get_insns ();
2691       end_sequence ();
2692       emit_insn (insns);
2693       return target;
2694     }
2695
2696   /* If we were unable to expand via the builtin, stop the sequence
2697      (without outputting the insns).  */
2698   end_sequence ();
2699
2700   /* Fall back to floating point rounding optab.  */
2701   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2702
2703   /* For non-C99 targets we may end up without a fallback fndecl here
2704      if the user called __builtin_lfloor directly.  In this case emit
2705      a call to the floor/ceil variants nevertheless.  This should result
2706      in the best user experience for not full C99 targets.  */
2707   if (fallback_fndecl == NULL_TREE)
2708     {
2709       tree fntype;
2710       const char *name = NULL;
2711
2712       switch (DECL_FUNCTION_CODE (fndecl))
2713         {
2714         case BUILT_IN_ICEIL:
2715         case BUILT_IN_LCEIL:
2716         case BUILT_IN_LLCEIL:
2717           name = "ceil";
2718           break;
2719         case BUILT_IN_ICEILF:
2720         case BUILT_IN_LCEILF:
2721         case BUILT_IN_LLCEILF:
2722           name = "ceilf";
2723           break;
2724         case BUILT_IN_ICEILL:
2725         case BUILT_IN_LCEILL:
2726         case BUILT_IN_LLCEILL:
2727           name = "ceill";
2728           break;
2729         case BUILT_IN_IFLOOR:
2730         case BUILT_IN_LFLOOR:
2731         case BUILT_IN_LLFLOOR:
2732           name = "floor";
2733           break;
2734         case BUILT_IN_IFLOORF:
2735         case BUILT_IN_LFLOORF:
2736         case BUILT_IN_LLFLOORF:
2737           name = "floorf";
2738           break;
2739         case BUILT_IN_IFLOORL:
2740         case BUILT_IN_LFLOORL:
2741         case BUILT_IN_LLFLOORL:
2742           name = "floorl";
2743           break;
2744         default:
2745           gcc_unreachable ();
2746         }
2747
2748       fntype = build_function_type_list (TREE_TYPE (arg),
2749                                          TREE_TYPE (arg), NULL_TREE);
2750       fallback_fndecl = build_fn_decl (name, fntype);
2751     }
2752
2753   exp = build_call_nofold_loc (EXPR_LOCATION (exp), fallback_fndecl, 1, arg);
2754
2755   tmp = expand_normal (exp);
2756   tmp = maybe_emit_group_store (tmp, TREE_TYPE (exp));
2757
2758   /* Truncate the result of floating point optab to integer
2759      via expand_fix ().  */
2760   target = gen_reg_rtx (mode);
2761   expand_fix (target, tmp, 0);
2762
2763   return target;
2764 }
2765
2766 /* Expand a call to one of the builtin math functions doing integer
2767    conversion (lrint).
2768    Return 0 if a normal call should be emitted rather than expanding the
2769    function in-line.  EXP is the expression that is a call to the builtin
2770    function; if convenient, the result should be placed in TARGET.  */
2771
2772 static rtx
2773 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2774 {
2775   convert_optab builtin_optab;
2776   rtx op0, insns;
2777   tree fndecl = get_callee_fndecl (exp);
2778   tree arg;
2779   enum machine_mode mode;
2780   enum built_in_function fallback_fn = BUILT_IN_NONE;
2781
2782   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2783      gcc_unreachable ();
2784
2785   arg = CALL_EXPR_ARG (exp, 0);
2786
2787   switch (DECL_FUNCTION_CODE (fndecl))
2788     {
2789     CASE_FLT_FN (BUILT_IN_IRINT):
2790       fallback_fn = BUILT_IN_LRINT;
2791       /* FALLTHRU */
2792     CASE_FLT_FN (BUILT_IN_LRINT):
2793     CASE_FLT_FN (BUILT_IN_LLRINT):
2794       builtin_optab = lrint_optab;
2795       break;
2796
2797     CASE_FLT_FN (BUILT_IN_IROUND):
2798       fallback_fn = BUILT_IN_LROUND;
2799       /* FALLTHRU */
2800     CASE_FLT_FN (BUILT_IN_LROUND):
2801     CASE_FLT_FN (BUILT_IN_LLROUND):
2802       builtin_optab = lround_optab;
2803       break;
2804
2805     default:
2806       gcc_unreachable ();
2807     }
2808
2809   /* There's no easy way to detect the case we need to set EDOM.  */
2810   if (flag_errno_math && fallback_fn == BUILT_IN_NONE)
2811     return NULL_RTX;
2812
2813   /* Make a suitable register to place result in.  */
2814   mode = TYPE_MODE (TREE_TYPE (exp));
2815
2816   /* There's no easy way to detect the case we need to set EDOM.  */
2817   if (!flag_errno_math)
2818     {
2819       rtx result = gen_reg_rtx (mode);
2820
2821       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2822          need to expand the argument again.  This way, we will not perform
2823          side-effects more the once.  */
2824       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2825
2826       op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2827
2828       start_sequence ();
2829
2830       if (expand_sfix_optab (result, op0, builtin_optab))
2831         {
2832           /* Output the entire sequence.  */
2833           insns = get_insns ();
2834           end_sequence ();
2835           emit_insn (insns);
2836           return result;
2837         }
2838
2839       /* If we were unable to expand via the builtin, stop the sequence
2840          (without outputting the insns) and call to the library function
2841          with the stabilized argument list.  */
2842       end_sequence ();
2843     }
2844
2845   if (fallback_fn != BUILT_IN_NONE)
2846     {
2847       /* Fall back to rounding to long int.  Use implicit_p 0 - for non-C99
2848          targets, (int) round (x) should never be transformed into
2849          BUILT_IN_IROUND and if __builtin_iround is called directly, emit
2850          a call to lround in the hope that the target provides at least some
2851          C99 functions.  This should result in the best user experience for
2852          not full C99 targets.  */
2853       tree fallback_fndecl = mathfn_built_in_1 (TREE_TYPE (arg),
2854                                                 fallback_fn, 0);
2855
2856       exp = build_call_nofold_loc (EXPR_LOCATION (exp),
2857                                    fallback_fndecl, 1, arg);
2858
2859       target = expand_call (exp, NULL_RTX, target == const0_rtx);
2860       target = maybe_emit_group_store (target, TREE_TYPE (exp));
2861       return convert_to_mode (mode, target, 0);
2862     }
2863
2864   return expand_call (exp, target, target == const0_rtx);
2865 }
2866
2867 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
2868    a normal call should be emitted rather than expanding the function
2869    in-line.  EXP is the expression that is a call to the builtin
2870    function; if convenient, the result should be placed in TARGET.  */
2871
2872 static rtx
2873 expand_builtin_powi (tree exp, rtx target)
2874 {
2875   tree arg0, arg1;
2876   rtx op0, op1;
2877   enum machine_mode mode;
2878   enum machine_mode mode2;
2879
2880   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2881     return NULL_RTX;
2882
2883   arg0 = CALL_EXPR_ARG (exp, 0);
2884   arg1 = CALL_EXPR_ARG (exp, 1);
2885   mode = TYPE_MODE (TREE_TYPE (exp));
2886
2887   /* Emit a libcall to libgcc.  */
2888
2889   /* Mode of the 2nd argument must match that of an int.  */
2890   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
2891
2892   if (target == NULL_RTX)
2893     target = gen_reg_rtx (mode);
2894
2895   op0 = expand_expr (arg0, NULL_RTX, mode, EXPAND_NORMAL);
2896   if (GET_MODE (op0) != mode)
2897     op0 = convert_to_mode (mode, op0, 0);
2898   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
2899   if (GET_MODE (op1) != mode2)
2900     op1 = convert_to_mode (mode2, op1, 0);
2901
2902   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
2903                                     target, LCT_CONST, mode, 2,
2904                                     op0, mode, op1, mode2);
2905
2906   return target;
2907 }
2908
2909 /* Expand expression EXP which is a call to the strlen builtin.  Return
2910    NULL_RTX if we failed the caller should emit a normal call, otherwise
2911    try to get the result in TARGET, if convenient.  */
2912
2913 static rtx
2914 expand_builtin_strlen (tree exp, rtx target,
2915                        enum machine_mode target_mode)
2916 {
2917   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
2918     return NULL_RTX;
2919   else
2920     {
2921       struct expand_operand ops[4];
2922       rtx pat;
2923       tree len;
2924       tree src = CALL_EXPR_ARG (exp, 0);
2925       rtx src_reg, before_strlen;
2926       enum machine_mode insn_mode = target_mode;
2927       enum insn_code icode = CODE_FOR_nothing;
2928       unsigned int align;
2929
2930       /* If the length can be computed at compile-time, return it.  */
2931       len = c_strlen (src, 0);
2932       if (len)
2933         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2934
2935       /* If the length can be computed at compile-time and is constant
2936          integer, but there are side-effects in src, evaluate
2937          src for side-effects, then return len.
2938          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2939          can be optimized into: i++; x = 3;  */
2940       len = c_strlen (src, 1);
2941       if (len && TREE_CODE (len) == INTEGER_CST)
2942         {
2943           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2944           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2945         }
2946
2947       align = get_pointer_alignment (src) / BITS_PER_UNIT;
2948
2949       /* If SRC is not a pointer type, don't do this operation inline.  */
2950       if (align == 0)
2951         return NULL_RTX;
2952
2953       /* Bail out if we can't compute strlen in the right mode.  */
2954       while (insn_mode != VOIDmode)
2955         {
2956           icode = optab_handler (strlen_optab, insn_mode);
2957           if (icode != CODE_FOR_nothing)
2958             break;
2959
2960           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2961         }
2962       if (insn_mode == VOIDmode)
2963         return NULL_RTX;
2964
2965       /* Make a place to hold the source address.  We will not expand
2966          the actual source until we are sure that the expansion will
2967          not fail -- there are trees that cannot be expanded twice.  */
2968       src_reg = gen_reg_rtx (Pmode);
2969
2970       /* Mark the beginning of the strlen sequence so we can emit the
2971          source operand later.  */
2972       before_strlen = get_last_insn ();
2973
2974       create_output_operand (&ops[0], target, insn_mode);
2975       create_fixed_operand (&ops[1], gen_rtx_MEM (BLKmode, src_reg));
2976       create_integer_operand (&ops[2], 0);
2977       create_integer_operand (&ops[3], align);
2978       if (!maybe_expand_insn (icode, 4, ops))
2979         return NULL_RTX;
2980
2981       /* Now that we are assured of success, expand the source.  */
2982       start_sequence ();
2983       pat = expand_expr (src, src_reg, Pmode, EXPAND_NORMAL);
2984       if (pat != src_reg)
2985         {
2986 #ifdef POINTERS_EXTEND_UNSIGNED
2987           if (GET_MODE (pat) != Pmode)
2988             pat = convert_to_mode (Pmode, pat,
2989                                    POINTERS_EXTEND_UNSIGNED);
2990 #endif
2991           emit_move_insn (src_reg, pat);
2992         }
2993       pat = get_insns ();
2994       end_sequence ();
2995
2996       if (before_strlen)
2997         emit_insn_after (pat, before_strlen);
2998       else
2999         emit_insn_before (pat, get_insns ());
3000
3001       /* Return the value in the proper mode for this function.  */
3002       if (GET_MODE (ops[0].value) == target_mode)
3003         target = ops[0].value;
3004       else if (target != 0)
3005         convert_move (target, ops[0].value, 0);
3006       else
3007         target = convert_to_mode (target_mode, ops[0].value, 0);
3008
3009       return target;
3010     }
3011 }
3012
3013 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3014    bytes from constant string DATA + OFFSET and return it as target
3015    constant.  */
3016
3017 static rtx
3018 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3019                          enum machine_mode mode)
3020 {
3021   const char *str = (const char *) data;
3022
3023   gcc_assert (offset >= 0
3024               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3025                   <= strlen (str) + 1));
3026
3027   return c_readstr (str + offset, mode);
3028 }
3029
3030 /* Expand a call EXP to the memcpy builtin.
3031    Return NULL_RTX if we failed, the caller should emit a normal call,
3032    otherwise try to get the result in TARGET, if convenient (and in
3033    mode MODE if that's convenient).  */
3034
3035 static rtx
3036 expand_builtin_memcpy (tree exp, rtx target)
3037 {
3038   if (!validate_arglist (exp,
3039                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3040     return NULL_RTX;
3041   else
3042     {
3043       tree dest = CALL_EXPR_ARG (exp, 0);
3044       tree src = CALL_EXPR_ARG (exp, 1);
3045       tree len = CALL_EXPR_ARG (exp, 2);
3046       const char *src_str;
3047       unsigned int src_align = get_pointer_alignment (src);
3048       unsigned int dest_align = get_pointer_alignment (dest);
3049       rtx dest_mem, src_mem, dest_addr, len_rtx;
3050       HOST_WIDE_INT expected_size = -1;
3051       unsigned int expected_align = 0;
3052
3053       /* If DEST is not a pointer type, call the normal function.  */
3054       if (dest_align == 0)
3055         return NULL_RTX;
3056
3057       /* If either SRC is not a pointer type, don't do this
3058          operation in-line.  */
3059       if (src_align == 0)
3060         return NULL_RTX;
3061
3062       if (currently_expanding_gimple_stmt)
3063         stringop_block_profile (currently_expanding_gimple_stmt,
3064                                 &expected_align, &expected_size);
3065
3066       if (expected_align < dest_align)
3067         expected_align = dest_align;
3068       dest_mem = get_memory_rtx (dest, len);
3069       set_mem_align (dest_mem, dest_align);
3070       len_rtx = expand_normal (len);
3071       src_str = c_getstr (src);
3072
3073       /* If SRC is a string constant and block move would be done
3074          by pieces, we can avoid loading the string from memory
3075          and only stored the computed constants.  */
3076       if (src_str
3077           && CONST_INT_P (len_rtx)
3078           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3079           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3080                                   CONST_CAST (char *, src_str),
3081                                   dest_align, false))
3082         {
3083           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3084                                       builtin_memcpy_read_str,
3085                                       CONST_CAST (char *, src_str),
3086                                       dest_align, false, 0);
3087           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3088           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3089           return dest_mem;
3090         }
3091
3092       src_mem = get_memory_rtx (src, len);
3093       set_mem_align (src_mem, src_align);
3094
3095       /* Copy word part most expediently.  */
3096       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3097                                          CALL_EXPR_TAILCALL (exp)
3098                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3099                                          expected_align, expected_size);
3100
3101       if (dest_addr == 0)
3102         {
3103           dest_addr = force_operand (XEXP (dest_mem, 0), target);
3104           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3105         }
3106       return dest_addr;
3107     }
3108 }
3109
3110 /* Expand a call EXP to the mempcpy builtin.
3111    Return NULL_RTX if we failed; the caller should emit a normal call,
3112    otherwise try to get the result in TARGET, if convenient (and in
3113    mode MODE if that's convenient).  If ENDP is 0 return the
3114    destination pointer, if ENDP is 1 return the end pointer ala
3115    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3116    stpcpy.  */
3117
3118 static rtx
3119 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3120 {
3121   if (!validate_arglist (exp,
3122                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3123     return NULL_RTX;
3124   else
3125     {
3126       tree dest = CALL_EXPR_ARG (exp, 0);
3127       tree src = CALL_EXPR_ARG (exp, 1);
3128       tree len = CALL_EXPR_ARG (exp, 2);
3129       return expand_builtin_mempcpy_args (dest, src, len,
3130                                           target, mode, /*endp=*/ 1);
3131     }
3132 }
3133
3134 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3135    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3136    so that this can also be called without constructing an actual CALL_EXPR.
3137    The other arguments and return value are the same as for
3138    expand_builtin_mempcpy.  */
3139
3140 static rtx
3141 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3142                              rtx target, enum machine_mode mode, int endp)
3143 {
3144     /* If return value is ignored, transform mempcpy into memcpy.  */
3145   if (target == const0_rtx && builtin_decl_implicit_p (BUILT_IN_MEMCPY))
3146     {
3147       tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
3148       tree result = build_call_nofold_loc (UNKNOWN_LOCATION, fn, 3,
3149                                            dest, src, len);
3150       return expand_expr (result, target, mode, EXPAND_NORMAL);
3151     }
3152   else
3153     {
3154       const char *src_str;
3155       unsigned int src_align = get_pointer_alignment (src);
3156       unsigned int dest_align = get_pointer_alignment (dest);
3157       rtx dest_mem, src_mem, len_rtx;
3158
3159       /* If either SRC or DEST is not a pointer type, don't do this
3160          operation in-line.  */
3161       if (dest_align == 0 || src_align == 0)
3162         return NULL_RTX;
3163
3164       /* If LEN is not constant, call the normal function.  */
3165       if (! host_integerp (len, 1))
3166         return NULL_RTX;
3167
3168       len_rtx = expand_normal (len);
3169       src_str = c_getstr (src);
3170
3171       /* If SRC is a string constant and block move would be done
3172          by pieces, we can avoid loading the string from memory
3173          and only stored the computed constants.  */
3174       if (src_str
3175           && CONST_INT_P (len_rtx)
3176           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3177           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3178                                   CONST_CAST (char *, src_str),
3179                                   dest_align, false))
3180         {
3181           dest_mem = get_memory_rtx (dest, len);
3182           set_mem_align (dest_mem, dest_align);
3183           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3184                                       builtin_memcpy_read_str,
3185                                       CONST_CAST (char *, src_str),
3186                                       dest_align, false, endp);
3187           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3188           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3189           return dest_mem;
3190         }
3191
3192       if (CONST_INT_P (len_rtx)
3193           && can_move_by_pieces (INTVAL (len_rtx),
3194                                  MIN (dest_align, src_align)))
3195         {
3196           dest_mem = get_memory_rtx (dest, len);
3197           set_mem_align (dest_mem, dest_align);
3198           src_mem = get_memory_rtx (src, len);
3199           set_mem_align (src_mem, src_align);
3200           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3201                                      MIN (dest_align, src_align), endp);
3202           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3203           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3204           return dest_mem;
3205         }
3206
3207       return NULL_RTX;
3208     }
3209 }
3210
3211 #ifndef HAVE_movstr
3212 # define HAVE_movstr 0
3213 # define CODE_FOR_movstr CODE_FOR_nothing
3214 #endif
3215
3216 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3217    we failed, the caller should emit a normal call, otherwise try to
3218    get the result in TARGET, if convenient.  If ENDP is 0 return the
3219    destination pointer, if ENDP is 1 return the end pointer ala
3220    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3221    stpcpy.  */
3222
3223 static rtx
3224 expand_movstr (tree dest, tree src, rtx target, int endp)
3225 {
3226   struct expand_operand ops[3];
3227   rtx dest_mem;
3228   rtx src_mem;
3229
3230   if (!HAVE_movstr)
3231     return NULL_RTX;
3232
3233   dest_mem = get_memory_rtx (dest, NULL);
3234   src_mem = get_memory_rtx (src, NULL);
3235   if (!endp)
3236     {
3237       target = force_reg (Pmode, XEXP (dest_mem, 0));
3238       dest_mem = replace_equiv_address (dest_mem, target);
3239     }
3240
3241   create_output_operand (&ops[0], endp ? target : NULL_RTX, Pmode);
3242   create_fixed_operand (&ops[1], dest_mem);
3243   create_fixed_operand (&ops[2], src_mem);
3244   expand_insn (CODE_FOR_movstr, 3, ops);
3245
3246   if (endp && target != const0_rtx)
3247     {
3248       target = ops[0].value;
3249       /* movstr is supposed to set end to the address of the NUL
3250          terminator.  If the caller requested a mempcpy-like return value,
3251          adjust it.  */
3252       if (endp == 1)
3253         {
3254           rtx tem = plus_constant (GET_MODE (target),
3255                                    gen_lowpart (GET_MODE (target), target), 1);
3256           emit_move_insn (target, force_operand (tem, NULL_RTX));
3257         }
3258     }
3259   return target;
3260 }
3261
3262 /* Expand expression EXP, which is a call to the strcpy builtin.  Return
3263    NULL_RTX if we failed the caller should emit a normal call, otherwise
3264    try to get the result in TARGET, if convenient (and in mode MODE if that's
3265    convenient).  */
3266
3267 static rtx
3268 expand_builtin_strcpy (tree exp, rtx target)
3269 {
3270   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3271    {
3272      tree dest = CALL_EXPR_ARG (exp, 0);
3273      tree src = CALL_EXPR_ARG (exp, 1);
3274      return expand_builtin_strcpy_args (dest, src, target);
3275    }
3276    return NULL_RTX;
3277 }
3278
3279 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3280    arguments to the builtin_strcpy call DEST and SRC are broken out
3281    so that this can also be called without constructing an actual CALL_EXPR.
3282    The other arguments and return value are the same as for
3283    expand_builtin_strcpy.  */
3284
3285 static rtx
3286 expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3287 {
3288   return expand_movstr (dest, src, target, /*endp=*/0);
3289 }
3290
3291 /* Expand a call EXP to the stpcpy builtin.
3292    Return NULL_RTX if we failed the caller should emit a normal call,
3293    otherwise try to get the result in TARGET, if convenient (and in
3294    mode MODE if that's convenient).  */
3295
3296 static rtx
3297 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3298 {
3299   tree dst, src;
3300   location_t loc = EXPR_LOCATION (exp);
3301
3302   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3303     return NULL_RTX;
3304
3305   dst = CALL_EXPR_ARG (exp, 0);
3306   src = CALL_EXPR_ARG (exp, 1);
3307
3308   /* If return value is ignored, transform stpcpy into strcpy.  */
3309   if (target == const0_rtx && builtin_decl_implicit (BUILT_IN_STRCPY))
3310     {
3311       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
3312       tree result = build_call_nofold_loc (loc, fn, 2, dst, src);
3313       return expand_expr (result, target, mode, EXPAND_NORMAL);
3314     }
3315   else
3316     {
3317       tree len, lenp1;
3318       rtx ret;
3319
3320       /* Ensure we get an actual string whose length can be evaluated at
3321          compile-time, not an expression containing a string.  This is
3322          because the latter will potentially produce pessimized code
3323          when used to produce the return value.  */
3324       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3325         return expand_movstr (dst, src, target, /*endp=*/2);
3326
3327       lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3328       ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3329                                          target, mode, /*endp=*/2);
3330
3331       if (ret)
3332         return ret;
3333
3334       if (TREE_CODE (len) == INTEGER_CST)
3335         {
3336           rtx len_rtx = expand_normal (len);
3337
3338           if (CONST_INT_P (len_rtx))
3339             {
3340               ret = expand_builtin_strcpy_args (dst, src, target);
3341
3342               if (ret)
3343                 {
3344                   if (! target)
3345                     {
3346                       if (mode != VOIDmode)
3347                         target = gen_reg_rtx (mode);
3348                       else
3349                         target = gen_reg_rtx (GET_MODE (ret));
3350                     }
3351                   if (GET_MODE (target) != GET_MODE (ret))
3352                     ret = gen_lowpart (GET_MODE (target), ret);
3353
3354                   ret = plus_constant (GET_MODE (ret), ret, INTVAL (len_rtx));
3355                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3356                   gcc_assert (ret);
3357
3358                   return target;
3359                 }
3360             }
3361         }
3362
3363       return expand_movstr (dst, src, target, /*endp=*/2);
3364     }
3365 }
3366
3367 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3368    bytes from constant string DATA + OFFSET and return it as target
3369    constant.  */
3370
3371 rtx
3372 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3373                           enum machine_mode mode)
3374 {
3375   const char *str = (const char *) data;
3376
3377   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3378     return const0_rtx;
3379
3380   return c_readstr (str + offset, mode);
3381 }
3382
3383 /* Expand expression EXP, which is a call to the strncpy builtin.  Return
3384    NULL_RTX if we failed the caller should emit a normal call.  */
3385
3386 static rtx
3387 expand_builtin_strncpy (tree exp, rtx target)
3388 {
3389   location_t loc = EXPR_LOCATION (exp);
3390
3391   if (validate_arglist (exp,
3392                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3393     {
3394       tree dest = CALL_EXPR_ARG (exp, 0);
3395       tree src = CALL_EXPR_ARG (exp, 1);
3396       tree len = CALL_EXPR_ARG (exp, 2);
3397       tree slen = c_strlen (src, 1);
3398
3399       /* We must be passed a constant len and src parameter.  */
3400       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3401         return NULL_RTX;
3402
3403       slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3404
3405       /* We're required to pad with trailing zeros if the requested
3406          len is greater than strlen(s2)+1.  In that case try to
3407          use store_by_pieces, if it fails, punt.  */
3408       if (tree_int_cst_lt (slen, len))
3409         {
3410           unsigned int dest_align = get_pointer_alignment (dest);
3411           const char *p = c_getstr (src);
3412           rtx dest_mem;
3413
3414           if (!p || dest_align == 0 || !host_integerp (len, 1)
3415               || !can_store_by_pieces (tree_low_cst (len, 1),
3416                                        builtin_strncpy_read_str,
3417                                        CONST_CAST (char *, p),
3418                                        dest_align, false))
3419             return NULL_RTX;
3420
3421           dest_mem = get_memory_rtx (dest, len);
3422           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3423                            builtin_strncpy_read_str,
3424                            CONST_CAST (char *, p), dest_align, false, 0);
3425           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3426           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3427           return dest_mem;
3428         }
3429     }
3430   return NULL_RTX;
3431 }
3432
3433 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3434    bytes from constant string DATA + OFFSET and return it as target
3435    constant.  */
3436
3437 rtx
3438 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3439                          enum machine_mode mode)
3440 {
3441   const char *c = (const char *) data;
3442   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3443
3444   memset (p, *c, GET_MODE_SIZE (mode));
3445
3446   return c_readstr (p, mode);
3447 }
3448
3449 /* Callback routine for store_by_pieces.  Return the RTL of a register
3450    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3451    char value given in the RTL register data.  For example, if mode is
3452    4 bytes wide, return the RTL for 0x01010101*data.  */
3453
3454 static rtx
3455 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3456                         enum machine_mode mode)
3457 {
3458   rtx target, coeff;
3459   size_t size;
3460   char *p;
3461
3462   size = GET_MODE_SIZE (mode);
3463   if (size == 1)
3464     return (rtx) data;
3465
3466   p = XALLOCAVEC (char, size);
3467   memset (p, 1, size);
3468   coeff = c_readstr (p, mode);
3469
3470   target = convert_to_mode (mode, (rtx) data, 1);
3471   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3472   return force_reg (mode, target);
3473 }
3474
3475 /* Expand expression EXP, which is a call to the memset builtin.  Return
3476    NULL_RTX if we failed the caller should emit a normal call, otherwise
3477    try to get the result in TARGET, if convenient (and in mode MODE if that's
3478    convenient).  */
3479
3480 static rtx
3481 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3482 {
3483   if (!validate_arglist (exp,
3484                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3485     return NULL_RTX;
3486   else
3487     {
3488       tree dest = CALL_EXPR_ARG (exp, 0);
3489       tree val = CALL_EXPR_ARG (exp, 1);
3490       tree len = CALL_EXPR_ARG (exp, 2);
3491       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3492     }
3493 }
3494
3495 /* Helper function to do the actual work for expand_builtin_memset.  The
3496    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3497    so that this can also be called without constructing an actual CALL_EXPR.
3498    The other arguments and return value are the same as for
3499    expand_builtin_memset.  */
3500
3501 static rtx
3502 expand_builtin_memset_args (tree dest, tree val, tree len,
3503                             rtx target, enum machine_mode mode, tree orig_exp)
3504 {
3505   tree fndecl, fn;
3506   enum built_in_function fcode;
3507   enum machine_mode val_mode;
3508   char c;
3509   unsigned int dest_align;
3510   rtx dest_mem, dest_addr, len_rtx;
3511   HOST_WIDE_INT expected_size = -1;
3512   unsigned int expected_align = 0;
3513
3514   dest_align = get_pointer_alignment (dest);
3515
3516   /* If DEST is not a pointer type, don't do this operation in-line.  */
3517   if (dest_align == 0)
3518     return NULL_RTX;
3519
3520   if (currently_expanding_gimple_stmt)
3521     stringop_block_profile (currently_expanding_gimple_stmt,
3522                             &expected_align, &expected_size);
3523
3524   if (expected_align < dest_align)
3525     expected_align = dest_align;
3526
3527   /* If the LEN parameter is zero, return DEST.  */
3528   if (integer_zerop (len))
3529     {
3530       /* Evaluate and ignore VAL in case it has side-effects.  */
3531       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3532       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3533     }
3534
3535   /* Stabilize the arguments in case we fail.  */
3536   dest = builtin_save_expr (dest);
3537   val = builtin_save_expr (val);
3538   len = builtin_save_expr (len);
3539
3540   len_rtx = expand_normal (len);
3541   dest_mem = get_memory_rtx (dest, len);
3542   val_mode = TYPE_MODE (unsigned_char_type_node);
3543
3544   if (TREE_CODE (val) != INTEGER_CST)
3545     {
3546       rtx val_rtx;
3547
3548       val_rtx = expand_normal (val);
3549       val_rtx = convert_to_mode (val_mode, val_rtx, 0);
3550
3551       /* Assume that we can memset by pieces if we can store
3552        * the coefficients by pieces (in the required modes).
3553        * We can't pass builtin_memset_gen_str as that emits RTL.  */
3554       c = 1;
3555       if (host_integerp (len, 1)
3556           && can_store_by_pieces (tree_low_cst (len, 1),
3557                                   builtin_memset_read_str, &c, dest_align,
3558                                   true))
3559         {
3560           val_rtx = force_reg (val_mode, val_rtx);
3561           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3562                            builtin_memset_gen_str, val_rtx, dest_align,
3563                            true, 0);
3564         }
3565       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3566                                         dest_align, expected_align,
3567                                         expected_size))
3568         goto do_libcall;
3569
3570       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3571       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3572       return dest_mem;
3573     }
3574
3575   if (target_char_cast (val, &c))
3576     goto do_libcall;
3577
3578   if (c)
3579     {
3580       if (host_integerp (len, 1)
3581           && can_store_by_pieces (tree_low_cst (len, 1),
3582                                   builtin_memset_read_str, &c, dest_align,
3583                                   true))
3584         store_by_pieces (dest_mem, tree_low_cst (len, 1),
3585                          builtin_memset_read_str, &c, dest_align, true, 0);
3586       else if (!set_storage_via_setmem (dest_mem, len_rtx,
3587                                         gen_int_mode (c, val_mode),
3588                                         dest_align, expected_align,
3589                                         expected_size))
3590         goto do_libcall;
3591
3592       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3593       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3594       return dest_mem;
3595     }
3596
3597   set_mem_align (dest_mem, dest_align);
3598   dest_addr = clear_storage_hints (dest_mem, len_rtx,
3599                                    CALL_EXPR_TAILCALL (orig_exp)
3600                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3601                                    expected_align, expected_size);
3602
3603   if (dest_addr == 0)
3604     {
3605       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3606       dest_addr = convert_memory_address (ptr_mode, dest_addr);
3607     }
3608
3609   return dest_addr;
3610
3611  do_libcall:
3612   fndecl = get_callee_fndecl (orig_exp);
3613   fcode = DECL_FUNCTION_CODE (fndecl);
3614   if (fcode == BUILT_IN_MEMSET)
3615     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 3,
3616                                 dest, val, len);
3617   else if (fcode == BUILT_IN_BZERO)
3618     fn = build_call_nofold_loc (EXPR_LOCATION (orig_exp), fndecl, 2,
3619                                 dest, len);
3620   else
3621     gcc_unreachable ();
3622   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3623   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3624   return expand_call (fn, target, target == const0_rtx);
3625 }
3626
3627 /* Expand expression EXP, which is a call to the bzero builtin.  Return
3628    NULL_RTX if we failed the caller should emit a normal call.  */
3629
3630 static rtx
3631 expand_builtin_bzero (tree exp)
3632 {
3633   tree dest, size;
3634   location_t loc = EXPR_LOCATION (exp);
3635
3636   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3637     return NULL_RTX;
3638
3639   dest = CALL_EXPR_ARG (exp, 0);
3640   size = CALL_EXPR_ARG (exp, 1);
3641
3642   /* New argument list transforming bzero(ptr x, int y) to
3643      memset(ptr x, int 0, size_t y).   This is done this way
3644      so that if it isn't expanded inline, we fallback to
3645      calling bzero instead of memset.  */
3646
3647   return expand_builtin_memset_args (dest, integer_zero_node,
3648                                      fold_convert_loc (loc,
3649                                                        size_type_node, size),
3650                                      const0_rtx, VOIDmode, exp);
3651 }
3652
3653 /* Expand expression EXP, which is a call to the memcmp built-in function.
3654    Return NULL_RTX if we failed and the caller should emit a normal call,
3655    otherwise try to get the result in TARGET, if convenient (and in mode
3656    MODE, if that's convenient).  */
3657
3658 static rtx
3659 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3660                        ATTRIBUTE_UNUSED enum machine_mode mode)
3661 {
3662   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3663
3664   if (!validate_arglist (exp,
3665                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3666     return NULL_RTX;
3667
3668   /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
3669      implementing memcmp because it will stop if it encounters two
3670      zero bytes.  */
3671 #if defined HAVE_cmpmemsi
3672   {
3673     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3674     rtx result;
3675     rtx insn;
3676     tree arg1 = CALL_EXPR_ARG (exp, 0);
3677     tree arg2 = CALL_EXPR_ARG (exp, 1);
3678     tree len = CALL_EXPR_ARG (exp, 2);
3679
3680     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3681     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3682     enum machine_mode insn_mode;
3683
3684     if (HAVE_cmpmemsi)
3685       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3686     else
3687       return NULL_RTX;
3688
3689     /* If we don't have POINTER_TYPE, call the function.  */
3690     if (arg1_align == 0 || arg2_align == 0)
3691       return NULL_RTX;
3692
3693     /* Make a place to write the result of the instruction.  */
3694     result = target;
3695     if (! (result != 0
3696            && REG_P (result) && GET_MODE (result) == insn_mode
3697            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3698       result = gen_reg_rtx (insn_mode);
3699
3700     arg1_rtx = get_memory_rtx (arg1, len);
3701     arg2_rtx = get_memory_rtx (arg2, len);
3702     arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3703
3704     /* Set MEM_SIZE as appropriate.  */
3705     if (CONST_INT_P (arg3_rtx))
3706       {
3707         set_mem_size (arg1_rtx, INTVAL (arg3_rtx));
3708         set_mem_size (arg2_rtx, INTVAL (arg3_rtx));
3709       }
3710
3711     if (HAVE_cmpmemsi)
3712       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3713                            GEN_INT (MIN (arg1_align, arg2_align)));
3714     else
3715       gcc_unreachable ();
3716
3717     if (insn)
3718       emit_insn (insn);
3719     else
3720       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3721                                TYPE_MODE (integer_type_node), 3,
3722                                XEXP (arg1_rtx, 0), Pmode,
3723                                XEXP (arg2_rtx, 0), Pmode,
3724                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3725                                                 TYPE_UNSIGNED (sizetype)),
3726                                TYPE_MODE (sizetype));
3727
3728     /* Return the value in the proper mode for this function.  */
3729     mode = TYPE_MODE (TREE_TYPE (exp));
3730     if (GET_MODE (result) == mode)
3731       return result;
3732     else if (target != 0)
3733       {
3734         convert_move (target, result, 0);
3735         return target;
3736       }
3737     else
3738       return convert_to_mode (mode, result, 0);
3739   }
3740 #endif /* HAVE_cmpmemsi.  */
3741
3742   return NULL_RTX;
3743 }
3744
3745 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
3746    if we failed the caller should emit a normal call, otherwise try to get
3747    the result in TARGET, if convenient.  */
3748
3749 static rtx
3750 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3751 {
3752   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3753     return NULL_RTX;
3754
3755 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3756   if (direct_optab_handler (cmpstr_optab, SImode) != CODE_FOR_nothing
3757       || direct_optab_handler (cmpstrn_optab, SImode) != CODE_FOR_nothing)
3758     {
3759       rtx arg1_rtx, arg2_rtx;
3760       rtx result, insn = NULL_RTX;
3761       tree fndecl, fn;
3762       tree arg1 = CALL_EXPR_ARG (exp, 0);
3763       tree arg2 = CALL_EXPR_ARG (exp, 1);
3764
3765       unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3766       unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3767
3768       /* If we don't have POINTER_TYPE, call the function.  */
3769       if (arg1_align == 0 || arg2_align == 0)
3770         return NULL_RTX;
3771
3772       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
3773       arg1 = builtin_save_expr (arg1);
3774       arg2 = builtin_save_expr (arg2);
3775
3776       arg1_rtx = get_memory_rtx (arg1, NULL);
3777       arg2_rtx = get_memory_rtx (arg2, NULL);
3778
3779 #ifdef HAVE_cmpstrsi
3780       /* Try to call cmpstrsi.  */
3781       if (HAVE_cmpstrsi)
3782         {
3783           enum machine_mode insn_mode
3784             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3785
3786           /* Make a place to write the result of the instruction.  */
3787           result = target;
3788           if (! (result != 0
3789                  && REG_P (result) && GET_MODE (result) == insn_mode
3790                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3791             result = gen_reg_rtx (insn_mode);
3792
3793           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
3794                                GEN_INT (MIN (arg1_align, arg2_align)));
3795         }
3796 #endif
3797 #ifdef HAVE_cmpstrnsi
3798       /* Try to determine at least one length and call cmpstrnsi.  */
3799       if (!insn && HAVE_cmpstrnsi)
3800         {
3801           tree len;
3802           rtx arg3_rtx;
3803
3804           enum machine_mode insn_mode
3805             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3806           tree len1 = c_strlen (arg1, 1);
3807           tree len2 = c_strlen (arg2, 1);
3808
3809           if (len1)
3810             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3811           if (len2)
3812             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3813
3814           /* If we don't have a constant length for the first, use the length
3815              of the second, if we know it.  We don't require a constant for
3816              this case; some cost analysis could be done if both are available
3817              but neither is constant.  For now, assume they're equally cheap,
3818              unless one has side effects.  If both strings have constant lengths,
3819              use the smaller.  */
3820
3821           if (!len1)
3822             len = len2;
3823           else if (!len2)
3824             len = len1;
3825           else if (TREE_SIDE_EFFECTS (len1))
3826             len = len2;
3827           else if (TREE_SIDE_EFFECTS (len2))
3828             len = len1;
3829           else if (TREE_CODE (len1) != INTEGER_CST)
3830             len = len2;
3831           else if (TREE_CODE (len2) != INTEGER_CST)
3832             len = len1;
3833           else if (tree_int_cst_lt (len1, len2))
3834             len = len1;
3835           else
3836             len = len2;
3837
3838           /* If both arguments have side effects, we cannot optimize.  */
3839           if (!len || TREE_SIDE_EFFECTS (len))
3840             goto do_libcall;
3841
3842           arg3_rtx = expand_normal (len);
3843
3844           /* Make a place to write the result of the instruction.  */
3845           result = target;
3846           if (! (result != 0
3847                  && REG_P (result) && GET_MODE (result) == insn_mode
3848                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3849             result = gen_reg_rtx (insn_mode);
3850
3851           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3852                                 GEN_INT (MIN (arg1_align, arg2_align)));
3853         }
3854 #endif
3855
3856       if (insn)
3857         {
3858           enum machine_mode mode;
3859           emit_insn (insn);
3860
3861           /* Return the value in the proper mode for this function.  */
3862           mode = TYPE_MODE (TREE_TYPE (exp));
3863           if (GET_MODE (result) == mode)
3864             return result;
3865           if (target == 0)
3866             return convert_to_mode (mode, result, 0);
3867           convert_move (target, result, 0);
3868           return target;
3869         }
3870
3871       /* Expand the library call ourselves using a stabilized argument
3872          list to avoid re-evaluating the function's arguments twice.  */
3873 #ifdef HAVE_cmpstrnsi
3874     do_libcall:
3875 #endif
3876       fndecl = get_callee_fndecl (exp);
3877       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 2, arg1, arg2);
3878       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3879       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
3880       return expand_call (fn, target, target == const0_rtx);
3881     }
3882 #endif
3883   return NULL_RTX;
3884 }
3885
3886 /* Expand expression EXP, which is a call to the strncmp builtin. Return
3887    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
3888    the result in TARGET, if convenient.  */
3889
3890 static rtx
3891 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3892                         ATTRIBUTE_UNUSED enum machine_mode mode)
3893 {
3894   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3895
3896   if (!validate_arglist (exp,
3897                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3898     return NULL_RTX;
3899
3900   /* If c_strlen can determine an expression for one of the string
3901      lengths, and it doesn't have side effects, then emit cmpstrnsi
3902      using length MIN(strlen(string)+1, arg3).  */
3903 #ifdef HAVE_cmpstrnsi
3904   if (HAVE_cmpstrnsi)
3905   {
3906     tree len, len1, len2;
3907     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3908     rtx result, insn;
3909     tree fndecl, fn;
3910     tree arg1 = CALL_EXPR_ARG (exp, 0);
3911     tree arg2 = CALL_EXPR_ARG (exp, 1);
3912     tree arg3 = CALL_EXPR_ARG (exp, 2);
3913
3914     unsigned int arg1_align = get_pointer_alignment (arg1) / BITS_PER_UNIT;
3915     unsigned int arg2_align = get_pointer_alignment (arg2) / BITS_PER_UNIT;
3916     enum machine_mode insn_mode
3917       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3918
3919     len1 = c_strlen (arg1, 1);
3920     len2 = c_strlen (arg2, 1);
3921
3922     if (len1)
3923       len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
3924     if (len2)
3925       len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
3926
3927     /* If we don't have a constant length for the first, use the length
3928        of the second, if we know it.  We don't require a constant for
3929        this case; some cost analysis could be done if both are available
3930        but neither is constant.  For now, assume they're equally cheap,
3931        unless one has side effects.  If both strings have constant lengths,
3932        use the smaller.  */
3933
3934     if (!len1)
3935       len = len2;
3936     else if (!len2)
3937       len = len1;
3938     else if (TREE_SIDE_EFFECTS (len1))
3939       len = len2;
3940     else if (TREE_SIDE_EFFECTS (len2))
3941       len = len1;
3942     else if (TREE_CODE (len1) != INTEGER_CST)
3943       len = len2;
3944     else if (TREE_CODE (len2) != INTEGER_CST)
3945       len = len1;
3946     else if (tree_int_cst_lt (len1, len2))
3947       len = len1;
3948     else
3949       len = len2;
3950
3951     /* If both arguments have side effects, we cannot optimize.  */
3952     if (!len || TREE_SIDE_EFFECTS (len))
3953       return NULL_RTX;
3954
3955     /* The actual new length parameter is MIN(len,arg3).  */
3956     len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
3957                        fold_convert_loc (loc, TREE_TYPE (len), arg3));
3958
3959     /* If we don't have POINTER_TYPE, call the function.  */
3960     if (arg1_align == 0 || arg2_align == 0)
3961       return NULL_RTX;
3962
3963     /* Make a place to write the result of the instruction.  */
3964     result = target;
3965     if (! (result != 0
3966            && REG_P (result) && GET_MODE (result) == insn_mode
3967            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3968       result = gen_reg_rtx (insn_mode);
3969
3970     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
3971     arg1 = builtin_save_expr (arg1);
3972     arg2 = builtin_save_expr (arg2);
3973     len = builtin_save_expr (len);
3974
3975     arg1_rtx = get_memory_rtx (arg1, len);
3976     arg2_rtx = get_memory_rtx (arg2, len);
3977     arg3_rtx = expand_normal (len);
3978     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3979                           GEN_INT (MIN (arg1_align, arg2_align)));
3980     if (insn)
3981       {
3982         emit_insn (insn);
3983
3984         /* Return the value in the proper mode for this function.  */
3985         mode = TYPE_MODE (TREE_TYPE (exp));
3986         if (GET_MODE (result) == mode)
3987           return result;
3988         if (target == 0)
3989           return convert_to_mode (mode, result, 0);
3990         convert_move (target, result, 0);
3991         return target;
3992       }
3993
3994     /* Expand the library call ourselves using a stabilized argument
3995        list to avoid re-evaluating the function's arguments twice.  */
3996     fndecl = get_callee_fndecl (exp);
3997     fn = build_call_nofold_loc (EXPR_LOCATION (exp), fndecl, 3,
3998                                 arg1, arg2, len);
3999     gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4000     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4001     return expand_call (fn, target, target == const0_rtx);
4002   }
4003 #endif
4004   return NULL_RTX;
4005 }
4006
4007 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4008    if that's convenient.  */
4009
4010 rtx
4011 expand_builtin_saveregs (void)
4012 {
4013   rtx val, seq;
4014
4015   /* Don't do __builtin_saveregs more than once in a function.
4016      Save the result of the first call and reuse it.  */
4017   if (saveregs_value != 0)
4018     return saveregs_value;
4019
4020   /* When this function is called, it means that registers must be
4021      saved on entry to this function.  So we migrate the call to the
4022      first insn of this function.  */
4023
4024   start_sequence ();
4025
4026   /* Do whatever the machine needs done in this case.  */
4027   val = targetm.calls.expand_builtin_saveregs ();
4028
4029   seq = get_insns ();
4030   end_sequence ();
4031
4032   saveregs_value = val;
4033
4034   /* Put the insns after the NOTE that starts the function.  If this
4035      is inside a start_sequence, make the outer-level insn chain current, so
4036      the code is placed at the start of the function.  */
4037   push_topmost_sequence ();
4038   emit_insn_after (seq, entry_of_function ());
4039   pop_topmost_sequence ();
4040
4041   return val;
4042 }
4043
4044 /* Expand a call to __builtin_next_arg.  */
4045
4046 static rtx
4047 expand_builtin_next_arg (void)
4048 {
4049   /* Checking arguments is already done in fold_builtin_next_arg
4050      that must be called before this function.  */
4051   return expand_binop (ptr_mode, add_optab,
4052                        crtl->args.internal_arg_pointer,
4053                        crtl->args.arg_offset_rtx,
4054                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4055 }
4056
4057 /* Make it easier for the backends by protecting the valist argument
4058    from multiple evaluations.  */
4059
4060 static tree
4061 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4062 {
4063   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4064
4065   /* The current way of determining the type of valist is completely
4066      bogus.  We should have the information on the va builtin instead.  */
4067   if (!vatype)
4068     vatype = targetm.fn_abi_va_list (cfun->decl);
4069
4070   if (TREE_CODE (vatype) == ARRAY_TYPE)
4071     {
4072       if (TREE_SIDE_EFFECTS (valist))
4073         valist = save_expr (valist);
4074
4075       /* For this case, the backends will be expecting a pointer to
4076          vatype, but it's possible we've actually been given an array
4077          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4078          So fix it.  */
4079       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4080         {
4081           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4082           valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4083         }
4084     }
4085   else
4086     {
4087       tree pt = build_pointer_type (vatype);
4088
4089       if (! needs_lvalue)
4090         {
4091           if (! TREE_SIDE_EFFECTS (valist))
4092             return valist;
4093
4094           valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4095           TREE_SIDE_EFFECTS (valist) = 1;
4096         }
4097
4098       if (TREE_SIDE_EFFECTS (valist))
4099         valist = save_expr (valist);
4100       valist = fold_build2_loc (loc, MEM_REF,
4101                                 vatype, valist, build_int_cst (pt, 0));
4102     }
4103
4104   return valist;
4105 }
4106
4107 /* The "standard" definition of va_list is void*.  */
4108
4109 tree
4110 std_build_builtin_va_list (void)
4111 {
4112   return ptr_type_node;
4113 }
4114
4115 /* The "standard" abi va_list is va_list_type_node.  */
4116
4117 tree
4118 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4119 {
4120   return va_list_type_node;
4121 }
4122
4123 /* The "standard" type of va_list is va_list_type_node.  */
4124
4125 tree
4126 std_canonical_va_list_type (tree type)
4127 {
4128   tree wtype, htype;
4129
4130   if (INDIRECT_REF_P (type))
4131     type = TREE_TYPE (type);
4132   else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4133     type = TREE_TYPE (type);
4134   wtype = va_list_type_node;
4135   htype = type;
4136   /* Treat structure va_list types.  */
4137   if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4138     htype = TREE_TYPE (htype);
4139   else if (TREE_CODE (wtype) == ARRAY_TYPE)
4140     {
4141       /* If va_list is an array type, the argument may have decayed
4142          to a pointer type, e.g. by being passed to another function.
4143          In that case, unwrap both types so that we can compare the
4144          underlying records.  */
4145       if (TREE_CODE (htype) == ARRAY_TYPE
4146           || POINTER_TYPE_P (htype))
4147         {
4148           wtype = TREE_TYPE (wtype);
4149           htype = TREE_TYPE (htype);
4150         }
4151     }
4152   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4153     return va_list_type_node;
4154
4155   return NULL_TREE;
4156 }
4157
4158 /* The "standard" implementation of va_start: just assign `nextarg' to
4159    the variable.  */
4160
4161 void
4162 std_expand_builtin_va_start (tree valist, rtx nextarg)
4163 {
4164   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4165   convert_move (va_r, nextarg, 0);
4166 }
4167
4168 /* Expand EXP, a call to __builtin_va_start.  */
4169
4170 static rtx
4171 expand_builtin_va_start (tree exp)
4172 {
4173   rtx nextarg;
4174   tree valist;
4175   location_t loc = EXPR_LOCATION (exp);
4176
4177   if (call_expr_nargs (exp) < 2)
4178     {
4179       error_at (loc, "too few arguments to function %<va_start%>");
4180       return const0_rtx;
4181     }
4182
4183   if (fold_builtin_next_arg (exp, true))
4184     return const0_rtx;
4185
4186   nextarg = expand_builtin_next_arg ();
4187   valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4188
4189   if (targetm.expand_builtin_va_start)
4190     targetm.expand_builtin_va_start (valist, nextarg);
4191   else
4192     std_expand_builtin_va_start (valist, nextarg);
4193
4194   return const0_rtx;
4195 }
4196
4197 /* The "standard" implementation of va_arg: read the value from the
4198    current (padded) address and increment by the (padded) size.  */
4199
4200 tree
4201 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4202                           gimple_seq *post_p)
4203 {
4204   tree addr, t, type_size, rounded_size, valist_tmp;
4205   unsigned HOST_WIDE_INT align, boundary;
4206   bool indirect;
4207
4208 #ifdef ARGS_GROW_DOWNWARD
4209   /* All of the alignment and movement below is for args-grow-up machines.
4210      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4211      implement their own specialized gimplify_va_arg_expr routines.  */
4212   gcc_unreachable ();
4213 #endif
4214
4215   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4216   if (indirect)
4217     type = build_pointer_type (type);
4218
4219   align = PARM_BOUNDARY / BITS_PER_UNIT;
4220   boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type);
4221
4222   /* When we align parameter on stack for caller, if the parameter
4223      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4224      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4225      here with caller.  */
4226   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4227     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4228
4229   boundary /= BITS_PER_UNIT;
4230
4231   /* Hoist the valist value into a temporary for the moment.  */
4232   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4233
4234   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4235      requires greater alignment, we must perform dynamic alignment.  */
4236   if (boundary > align
4237       && !integer_zerop (TYPE_SIZE (type)))
4238     {
4239       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4240                   fold_build_pointer_plus_hwi (valist_tmp, boundary - 1));
4241       gimplify_and_add (t, pre_p);
4242
4243       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4244                   fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
4245                                valist_tmp,
4246                                build_int_cst (TREE_TYPE (valist), -boundary)));
4247       gimplify_and_add (t, pre_p);
4248     }
4249   else
4250     boundary = align;
4251
4252   /* If the actual alignment is less than the alignment of the type,
4253      adjust the type accordingly so that we don't assume strict alignment
4254      when dereferencing the pointer.  */
4255   boundary *= BITS_PER_UNIT;
4256   if (boundary < TYPE_ALIGN (type))
4257     {
4258       type = build_variant_type_copy (type);
4259       TYPE_ALIGN (type) = boundary;
4260     }
4261
4262   /* Compute the rounded size of the type.  */
4263   type_size = size_in_bytes (type);
4264   rounded_size = round_up (type_size, align);
4265
4266   /* Reduce rounded_size so it's sharable with the postqueue.  */
4267   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4268
4269   /* Get AP.  */
4270   addr = valist_tmp;
4271   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4272     {
4273       /* Small args are padded downward.  */
4274       t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4275                        rounded_size, size_int (align));
4276       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4277                        size_binop (MINUS_EXPR, rounded_size, type_size));
4278       addr = fold_build_pointer_plus (addr, t);
4279     }
4280
4281   /* Compute new value for AP.  */
4282   t = fold_build_pointer_plus (valist_tmp, rounded_size);
4283   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4284   gimplify_and_add (t, pre_p);
4285
4286   addr = fold_convert (build_pointer_type (type), addr);
4287
4288   if (indirect)
4289     addr = build_va_arg_indirect_ref (addr);
4290
4291   return build_va_arg_indirect_ref (addr);
4292 }
4293
4294 /* Build an indirect-ref expression over the given TREE, which represents a
4295    piece of a va_arg() expansion.  */
4296 tree
4297 build_va_arg_indirect_ref (tree addr)
4298 {
4299   addr = build_simple_mem_ref_loc (EXPR_LOCATION (addr), addr);
4300
4301   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4302     mf_mark (addr);
4303
4304   return addr;
4305 }
4306
4307 /* Return a dummy expression of type TYPE in order to keep going after an
4308    error.  */
4309
4310 static tree
4311 dummy_object (tree type)
4312 {
4313   tree t = build_int_cst (build_pointer_type (type), 0);
4314   return build2 (MEM_REF, type, t, t);
4315 }
4316
4317 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4318    builtin function, but a very special sort of operator.  */
4319
4320 enum gimplify_status
4321 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4322 {
4323   tree promoted_type, have_va_type;
4324   tree valist = TREE_OPERAND (*expr_p, 0);
4325   tree type = TREE_TYPE (*expr_p);
4326   tree t;
4327   location_t loc = EXPR_LOCATION (*expr_p);
4328
4329   /* Verify that valist is of the proper type.  */
4330   have_va_type = TREE_TYPE (valist);
4331   if (have_va_type == error_mark_node)
4332     return GS_ERROR;
4333   have_va_type = targetm.canonical_va_list_type (have_va_type);
4334
4335   if (have_va_type == NULL_TREE)
4336     {
4337       error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4338       return GS_ERROR;
4339     }
4340
4341   /* Generate a diagnostic for requesting data of a type that cannot
4342      be passed through `...' due to type promotion at the call site.  */
4343   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4344            != type)
4345     {
4346       static bool gave_help;
4347       bool warned;
4348
4349       /* Unfortunately, this is merely undefined, rather than a constraint
4350          violation, so we cannot make this an error.  If this call is never
4351          executed, the program is still strictly conforming.  */
4352       warned = warning_at (loc, 0,
4353                            "%qT is promoted to %qT when passed through %<...%>",
4354                            type, promoted_type);
4355       if (!gave_help && warned)
4356         {
4357           gave_help = true;
4358           inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4359                   promoted_type, type);
4360         }
4361
4362       /* We can, however, treat "undefined" any way we please.
4363          Call abort to encourage the user to fix the program.  */
4364       if (warned)
4365         inform (loc, "if this code is reached, the program will abort");
4366       /* Before the abort, allow the evaluation of the va_list
4367          expression to exit or longjmp.  */
4368       gimplify_and_add (valist, pre_p);
4369       t = build_call_expr_loc (loc,
4370                                builtin_decl_implicit (BUILT_IN_TRAP), 0);
4371       gimplify_and_add (t, pre_p);
4372
4373       /* This is dead code, but go ahead and finish so that the
4374          mode of the result comes out right.  */
4375       *expr_p = dummy_object (type);
4376       return GS_ALL_DONE;
4377     }
4378   else
4379     {
4380       /* Make it easier for the backends by protecting the valist argument
4381          from multiple evaluations.  */
4382       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4383         {
4384           /* For this case, the backends will be expecting a pointer to
4385              TREE_TYPE (abi), but it's possible we've
4386              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4387              So fix it.  */
4388           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4389             {
4390               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4391               valist = fold_convert_loc (loc, p1,
4392                                          build_fold_addr_expr_loc (loc, valist));
4393             }
4394
4395           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4396         }
4397       else
4398         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4399
4400       if (!targetm.gimplify_va_arg_expr)
4401         /* FIXME: Once most targets are converted we should merely
4402            assert this is non-null.  */
4403         return GS_ALL_DONE;
4404
4405       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4406       return GS_OK;
4407     }
4408 }
4409
4410 /* Expand EXP, a call to __builtin_va_end.  */
4411
4412 static rtx
4413 expand_builtin_va_end (tree exp)
4414 {
4415   tree valist = CALL_EXPR_ARG (exp, 0);
4416
4417   /* Evaluate for side effects, if needed.  I hate macros that don't
4418      do that.  */
4419   if (TREE_SIDE_EFFECTS (valist))
4420     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4421
4422   return const0_rtx;
4423 }
4424
4425 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
4426    builtin rather than just as an assignment in stdarg.h because of the
4427    nastiness of array-type va_list types.  */
4428
4429 static rtx
4430 expand_builtin_va_copy (tree exp)
4431 {
4432   tree dst, src, t;
4433   location_t loc = EXPR_LOCATION (exp);
4434
4435   dst = CALL_EXPR_ARG (exp, 0);
4436   src = CALL_EXPR_ARG (exp, 1);
4437
4438   dst = stabilize_va_list_loc (loc, dst, 1);
4439   src = stabilize_va_list_loc (loc, src, 0);
4440
4441   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4442
4443   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4444     {
4445       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4446       TREE_SIDE_EFFECTS (t) = 1;
4447       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4448     }
4449   else
4450     {
4451       rtx dstb, srcb, size;
4452
4453       /* Evaluate to pointers.  */
4454       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4455       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4456       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4457                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
4458
4459       dstb = convert_memory_address (Pmode, dstb);
4460       srcb = convert_memory_address (Pmode, srcb);
4461
4462       /* "Dereference" to BLKmode memories.  */
4463       dstb = gen_rtx_MEM (BLKmode, dstb);
4464       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4465       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4466       srcb = gen_rtx_MEM (BLKmode, srcb);
4467       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4468       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4469
4470       /* Copy.  */
4471       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4472     }
4473
4474   return const0_rtx;
4475 }
4476
4477 /* Expand a call to one of the builtin functions __builtin_frame_address or
4478    __builtin_return_address.  */
4479
4480 static rtx
4481 expand_builtin_frame_address (tree fndecl, tree exp)
4482 {
4483   /* The argument must be a nonnegative integer constant.
4484      It counts the number of frames to scan up the stack.
4485      The value is the return address saved in that frame.  */
4486   if (call_expr_nargs (exp) == 0)
4487     /* Warning about missing arg was already issued.  */
4488     return const0_rtx;
4489   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4490     {
4491       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4492         error ("invalid argument to %<__builtin_frame_address%>");
4493       else
4494         error ("invalid argument to %<__builtin_return_address%>");
4495       return const0_rtx;
4496     }
4497   else
4498     {
4499       rtx tem
4500         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4501                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4502
4503       /* Some ports cannot access arbitrary stack frames.  */
4504       if (tem == NULL)
4505         {
4506           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4507             warning (0, "unsupported argument to %<__builtin_frame_address%>");
4508           else
4509             warning (0, "unsupported argument to %<__builtin_return_address%>");
4510           return const0_rtx;
4511         }
4512
4513       /* For __builtin_frame_address, return what we've got.  */
4514       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4515         return tem;
4516
4517       if (!REG_P (tem)
4518           && ! CONSTANT_P (tem))
4519         tem = copy_addr_to_reg (tem);
4520       return tem;
4521     }
4522 }
4523
4524 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if we
4525    failed and the caller should emit a normal call.  CANNOT_ACCUMULATE
4526    is the same as for allocate_dynamic_stack_space.  */
4527
4528 static rtx
4529 expand_builtin_alloca (tree exp, bool cannot_accumulate)
4530 {
4531   rtx op0;
4532   rtx result;
4533   bool valid_arglist;
4534   unsigned int align;
4535   bool alloca_with_align = (DECL_FUNCTION_CODE (get_callee_fndecl (exp))
4536                             == BUILT_IN_ALLOCA_WITH_ALIGN);
4537
4538   /* Emit normal call if we use mudflap.  */
4539   if (flag_mudflap)
4540     return NULL_RTX;
4541
4542   valid_arglist
4543     = (alloca_with_align
4544        ? validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE)
4545        : validate_arglist (exp, INTEGER_TYPE, VOID_TYPE));
4546
4547   if (!valid_arglist)
4548     return NULL_RTX;
4549
4550   /* Compute the argument.  */
4551   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4552
4553   /* Compute the alignment.  */
4554   align = (alloca_with_align
4555            ? TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1))
4556            : BIGGEST_ALIGNMENT);
4557
4558   /* Allocate the desired space.  */
4559   result = allocate_dynamic_stack_space (op0, 0, align, cannot_accumulate);
4560   result = convert_memory_address (ptr_mode, result);
4561
4562   return result;
4563 }
4564
4565 /* Expand a call to bswap builtin in EXP.
4566    Return NULL_RTX if a normal call should be emitted rather than expanding the
4567    function in-line.  If convenient, the result should be placed in TARGET.
4568    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4569
4570 static rtx
4571 expand_builtin_bswap (enum machine_mode target_mode, tree exp, rtx target,
4572                       rtx subtarget)
4573 {
4574   tree arg;
4575   rtx op0;
4576
4577   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4578     return NULL_RTX;
4579
4580   arg = CALL_EXPR_ARG (exp, 0);
4581   op0 = expand_expr (arg,
4582                      subtarget && GET_MODE (subtarget) == target_mode
4583                      ? subtarget : NULL_RTX,
4584                      target_mode, EXPAND_NORMAL);
4585   if (GET_MODE (op0) != target_mode)
4586     op0 = convert_to_mode (target_mode, op0, 1);
4587
4588   target = expand_unop (target_mode, bswap_optab, op0, target, 1);
4589
4590   gcc_assert (target);
4591
4592   return convert_to_mode (target_mode, target, 1);
4593 }
4594
4595 /* Expand a call to a unary builtin in EXP.
4596    Return NULL_RTX if a normal call should be emitted rather than expanding the
4597    function in-line.  If convenient, the result should be placed in TARGET.
4598    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4599
4600 static rtx
4601 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4602                      rtx subtarget, optab op_optab)
4603 {
4604   rtx op0;
4605
4606   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4607     return NULL_RTX;
4608
4609   /* Compute the argument.  */
4610   op0 = expand_expr (CALL_EXPR_ARG (exp, 0),
4611                      (subtarget
4612                       && (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0)))
4613                           == GET_MODE (subtarget))) ? subtarget : NULL_RTX,
4614                      VOIDmode, EXPAND_NORMAL);
4615   /* Compute op, into TARGET if possible.
4616      Set TARGET to wherever the result comes back.  */
4617   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4618                         op_optab, op0, target, op_optab != clrsb_optab);
4619   gcc_assert (target);
4620
4621   return convert_to_mode (target_mode, target, 0);
4622 }
4623
4624 /* Expand a call to __builtin_expect.  We just return our argument
4625    as the builtin_expect semantic should've been already executed by
4626    tree branch prediction pass. */
4627
4628 static rtx
4629 expand_builtin_expect (tree exp, rtx target)
4630 {
4631   tree arg;
4632
4633   if (call_expr_nargs (exp) < 2)
4634     return const0_rtx;
4635   arg = CALL_EXPR_ARG (exp, 0);
4636
4637   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4638   /* When guessing was done, the hints should be already stripped away.  */
4639   gcc_assert (!flag_guess_branch_prob
4640               || optimize == 0 || seen_error ());
4641   return target;
4642 }
4643
4644 /* Expand a call to __builtin_assume_aligned.  We just return our first
4645    argument as the builtin_assume_aligned semantic should've been already
4646    executed by CCP.  */
4647
4648 static rtx
4649 expand_builtin_assume_aligned (tree exp, rtx target)
4650 {
4651   if (call_expr_nargs (exp) < 2)
4652     return const0_rtx;
4653   target = expand_expr (CALL_EXPR_ARG (exp, 0), target, VOIDmode,
4654                         EXPAND_NORMAL);
4655   gcc_assert (!TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 1))
4656               && (call_expr_nargs (exp) < 3
4657                   || !TREE_SIDE_EFFECTS (CALL_EXPR_ARG (exp, 2))));
4658   return target;
4659 }
4660
4661 void
4662 expand_builtin_trap (void)
4663 {
4664 #ifdef HAVE_trap
4665   if (HAVE_trap)
4666     {
4667       rtx insn = emit_insn (gen_trap ());
4668       /* For trap insns when not accumulating outgoing args force
4669          REG_ARGS_SIZE note to prevent crossjumping of calls with
4670          different args sizes.  */
4671       if (!ACCUMULATE_OUTGOING_ARGS)
4672         add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
4673     }
4674   else
4675 #endif
4676     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4677   emit_barrier ();
4678 }
4679
4680 /* Expand a call to __builtin_unreachable.  We do nothing except emit
4681    a barrier saying that control flow will not pass here.
4682
4683    It is the responsibility of the program being compiled to ensure
4684    that control flow does never reach __builtin_unreachable.  */
4685 static void
4686 expand_builtin_unreachable (void)
4687 {
4688   emit_barrier ();
4689 }
4690
4691 /* Expand EXP, a call to fabs, fabsf or fabsl.
4692    Return NULL_RTX if a normal call should be emitted rather than expanding
4693    the function inline.  If convenient, the result should be placed
4694    in TARGET.  SUBTARGET may be used as the target for computing
4695    the operand.  */
4696
4697 static rtx
4698 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4699 {
4700   enum machine_mode mode;
4701   tree arg;
4702   rtx op0;
4703
4704   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4705     return NULL_RTX;
4706
4707   arg = CALL_EXPR_ARG (exp, 0);
4708   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4709   mode = TYPE_MODE (TREE_TYPE (arg));
4710   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4711   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4712 }
4713
4714 /* Expand EXP, a call to copysign, copysignf, or copysignl.
4715    Return NULL is a normal call should be emitted rather than expanding the
4716    function inline.  If convenient, the result should be placed in TARGET.
4717    SUBTARGET may be used as the target for computing the operand.  */
4718
4719 static rtx
4720 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4721 {
4722   rtx op0, op1;
4723   tree arg;
4724
4725   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4726     return NULL_RTX;
4727
4728   arg = CALL_EXPR_ARG (exp, 0);
4729   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4730
4731   arg = CALL_EXPR_ARG (exp, 1);
4732   op1 = expand_normal (arg);
4733
4734   return expand_copysign (op0, op1, target);
4735 }
4736
4737 /* Create a new constant string literal and return a char* pointer to it.
4738    The STRING_CST value is the LEN characters at STR.  */
4739 tree
4740 build_string_literal (int len, const char *str)
4741 {
4742   tree t, elem, index, type;
4743
4744   t = build_string (len, str);
4745   elem = build_type_variant (char_type_node, 1, 0);
4746   index = build_index_type (size_int (len - 1));
4747   type = build_array_type (elem, index);
4748   TREE_TYPE (t) = type;
4749   TREE_CONSTANT (t) = 1;
4750   TREE_READONLY (t) = 1;
4751   TREE_STATIC (t) = 1;
4752
4753   type = build_pointer_type (elem);
4754   t = build1 (ADDR_EXPR, type,
4755               build4 (ARRAY_REF, elem,
4756                       t, integer_zero_node, NULL_TREE, NULL_TREE));
4757   return t;
4758 }
4759
4760 /* Expand a call to __builtin___clear_cache.  */
4761
4762 static rtx
4763 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
4764 {
4765 #ifndef HAVE_clear_cache
4766 #ifdef CLEAR_INSN_CACHE
4767   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4768      does something.  Just do the default expansion to a call to
4769      __clear_cache().  */
4770   return NULL_RTX;
4771 #else
4772   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
4773      does nothing.  There is no need to call it.  Do nothing.  */
4774   return const0_rtx;
4775 #endif /* CLEAR_INSN_CACHE */
4776 #else
4777   /* We have a "clear_cache" insn, and it will handle everything.  */
4778   tree begin, end;
4779   rtx begin_rtx, end_rtx;
4780
4781   /* We must not expand to a library call.  If we did, any
4782      fallback library function in libgcc that might contain a call to
4783      __builtin___clear_cache() would recurse infinitely.  */
4784   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4785     {
4786       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
4787       return const0_rtx;
4788     }
4789
4790   if (HAVE_clear_cache)
4791     {
4792       struct expand_operand ops[2];
4793
4794       begin = CALL_EXPR_ARG (exp, 0);
4795       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
4796
4797       end = CALL_EXPR_ARG (exp, 1);
4798       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
4799
4800       create_address_operand (&ops[0], begin_rtx);
4801       create_address_operand (&ops[1], end_rtx);
4802       if (maybe_expand_insn (CODE_FOR_clear_cache, 2, ops))
4803         return const0_rtx;
4804     }
4805   return const0_rtx;
4806 #endif /* HAVE_clear_cache */
4807 }
4808
4809 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4810
4811 static rtx
4812 round_trampoline_addr (rtx tramp)
4813 {
4814   rtx temp, addend, mask;
4815
4816   /* If we don't need too much alignment, we'll have been guaranteed
4817      proper alignment by get_trampoline_type.  */
4818   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4819     return tramp;
4820
4821   /* Round address up to desired boundary.  */
4822   temp = gen_reg_rtx (Pmode);
4823   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4824   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4825
4826   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4827                                temp, 0, OPTAB_LIB_WIDEN);
4828   tramp = expand_simple_binop (Pmode, AND, temp, mask,
4829                                temp, 0, OPTAB_LIB_WIDEN);
4830
4831   return tramp;
4832 }
4833
4834 static rtx
4835 expand_builtin_init_trampoline (tree exp, bool onstack)
4836 {
4837   tree t_tramp, t_func, t_chain;
4838   rtx m_tramp, r_tramp, r_chain, tmp;
4839
4840   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
4841                          POINTER_TYPE, VOID_TYPE))
4842     return NULL_RTX;
4843
4844   t_tramp = CALL_EXPR_ARG (exp, 0);
4845   t_func = CALL_EXPR_ARG (exp, 1);
4846   t_chain = CALL_EXPR_ARG (exp, 2);
4847
4848   r_tramp = expand_normal (t_tramp);
4849   m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
4850   MEM_NOTRAP_P (m_tramp) = 1;
4851
4852   /* If ONSTACK, the TRAMP argument should be the address of a field
4853      within the local function's FRAME decl.  Either way, let's see if
4854      we can fill in the MEM_ATTRs for this memory.  */
4855   if (TREE_CODE (t_tramp) == ADDR_EXPR)
4856     set_mem_attributes (m_tramp, TREE_OPERAND (t_tramp, 0), true);
4857
4858   /* Creator of a heap trampoline is responsible for making sure the
4859      address is aligned to at least STACK_BOUNDARY.  Normally malloc
4860      will ensure this anyhow.  */
4861   tmp = round_trampoline_addr (r_tramp);
4862   if (tmp != r_tramp)
4863     {
4864       m_tramp = change_address (m_tramp, BLKmode, tmp);
4865       set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
4866       set_mem_size (m_tramp, TRAMPOLINE_SIZE);
4867     }
4868
4869   /* The FUNC argument should be the address of the nested function.
4870      Extract the actual function decl to pass to the hook.  */
4871   gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
4872   t_func = TREE_OPERAND (t_func, 0);
4873   gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
4874
4875   r_chain = expand_normal (t_chain);
4876
4877   /* Generate insns to initialize the trampoline.  */
4878   targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
4879
4880   if (onstack)
4881     {
4882       trampolines_created = 1;
4883
4884       warning_at (DECL_SOURCE_LOCATION (t_func), OPT_Wtrampolines,
4885                   "trampoline generated for nested function %qD", t_func);
4886     }
4887
4888   return const0_rtx;
4889 }
4890
4891 static rtx
4892 expand_builtin_adjust_trampoline (tree exp)
4893 {
4894   rtx tramp;
4895
4896   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
4897     return NULL_RTX;
4898
4899   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
4900   tramp = round_trampoline_addr (tramp);
4901   if (targetm.calls.trampoline_adjust_address)
4902     tramp = targetm.calls.trampoline_adjust_address (tramp);
4903
4904   return tramp;
4905 }
4906
4907 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
4908    function.  The function first checks whether the back end provides
4909    an insn to implement signbit for the respective mode.  If not, it
4910    checks whether the floating point format of the value is such that
4911    the sign bit can be extracted.  If that is not the case, the
4912    function returns NULL_RTX to indicate that a normal call should be
4913    emitted rather than expanding the function in-line.  EXP is the
4914    expression that is a call to the builtin function; if convenient,
4915    the result should be placed in TARGET.  */
4916 static rtx
4917 expand_builtin_signbit (tree exp, rtx target)
4918 {
4919   const struct real_format *fmt;
4920   enum machine_mode fmode, imode, rmode;
4921   tree arg;
4922   int word, bitpos;
4923   enum insn_code icode;
4924   rtx temp;
4925   location_t loc = EXPR_LOCATION (exp);
4926
4927   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4928     return NULL_RTX;
4929
4930   arg = CALL_EXPR_ARG (exp, 0);
4931   fmode = TYPE_MODE (TREE_TYPE (arg));
4932   rmode = TYPE_MODE (TREE_TYPE (exp));
4933   fmt = REAL_MODE_FORMAT (fmode);
4934
4935   arg = builtin_save_expr (arg);
4936
4937   /* Expand the argument yielding a RTX expression. */
4938   temp = expand_normal (arg);
4939
4940   /* Check if the back end provides an insn that handles signbit for the
4941      argument's mode. */
4942   icode = optab_handler (signbit_optab, fmode);
4943   if (icode != CODE_FOR_nothing)
4944     {
4945       rtx last = get_last_insn ();
4946       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
4947       if (maybe_emit_unop_insn (icode, target, temp, UNKNOWN))
4948         return target;
4949       delete_insns_since (last);
4950     }
4951
4952   /* For floating point formats without a sign bit, implement signbit
4953      as "ARG < 0.0".  */
4954   bitpos = fmt->signbit_ro;
4955   if (bitpos < 0)
4956   {
4957     /* But we can't do this if the format supports signed zero.  */
4958     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4959       return NULL_RTX;
4960
4961     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
4962                        build_real (TREE_TYPE (arg), dconst0));
4963     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4964   }
4965
4966   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4967     {
4968       imode = int_mode_for_mode (fmode);
4969       if (imode == BLKmode)
4970         return NULL_RTX;
4971       temp = gen_lowpart (imode, temp);
4972     }
4973   else
4974     {
4975       imode = word_mode;
4976       /* Handle targets with different FP word orders.  */
4977       if (FLOAT_WORDS_BIG_ENDIAN)
4978         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
4979       else
4980         word = bitpos / BITS_PER_WORD;
4981       temp = operand_subword_force (temp, word, fmode);
4982       bitpos = bitpos % BITS_PER_WORD;
4983     }
4984
4985   /* Force the intermediate word_mode (or narrower) result into a
4986      register.  This avoids attempting to create paradoxical SUBREGs
4987      of floating point modes below.  */
4988   temp = force_reg (imode, temp);
4989
4990   /* If the bitpos is within the "result mode" lowpart, the operation
4991      can be implement with a single bitwise AND.  Otherwise, we need
4992      a right shift and an AND.  */
4993
4994   if (bitpos < GET_MODE_BITSIZE (rmode))
4995     {
4996       double_int mask = double_int_zero.set_bit (bitpos);
4997
4998       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
4999         temp = gen_lowpart (rmode, temp);
5000       temp = expand_binop (rmode, and_optab, temp,
5001                            immed_double_int_const (mask, rmode),
5002                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5003     }
5004   else
5005     {
5006       /* Perform a logical right shift to place the signbit in the least
5007          significant bit, then truncate the result to the desired mode
5008          and mask just this bit.  */
5009       temp = expand_shift (RSHIFT_EXPR, imode, temp, bitpos, NULL_RTX, 1);
5010       temp = gen_lowpart (rmode, temp);
5011       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5012                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5013     }
5014
5015   return temp;
5016 }
5017
5018 /* Expand fork or exec calls.  TARGET is the desired target of the
5019    call.  EXP is the call. FN is the
5020    identificator of the actual function.  IGNORE is nonzero if the
5021    value is to be ignored.  */
5022
5023 static rtx
5024 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5025 {
5026   tree id, decl;
5027   tree call;
5028
5029   /* If we are not profiling, just call the function.  */
5030   if (!profile_arc_flag)
5031     return NULL_RTX;
5032
5033   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5034      compiler, so the code does not diverge, and the wrapper may run the
5035      code necessary for keeping the profiling sane.  */
5036
5037   switch (DECL_FUNCTION_CODE (fn))
5038     {
5039     case BUILT_IN_FORK:
5040       id = get_identifier ("__gcov_fork");
5041       break;
5042
5043     case BUILT_IN_EXECL:
5044       id = get_identifier ("__gcov_execl");
5045       break;
5046
5047     case BUILT_IN_EXECV:
5048       id = get_identifier ("__gcov_execv");
5049       break;
5050
5051     case BUILT_IN_EXECLP:
5052       id = get_identifier ("__gcov_execlp");
5053       break;
5054
5055     case BUILT_IN_EXECLE:
5056       id = get_identifier ("__gcov_execle");
5057       break;
5058
5059     case BUILT_IN_EXECVP:
5060       id = get_identifier ("__gcov_execvp");
5061       break;
5062
5063     case BUILT_IN_EXECVE:
5064       id = get_identifier ("__gcov_execve");
5065       break;
5066
5067     default:
5068       gcc_unreachable ();
5069     }
5070
5071   decl = build_decl (DECL_SOURCE_LOCATION (fn),
5072                      FUNCTION_DECL, id, TREE_TYPE (fn));
5073   DECL_EXTERNAL (decl) = 1;
5074   TREE_PUBLIC (decl) = 1;
5075   DECL_ARTIFICIAL (decl) = 1;
5076   TREE_NOTHROW (decl) = 1;
5077   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5078   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5079   call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5080   return expand_call (call, target, ignore);
5081  }
5082
5083
5084 \f
5085 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5086    the pointer in these functions is void*, the tree optimizers may remove
5087    casts.  The mode computed in expand_builtin isn't reliable either, due
5088    to __sync_bool_compare_and_swap.
5089
5090    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5091    group of builtins.  This gives us log2 of the mode size.  */
5092
5093 static inline enum machine_mode
5094 get_builtin_sync_mode (int fcode_diff)
5095 {
5096   /* The size is not negotiable, so ask not to get BLKmode in return
5097      if the target indicates that a smaller size would be better.  */
5098   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5099 }
5100
5101 /* Expand the memory expression LOC and return the appropriate memory operand
5102    for the builtin_sync operations.  */
5103
5104 static rtx
5105 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5106 {
5107   rtx addr, mem;
5108
5109   addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5110   addr = convert_memory_address (Pmode, addr);
5111
5112   /* Note that we explicitly do not want any alias information for this
5113      memory, so that we kill all other live memories.  Otherwise we don't
5114      satisfy the full barrier semantics of the intrinsic.  */
5115   mem = validize_mem (gen_rtx_MEM (mode, addr));
5116
5117   /* The alignment needs to be at least according to that of the mode.  */
5118   set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
5119                            get_pointer_alignment (loc)));
5120   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5121   MEM_VOLATILE_P (mem) = 1;
5122
5123   return mem;
5124 }
5125
5126 /* Make sure an argument is in the right mode.
5127    EXP is the tree argument. 
5128    MODE is the mode it should be in.  */
5129
5130 static rtx
5131 expand_expr_force_mode (tree exp, enum machine_mode mode)
5132 {
5133   rtx val;
5134   enum machine_mode old_mode;
5135
5136   val = expand_expr (exp, NULL_RTX, mode, EXPAND_NORMAL);
5137   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5138      of CONST_INTs, where we know the old_mode only from the call argument.  */
5139
5140   old_mode = GET_MODE (val);
5141   if (old_mode == VOIDmode)
5142     old_mode = TYPE_MODE (TREE_TYPE (exp));
5143   val = convert_modes (mode, old_mode, val, 1);
5144   return val;
5145 }
5146
5147
5148 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5149    EXP is the CALL_EXPR.  CODE is the rtx code
5150    that corresponds to the arithmetic or logical operation from the name;
5151    an exception here is that NOT actually means NAND.  TARGET is an optional
5152    place for us to store the results; AFTER is true if this is the
5153    fetch_and_xxx form.  */
5154
5155 static rtx
5156 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5157                                enum rtx_code code, bool after,
5158                                rtx target)
5159 {
5160   rtx val, mem;
5161   location_t loc = EXPR_LOCATION (exp);
5162
5163   if (code == NOT && warn_sync_nand)
5164     {
5165       tree fndecl = get_callee_fndecl (exp);
5166       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5167
5168       static bool warned_f_a_n, warned_n_a_f;
5169
5170       switch (fcode)
5171         {
5172         case BUILT_IN_SYNC_FETCH_AND_NAND_1:
5173         case BUILT_IN_SYNC_FETCH_AND_NAND_2:
5174         case BUILT_IN_SYNC_FETCH_AND_NAND_4:
5175         case BUILT_IN_SYNC_FETCH_AND_NAND_8:
5176         case BUILT_IN_SYNC_FETCH_AND_NAND_16:
5177           if (warned_f_a_n)
5178             break;
5179
5180           fndecl = builtin_decl_implicit (BUILT_IN_SYNC_FETCH_AND_NAND_N);
5181           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5182           warned_f_a_n = true;
5183           break;
5184
5185         case BUILT_IN_SYNC_NAND_AND_FETCH_1:
5186         case BUILT_IN_SYNC_NAND_AND_FETCH_2:
5187         case BUILT_IN_SYNC_NAND_AND_FETCH_4:
5188         case BUILT_IN_SYNC_NAND_AND_FETCH_8:
5189         case BUILT_IN_SYNC_NAND_AND_FETCH_16:
5190           if (warned_n_a_f)
5191             break;
5192
5193          fndecl = builtin_decl_implicit (BUILT_IN_SYNC_NAND_AND_FETCH_N);
5194           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5195           warned_n_a_f = true;
5196           break;
5197
5198         default:
5199           gcc_unreachable ();
5200         }
5201     }
5202
5203   /* Expand the operands.  */
5204   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5205   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5206
5207   return expand_atomic_fetch_op (target, mem, val, code, MEMMODEL_SEQ_CST,
5208                                  after);
5209 }
5210
5211 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5212    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5213    true if this is the boolean form.  TARGET is a place for us to store the
5214    results; this is NOT optional if IS_BOOL is true.  */
5215
5216 static rtx
5217 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5218                                  bool is_bool, rtx target)
5219 {
5220   rtx old_val, new_val, mem;
5221   rtx *pbool, *poval;
5222
5223   /* Expand the operands.  */
5224   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5225   old_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5226   new_val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5227
5228   pbool = poval = NULL;
5229   if (target != const0_rtx)
5230     {
5231       if (is_bool)
5232         pbool = &target;
5233       else
5234         poval = &target;
5235     }
5236   if (!expand_atomic_compare_and_swap (pbool, poval, mem, old_val, new_val,
5237                                        false, MEMMODEL_SEQ_CST,
5238                                        MEMMODEL_SEQ_CST))
5239     return NULL_RTX;
5240
5241   return target;
5242 }
5243
5244 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5245    general form is actually an atomic exchange, and some targets only
5246    support a reduced form with the second argument being a constant 1.
5247    EXP is the CALL_EXPR; TARGET is an optional place for us to store
5248    the results.  */
5249
5250 static rtx
5251 expand_builtin_sync_lock_test_and_set (enum machine_mode mode, tree exp,
5252                                        rtx target)
5253 {
5254   rtx val, mem;
5255
5256   /* Expand the operands.  */
5257   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5258   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5259
5260   return expand_sync_lock_test_and_set (target, mem, val);
5261 }
5262
5263 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
5264
5265 static void
5266 expand_builtin_sync_lock_release (enum machine_mode mode, tree exp)
5267 {
5268   rtx mem;
5269
5270   /* Expand the operands.  */
5271   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5272
5273   expand_atomic_store (mem, const0_rtx, MEMMODEL_RELEASE, true);
5274 }
5275
5276 /* Given an integer representing an ``enum memmodel'', verify its
5277    correctness and return the memory model enum.  */
5278
5279 static enum memmodel
5280 get_memmodel (tree exp)
5281 {
5282   rtx op;
5283   unsigned HOST_WIDE_INT val;
5284
5285   /* If the parameter is not a constant, it's a run time value so we'll just
5286      convert it to MEMMODEL_SEQ_CST to avoid annoying runtime checking.  */
5287   if (TREE_CODE (exp) != INTEGER_CST)
5288     return MEMMODEL_SEQ_CST;
5289
5290   op = expand_normal (exp);
5291
5292   val = INTVAL (op);
5293   if (targetm.memmodel_check)
5294     val = targetm.memmodel_check (val);
5295   else if (val & ~MEMMODEL_MASK)
5296     {
5297       warning (OPT_Winvalid_memory_model,
5298                "Unknown architecture specifier in memory model to builtin.");
5299       return MEMMODEL_SEQ_CST;
5300     }
5301
5302   if ((INTVAL(op) & MEMMODEL_MASK) >= MEMMODEL_LAST)
5303     {
5304       warning (OPT_Winvalid_memory_model,
5305                "invalid memory model argument to builtin");
5306       return MEMMODEL_SEQ_CST;
5307     }
5308
5309   return (enum memmodel) val;
5310 }
5311
5312 /* Expand the __atomic_exchange intrinsic:
5313         TYPE __atomic_exchange (TYPE *object, TYPE desired, enum memmodel)
5314    EXP is the CALL_EXPR.
5315    TARGET is an optional place for us to store the results.  */
5316
5317 static rtx
5318 expand_builtin_atomic_exchange (enum machine_mode mode, tree exp, rtx target)
5319 {
5320   rtx val, mem;
5321   enum memmodel model;
5322
5323   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5324   if ((model & MEMMODEL_MASK) == MEMMODEL_CONSUME)
5325     {
5326       error ("invalid memory model for %<__atomic_exchange%>");
5327       return NULL_RTX;
5328     }
5329
5330   if (!flag_inline_atomics)
5331     return NULL_RTX;
5332
5333   /* Expand the operands.  */
5334   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5335   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5336
5337   return expand_atomic_exchange (target, mem, val, model);
5338 }
5339
5340 /* Expand the __atomic_compare_exchange intrinsic:
5341         bool __atomic_compare_exchange (TYPE *object, TYPE *expect, 
5342                                         TYPE desired, BOOL weak, 
5343                                         enum memmodel success,
5344                                         enum memmodel failure)
5345    EXP is the CALL_EXPR.
5346    TARGET is an optional place for us to store the results.  */
5347
5348 static rtx
5349 expand_builtin_atomic_compare_exchange (enum machine_mode mode, tree exp, 
5350                                         rtx target)
5351 {
5352   rtx expect, desired, mem, oldval;
5353   enum memmodel success, failure;
5354   tree weak;
5355   bool is_weak;
5356
5357   success = get_memmodel (CALL_EXPR_ARG (exp, 4));
5358   failure = get_memmodel (CALL_EXPR_ARG (exp, 5));
5359
5360   if ((failure & MEMMODEL_MASK) == MEMMODEL_RELEASE
5361       || (failure & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5362     {
5363       error ("invalid failure memory model for %<__atomic_compare_exchange%>");
5364       return NULL_RTX;
5365     }
5366
5367   if (failure > success)
5368     {
5369       error ("failure memory model cannot be stronger than success "
5370              "memory model for %<__atomic_compare_exchange%>");
5371       return NULL_RTX;
5372     }
5373   
5374   if (!flag_inline_atomics)
5375     return NULL_RTX;
5376
5377   /* Expand the operands.  */
5378   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5379
5380   expect = expand_normal (CALL_EXPR_ARG (exp, 1));
5381   expect = convert_memory_address (Pmode, expect);
5382   expect = gen_rtx_MEM (mode, expect);
5383   desired = expand_expr_force_mode (CALL_EXPR_ARG (exp, 2), mode);
5384
5385   weak = CALL_EXPR_ARG (exp, 3);
5386   is_weak = false;
5387   if (host_integerp (weak, 0) && tree_low_cst (weak, 0) != 0)
5388     is_weak = true;
5389
5390   oldval = expect;
5391   if (!expand_atomic_compare_and_swap ((target == const0_rtx ? NULL : &target),
5392                                        &oldval, mem, oldval, desired,
5393                                        is_weak, success, failure))
5394     return NULL_RTX;
5395
5396   if (oldval != expect)
5397     emit_move_insn (expect, oldval);
5398
5399   return target;
5400 }
5401
5402 /* Expand the __atomic_load intrinsic:
5403         TYPE __atomic_load (TYPE *object, enum memmodel)
5404    EXP is the CALL_EXPR.
5405    TARGET is an optional place for us to store the results.  */
5406
5407 static rtx
5408 expand_builtin_atomic_load (enum machine_mode mode, tree exp, rtx target)
5409 {
5410   rtx mem;
5411   enum memmodel model;
5412
5413   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5414   if ((model & MEMMODEL_MASK) == MEMMODEL_RELEASE
5415       || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5416     {
5417       error ("invalid memory model for %<__atomic_load%>");
5418       return NULL_RTX;
5419     }
5420
5421   if (!flag_inline_atomics)
5422     return NULL_RTX;
5423
5424   /* Expand the operand.  */
5425   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5426
5427   return expand_atomic_load (target, mem, model);
5428 }
5429
5430
5431 /* Expand the __atomic_store intrinsic:
5432         void __atomic_store (TYPE *object, TYPE desired, enum memmodel)
5433    EXP is the CALL_EXPR.
5434    TARGET is an optional place for us to store the results.  */
5435
5436 static rtx
5437 expand_builtin_atomic_store (enum machine_mode mode, tree exp)
5438 {
5439   rtx mem, val;
5440   enum memmodel model;
5441
5442   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5443   if ((model & MEMMODEL_MASK) != MEMMODEL_RELAXED
5444       && (model & MEMMODEL_MASK) != MEMMODEL_SEQ_CST
5445       && (model & MEMMODEL_MASK) != MEMMODEL_RELEASE)
5446     {
5447       error ("invalid memory model for %<__atomic_store%>");
5448       return NULL_RTX;
5449     }
5450
5451   if (!flag_inline_atomics)
5452     return NULL_RTX;
5453
5454   /* Expand the operands.  */
5455   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5456   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5457
5458   return expand_atomic_store (mem, val, model, false);
5459 }
5460
5461 /* Expand the __atomic_fetch_XXX intrinsic:
5462         TYPE __atomic_fetch_XXX (TYPE *object, TYPE val, enum memmodel)
5463    EXP is the CALL_EXPR.
5464    TARGET is an optional place for us to store the results.
5465    CODE is the operation, PLUS, MINUS, ADD, XOR, or IOR.
5466    FETCH_AFTER is true if returning the result of the operation.
5467    FETCH_AFTER is false if returning the value before the operation.
5468    IGNORE is true if the result is not used.
5469    EXT_CALL is the correct builtin for an external call if this cannot be
5470    resolved to an instruction sequence.  */
5471
5472 static rtx
5473 expand_builtin_atomic_fetch_op (enum machine_mode mode, tree exp, rtx target,
5474                                 enum rtx_code code, bool fetch_after,
5475                                 bool ignore, enum built_in_function ext_call)
5476 {
5477   rtx val, mem, ret;
5478   enum memmodel model;
5479   tree fndecl;
5480   tree addr;
5481
5482   model = get_memmodel (CALL_EXPR_ARG (exp, 2));
5483
5484   /* Expand the operands.  */
5485   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5486   val = expand_expr_force_mode (CALL_EXPR_ARG (exp, 1), mode);
5487
5488   /* Only try generating instructions if inlining is turned on.  */
5489   if (flag_inline_atomics)
5490     {
5491       ret = expand_atomic_fetch_op (target, mem, val, code, model, fetch_after);
5492       if (ret)
5493         return ret;
5494     }
5495
5496   /* Return if a different routine isn't needed for the library call.  */
5497   if (ext_call == BUILT_IN_NONE)
5498     return NULL_RTX;
5499
5500   /* Change the call to the specified function.  */
5501   fndecl = get_callee_fndecl (exp);
5502   addr = CALL_EXPR_FN (exp);
5503   STRIP_NOPS (addr);
5504
5505   gcc_assert (TREE_OPERAND (addr, 0) == fndecl);
5506   TREE_OPERAND (addr, 0) = builtin_decl_explicit(ext_call);
5507
5508   /* Expand the call here so we can emit trailing code.  */
5509   ret = expand_call (exp, target, ignore);
5510
5511   /* Replace the original function just in case it matters.  */
5512   TREE_OPERAND (addr, 0) = fndecl;
5513
5514   /* Then issue the arithmetic correction to return the right result.  */
5515   if (!ignore)
5516     {
5517       if (code == NOT)
5518         {
5519           ret = expand_simple_binop (mode, AND, ret, val, NULL_RTX, true,
5520                                      OPTAB_LIB_WIDEN);
5521           ret = expand_simple_unop (mode, NOT, ret, target, true);
5522         }
5523       else
5524         ret = expand_simple_binop (mode, code, ret, val, target, true,
5525                                    OPTAB_LIB_WIDEN);
5526     }
5527   return ret;
5528 }
5529
5530
5531 #ifndef HAVE_atomic_clear
5532 # define HAVE_atomic_clear 0
5533 # define gen_atomic_clear(x,y) (gcc_unreachable (), NULL_RTX)
5534 #endif
5535
5536 /* Expand an atomic clear operation.
5537         void _atomic_clear (BOOL *obj, enum memmodel)
5538    EXP is the call expression.  */
5539
5540 static rtx
5541 expand_builtin_atomic_clear (tree exp) 
5542 {
5543   enum machine_mode mode;
5544   rtx mem, ret;
5545   enum memmodel model;
5546
5547   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5548   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5549   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5550
5551   if ((model & MEMMODEL_MASK) == MEMMODEL_ACQUIRE
5552       || (model & MEMMODEL_MASK) == MEMMODEL_ACQ_REL)
5553     {
5554       error ("invalid memory model for %<__atomic_store%>");
5555       return const0_rtx;
5556     }
5557
5558   if (HAVE_atomic_clear)
5559     {
5560       emit_insn (gen_atomic_clear (mem, model));
5561       return const0_rtx;
5562     }
5563
5564   /* Try issuing an __atomic_store, and allow fallback to __sync_lock_release.
5565      Failing that, a store is issued by __atomic_store.  The only way this can
5566      fail is if the bool type is larger than a word size.  Unlikely, but
5567      handle it anyway for completeness.  Assume a single threaded model since
5568      there is no atomic support in this case, and no barriers are required.  */
5569   ret = expand_atomic_store (mem, const0_rtx, model, true);
5570   if (!ret)
5571     emit_move_insn (mem, const0_rtx);
5572   return const0_rtx;
5573 }
5574
5575 /* Expand an atomic test_and_set operation.
5576         bool _atomic_test_and_set (BOOL *obj, enum memmodel)
5577    EXP is the call expression.  */
5578
5579 static rtx
5580 expand_builtin_atomic_test_and_set (tree exp, rtx target)
5581 {
5582   rtx mem;
5583   enum memmodel model;
5584   enum machine_mode mode;
5585
5586   mode = mode_for_size (BOOL_TYPE_SIZE, MODE_INT, 0);
5587   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5588   model = get_memmodel (CALL_EXPR_ARG (exp, 1));
5589
5590   return expand_atomic_test_and_set (target, mem, model);
5591 }
5592
5593
5594 /* Return true if (optional) argument ARG1 of size ARG0 is always lock free on
5595    this architecture.  If ARG1 is NULL, use typical alignment for size ARG0.  */
5596
5597 static tree
5598 fold_builtin_atomic_always_lock_free (tree arg0, tree arg1)
5599 {
5600   int size;
5601   enum machine_mode mode;
5602   unsigned int mode_align, type_align;
5603
5604   if (TREE_CODE (arg0) != INTEGER_CST)
5605     return NULL_TREE;
5606
5607   size = INTVAL (expand_normal (arg0)) * BITS_PER_UNIT;
5608   mode = mode_for_size (size, MODE_INT, 0);
5609   mode_align = GET_MODE_ALIGNMENT (mode);
5610
5611   if (TREE_CODE (arg1) == INTEGER_CST && INTVAL (expand_normal (arg1)) == 0)
5612     type_align = mode_align;
5613   else
5614     {
5615       tree ttype = TREE_TYPE (arg1);
5616
5617       /* This function is usually invoked and folded immediately by the front
5618          end before anything else has a chance to look at it.  The pointer
5619          parameter at this point is usually cast to a void *, so check for that
5620          and look past the cast.  */
5621       if (TREE_CODE (arg1) == NOP_EXPR && POINTER_TYPE_P (ttype)
5622           && VOID_TYPE_P (TREE_TYPE (ttype)))
5623         arg1 = TREE_OPERAND (arg1, 0);
5624
5625       ttype = TREE_TYPE (arg1);
5626       gcc_assert (POINTER_TYPE_P (ttype));
5627
5628       /* Get the underlying type of the object.  */
5629       ttype = TREE_TYPE (ttype);
5630       type_align = TYPE_ALIGN (ttype);
5631     }
5632
5633   /* If the object has smaller alignment, the the lock free routines cannot
5634      be used.  */
5635   if (type_align < mode_align)
5636     return boolean_false_node;
5637
5638   /* Check if a compare_and_swap pattern exists for the mode which represents
5639      the required size.  The pattern is not allowed to fail, so the existence
5640      of the pattern indicates support is present.  */
5641   if (can_compare_and_swap_p (mode, true))
5642     return boolean_true_node;
5643   else
5644     return boolean_false_node;
5645 }
5646
5647 /* Return true if the parameters to call EXP represent an object which will
5648    always generate lock free instructions.  The first argument represents the
5649    size of the object, and the second parameter is a pointer to the object 
5650    itself.  If NULL is passed for the object, then the result is based on 
5651    typical alignment for an object of the specified size.  Otherwise return 
5652    false.  */
5653
5654 static rtx
5655 expand_builtin_atomic_always_lock_free (tree exp)
5656 {
5657   tree size;
5658   tree arg0 = CALL_EXPR_ARG (exp, 0);
5659   tree arg1 = CALL_EXPR_ARG (exp, 1);
5660
5661   if (TREE_CODE (arg0) != INTEGER_CST)
5662     {
5663       error ("non-constant argument 1 to __atomic_always_lock_free");
5664       return const0_rtx;
5665     }
5666
5667   size = fold_builtin_atomic_always_lock_free (arg0, arg1);
5668   if (size == boolean_true_node)
5669     return const1_rtx;
5670   return const0_rtx;
5671 }
5672
5673 /* Return a one or zero if it can be determined that object ARG1 of size ARG 
5674    is lock free on this architecture.  */
5675
5676 static tree
5677 fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
5678 {
5679   if (!flag_inline_atomics)
5680     return NULL_TREE;
5681   
5682   /* If it isn't always lock free, don't generate a result.  */
5683   if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node)
5684     return boolean_true_node;
5685
5686   return NULL_TREE;
5687 }
5688
5689 /* Return true if the parameters to call EXP represent an object which will
5690    always generate lock free instructions.  The first argument represents the
5691    size of the object, and the second parameter is a pointer to the object 
5692    itself.  If NULL is passed for the object, then the result is based on 
5693    typical alignment for an object of the specified size.  Otherwise return 
5694    NULL*/
5695
5696 static rtx
5697 expand_builtin_atomic_is_lock_free (tree exp)
5698 {
5699   tree size;
5700   tree arg0 = CALL_EXPR_ARG (exp, 0);
5701   tree arg1 = CALL_EXPR_ARG (exp, 1);
5702
5703   if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
5704     {
5705       error ("non-integer argument 1 to __atomic_is_lock_free");
5706       return NULL_RTX;
5707     }
5708
5709   if (!flag_inline_atomics)
5710     return NULL_RTX; 
5711
5712   /* If the value is known at compile time, return the RTX for it.  */
5713   size = fold_builtin_atomic_is_lock_free (arg0, arg1);
5714   if (size == boolean_true_node)
5715     return const1_rtx;
5716
5717   return NULL_RTX;
5718 }
5719
5720 /* Expand the __atomic_thread_fence intrinsic:
5721         void __atomic_thread_fence (enum memmodel)
5722    EXP is the CALL_EXPR.  */
5723
5724 static void
5725 expand_builtin_atomic_thread_fence (tree exp)
5726 {
5727   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5728   expand_mem_thread_fence (model);
5729 }
5730
5731 /* Expand the __atomic_signal_fence intrinsic:
5732         void __atomic_signal_fence (enum memmodel)
5733    EXP is the CALL_EXPR.  */
5734
5735 static void
5736 expand_builtin_atomic_signal_fence (tree exp)
5737 {
5738   enum memmodel model = get_memmodel (CALL_EXPR_ARG (exp, 0));
5739   expand_mem_signal_fence (model);
5740 }
5741
5742 /* Expand the __sync_synchronize intrinsic.  */
5743
5744 static void
5745 expand_builtin_sync_synchronize (void)
5746 {
5747   expand_mem_thread_fence (MEMMODEL_SEQ_CST);
5748 }
5749
5750 static rtx
5751 expand_builtin_thread_pointer (tree exp, rtx target)
5752 {
5753   enum insn_code icode;
5754   if (!validate_arglist (exp, VOID_TYPE))
5755     return const0_rtx;
5756   icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
5757   if (icode != CODE_FOR_nothing)
5758     {
5759       struct expand_operand op;
5760       if (!REG_P (target) || GET_MODE (target) != Pmode)
5761         target = gen_reg_rtx (Pmode);
5762       create_output_operand (&op, target, Pmode);
5763       expand_insn (icode, 1, &op);
5764       return target;
5765     }
5766   error ("__builtin_thread_pointer is not supported on this target");
5767   return const0_rtx;
5768 }
5769
5770 static void
5771 expand_builtin_set_thread_pointer (tree exp)
5772 {
5773   enum insn_code icode;
5774   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5775     return;
5776   icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
5777   if (icode != CODE_FOR_nothing)
5778     {
5779       struct expand_operand op;
5780       rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
5781                              Pmode, EXPAND_NORMAL);      
5782       create_input_operand (&op, val, Pmode);
5783       expand_insn (icode, 1, &op);
5784       return;
5785     }
5786   error ("__builtin_set_thread_pointer is not supported on this target");
5787 }
5788
5789 \f
5790 /* Expand an expression EXP that calls a built-in function,
5791    with result going to TARGET if that's convenient
5792    (and in mode MODE if that's convenient).
5793    SUBTARGET may be used as the target for computing one of EXP's operands.
5794    IGNORE is nonzero if the value is to be ignored.  */
5795
5796 rtx
5797 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5798                 int ignore)
5799 {
5800   tree fndecl = get_callee_fndecl (exp);
5801   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5802   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5803   int flags;
5804
5805   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5806     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5807
5808   /* When not optimizing, generate calls to library functions for a certain
5809      set of builtins.  */
5810   if (!optimize
5811       && !called_as_built_in (fndecl)
5812       && fcode != BUILT_IN_ALLOCA
5813       && fcode != BUILT_IN_ALLOCA_WITH_ALIGN
5814       && fcode != BUILT_IN_FREE)
5815     return expand_call (exp, target, ignore);
5816
5817   /* The built-in function expanders test for target == const0_rtx
5818      to determine whether the function's result will be ignored.  */
5819   if (ignore)
5820     target = const0_rtx;
5821
5822   /* If the result of a pure or const built-in function is ignored, and
5823      none of its arguments are volatile, we can avoid expanding the
5824      built-in call and just evaluate the arguments for side-effects.  */
5825   if (target == const0_rtx
5826       && ((flags = flags_from_decl_or_type (fndecl)) & (ECF_CONST | ECF_PURE))
5827       && !(flags & ECF_LOOPING_CONST_OR_PURE))
5828     {
5829       bool volatilep = false;
5830       tree arg;
5831       call_expr_arg_iterator iter;
5832
5833       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5834         if (TREE_THIS_VOLATILE (arg))
5835           {
5836             volatilep = true;
5837             break;
5838           }
5839
5840       if (! volatilep)
5841         {
5842           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5843             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5844           return const0_rtx;
5845         }
5846     }
5847
5848   switch (fcode)
5849     {
5850     CASE_FLT_FN (BUILT_IN_FABS):
5851       target = expand_builtin_fabs (exp, target, subtarget);
5852       if (target)
5853         return target;
5854       break;
5855
5856     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5857       target = expand_builtin_copysign (exp, target, subtarget);
5858       if (target)
5859         return target;
5860       break;
5861
5862       /* Just do a normal library call if we were unable to fold
5863          the values.  */
5864     CASE_FLT_FN (BUILT_IN_CABS):
5865       break;
5866
5867     CASE_FLT_FN (BUILT_IN_EXP):
5868     CASE_FLT_FN (BUILT_IN_EXP10):
5869     CASE_FLT_FN (BUILT_IN_POW10):
5870     CASE_FLT_FN (BUILT_IN_EXP2):
5871     CASE_FLT_FN (BUILT_IN_EXPM1):
5872     CASE_FLT_FN (BUILT_IN_LOGB):
5873     CASE_FLT_FN (BUILT_IN_LOG):
5874     CASE_FLT_FN (BUILT_IN_LOG10):
5875     CASE_FLT_FN (BUILT_IN_LOG2):
5876     CASE_FLT_FN (BUILT_IN_LOG1P):
5877     CASE_FLT_FN (BUILT_IN_TAN):
5878     CASE_FLT_FN (BUILT_IN_ASIN):
5879     CASE_FLT_FN (BUILT_IN_ACOS):
5880     CASE_FLT_FN (BUILT_IN_ATAN):
5881     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5882       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5883          because of possible accuracy problems.  */
5884       if (! flag_unsafe_math_optimizations)
5885         break;
5886     CASE_FLT_FN (BUILT_IN_SQRT):
5887     CASE_FLT_FN (BUILT_IN_FLOOR):
5888     CASE_FLT_FN (BUILT_IN_CEIL):
5889     CASE_FLT_FN (BUILT_IN_TRUNC):
5890     CASE_FLT_FN (BUILT_IN_ROUND):
5891     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5892     CASE_FLT_FN (BUILT_IN_RINT):
5893       target = expand_builtin_mathfn (exp, target, subtarget);
5894       if (target)
5895         return target;
5896       break;
5897
5898     CASE_FLT_FN (BUILT_IN_FMA):
5899       target = expand_builtin_mathfn_ternary (exp, target, subtarget);
5900       if (target)
5901         return target;
5902       break;
5903
5904     CASE_FLT_FN (BUILT_IN_ILOGB):
5905       if (! flag_unsafe_math_optimizations)
5906         break;
5907     CASE_FLT_FN (BUILT_IN_ISINF):
5908     CASE_FLT_FN (BUILT_IN_FINITE):
5909     case BUILT_IN_ISFINITE:
5910     case BUILT_IN_ISNORMAL:
5911       target = expand_builtin_interclass_mathfn (exp, target);
5912       if (target)
5913         return target;
5914       break;
5915
5916     CASE_FLT_FN (BUILT_IN_ICEIL):
5917     CASE_FLT_FN (BUILT_IN_LCEIL):
5918     CASE_FLT_FN (BUILT_IN_LLCEIL):
5919     CASE_FLT_FN (BUILT_IN_LFLOOR):
5920     CASE_FLT_FN (BUILT_IN_IFLOOR):
5921     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5922       target = expand_builtin_int_roundingfn (exp, target);
5923       if (target)
5924         return target;
5925       break;
5926
5927     CASE_FLT_FN (BUILT_IN_IRINT):
5928     CASE_FLT_FN (BUILT_IN_LRINT):
5929     CASE_FLT_FN (BUILT_IN_LLRINT):
5930     CASE_FLT_FN (BUILT_IN_IROUND):
5931     CASE_FLT_FN (BUILT_IN_LROUND):
5932     CASE_FLT_FN (BUILT_IN_LLROUND):
5933       target = expand_builtin_int_roundingfn_2 (exp, target);
5934       if (target)
5935         return target;
5936       break;
5937
5938     CASE_FLT_FN (BUILT_IN_POWI):
5939       target = expand_builtin_powi (exp, target);
5940       if (target)
5941         return target;
5942       break;
5943
5944     CASE_FLT_FN (BUILT_IN_ATAN2):
5945     CASE_FLT_FN (BUILT_IN_LDEXP):
5946     CASE_FLT_FN (BUILT_IN_SCALB):
5947     CASE_FLT_FN (BUILT_IN_SCALBN):
5948     CASE_FLT_FN (BUILT_IN_SCALBLN):
5949       if (! flag_unsafe_math_optimizations)
5950         break;
5951
5952     CASE_FLT_FN (BUILT_IN_FMOD):
5953     CASE_FLT_FN (BUILT_IN_REMAINDER):
5954     CASE_FLT_FN (BUILT_IN_DREM):
5955     CASE_FLT_FN (BUILT_IN_POW):
5956       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5957       if (target)
5958         return target;
5959       break;
5960
5961     CASE_FLT_FN (BUILT_IN_CEXPI):
5962       target = expand_builtin_cexpi (exp, target);
5963       gcc_assert (target);
5964       return target;
5965
5966     CASE_FLT_FN (BUILT_IN_SIN):
5967     CASE_FLT_FN (BUILT_IN_COS):
5968       if (! flag_unsafe_math_optimizations)
5969         break;
5970       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5971       if (target)
5972         return target;
5973       break;
5974
5975     CASE_FLT_FN (BUILT_IN_SINCOS):
5976       if (! flag_unsafe_math_optimizations)
5977         break;
5978       target = expand_builtin_sincos (exp);
5979       if (target)
5980         return target;
5981       break;
5982
5983     case BUILT_IN_APPLY_ARGS:
5984       return expand_builtin_apply_args ();
5985
5986       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5987          FUNCTION with a copy of the parameters described by
5988          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5989          allocated on the stack into which is stored all the registers
5990          that might possibly be used for returning the result of a
5991          function.  ARGUMENTS is the value returned by
5992          __builtin_apply_args.  ARGSIZE is the number of bytes of
5993          arguments that must be copied.  ??? How should this value be
5994          computed?  We'll also need a safe worst case value for varargs
5995          functions.  */
5996     case BUILT_IN_APPLY:
5997       if (!validate_arglist (exp, POINTER_TYPE,
5998                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5999           && !validate_arglist (exp, REFERENCE_TYPE,
6000                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6001         return const0_rtx;
6002       else
6003         {
6004           rtx ops[3];
6005
6006           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6007           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6008           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6009
6010           return expand_builtin_apply (ops[0], ops[1], ops[2]);
6011         }
6012
6013       /* __builtin_return (RESULT) causes the function to return the
6014          value described by RESULT.  RESULT is address of the block of
6015          memory returned by __builtin_apply.  */
6016     case BUILT_IN_RETURN:
6017       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6018         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6019       return const0_rtx;
6020
6021     case BUILT_IN_SAVEREGS:
6022       return expand_builtin_saveregs ();
6023
6024     case BUILT_IN_VA_ARG_PACK:
6025       /* All valid uses of __builtin_va_arg_pack () are removed during
6026          inlining.  */
6027       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6028       return const0_rtx;
6029
6030     case BUILT_IN_VA_ARG_PACK_LEN:
6031       /* All valid uses of __builtin_va_arg_pack_len () are removed during
6032          inlining.  */
6033       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6034       return const0_rtx;
6035
6036       /* Return the address of the first anonymous stack arg.  */
6037     case BUILT_IN_NEXT_ARG:
6038       if (fold_builtin_next_arg (exp, false))
6039         return const0_rtx;
6040       return expand_builtin_next_arg ();
6041
6042     case BUILT_IN_CLEAR_CACHE:
6043       target = expand_builtin___clear_cache (exp);
6044       if (target)
6045         return target;
6046       break;
6047
6048     case BUILT_IN_CLASSIFY_TYPE:
6049       return expand_builtin_classify_type (exp);
6050
6051     case BUILT_IN_CONSTANT_P:
6052       return const0_rtx;
6053
6054     case BUILT_IN_FRAME_ADDRESS:
6055     case BUILT_IN_RETURN_ADDRESS:
6056       return expand_builtin_frame_address (fndecl, exp);
6057
6058     /* Returns the address of the area where the structure is returned.
6059        0 otherwise.  */
6060     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6061       if (call_expr_nargs (exp) != 0
6062           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6063           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6064         return const0_rtx;
6065       else
6066         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6067
6068     case BUILT_IN_ALLOCA:
6069     case BUILT_IN_ALLOCA_WITH_ALIGN:
6070       /* If the allocation stems from the declaration of a variable-sized
6071          object, it cannot accumulate.  */
6072       target = expand_builtin_alloca (exp, CALL_ALLOCA_FOR_VAR_P (exp));
6073       if (target)
6074         return target;
6075       break;
6076
6077     case BUILT_IN_STACK_SAVE:
6078       return expand_stack_save ();
6079
6080     case BUILT_IN_STACK_RESTORE:
6081       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6082       return const0_rtx;
6083
6084     case BUILT_IN_BSWAP16:
6085     case BUILT_IN_BSWAP32:
6086     case BUILT_IN_BSWAP64:
6087       target = expand_builtin_bswap (target_mode, exp, target, subtarget);
6088       if (target)
6089         return target;
6090       break;
6091
6092     CASE_INT_FN (BUILT_IN_FFS):
6093     case BUILT_IN_FFSIMAX:
6094       target = expand_builtin_unop (target_mode, exp, target,
6095                                     subtarget, ffs_optab);
6096       if (target)
6097         return target;
6098       break;
6099
6100     CASE_INT_FN (BUILT_IN_CLZ):
6101     case BUILT_IN_CLZIMAX:
6102       target = expand_builtin_unop (target_mode, exp, target,
6103                                     subtarget, clz_optab);
6104       if (target)
6105         return target;
6106       break;
6107
6108     CASE_INT_FN (BUILT_IN_CTZ):
6109     case BUILT_IN_CTZIMAX:
6110       target = expand_builtin_unop (target_mode, exp, target,
6111                                     subtarget, ctz_optab);
6112       if (target)
6113         return target;
6114       break;
6115
6116     CASE_INT_FN (BUILT_IN_CLRSB):
6117     case BUILT_IN_CLRSBIMAX:
6118       target = expand_builtin_unop (target_mode, exp, target,
6119                                     subtarget, clrsb_optab);
6120       if (target)
6121         return target;
6122       break;
6123
6124     CASE_INT_FN (BUILT_IN_POPCOUNT):
6125     case BUILT_IN_POPCOUNTIMAX:
6126       target = expand_builtin_unop (target_mode, exp, target,
6127                                     subtarget, popcount_optab);
6128       if (target)
6129         return target;
6130       break;
6131
6132     CASE_INT_FN (BUILT_IN_PARITY):
6133     case BUILT_IN_PARITYIMAX:
6134       target = expand_builtin_unop (target_mode, exp, target,
6135                                     subtarget, parity_optab);
6136       if (target)
6137         return target;
6138       break;
6139
6140     case BUILT_IN_STRLEN:
6141       target = expand_builtin_strlen (exp, target, target_mode);
6142       if (target)
6143         return target;
6144       break;
6145
6146     case BUILT_IN_STRCPY:
6147       target = expand_builtin_strcpy (exp, target);
6148       if (target)
6149         return target;
6150       break;
6151
6152     case BUILT_IN_STRNCPY:
6153       target = expand_builtin_strncpy (exp, target);
6154       if (target)
6155         return target;
6156       break;
6157
6158     case BUILT_IN_STPCPY:
6159       target = expand_builtin_stpcpy (exp, target, mode);
6160       if (target)
6161         return target;
6162       break;
6163
6164     case BUILT_IN_MEMCPY:
6165       target = expand_builtin_memcpy (exp, target);
6166       if (target)
6167         return target;
6168       break;
6169
6170     case BUILT_IN_MEMPCPY:
6171       target = expand_builtin_mempcpy (exp, target, mode);
6172       if (target)
6173         return target;
6174       break;
6175
6176     case BUILT_IN_MEMSET:
6177       target = expand_builtin_memset (exp, target, mode);
6178       if (target)
6179         return target;
6180       break;
6181
6182     case BUILT_IN_BZERO:
6183       target = expand_builtin_bzero (exp);
6184       if (target)
6185         return target;
6186       break;
6187
6188     case BUILT_IN_STRCMP:
6189       target = expand_builtin_strcmp (exp, target);
6190       if (target)
6191         return target;
6192       break;
6193
6194     case BUILT_IN_STRNCMP:
6195       target = expand_builtin_strncmp (exp, target, mode);
6196       if (target)
6197         return target;
6198       break;
6199
6200     case BUILT_IN_BCMP:
6201     case BUILT_IN_MEMCMP:
6202       target = expand_builtin_memcmp (exp, target, mode);
6203       if (target)
6204         return target;
6205       break;
6206
6207     case BUILT_IN_SETJMP:
6208       /* This should have been lowered to the builtins below.  */
6209       gcc_unreachable ();
6210
6211     case BUILT_IN_SETJMP_SETUP:
6212       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6213           and the receiver label.  */
6214       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6215         {
6216           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6217                                       VOIDmode, EXPAND_NORMAL);
6218           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6219           rtx label_r = label_rtx (label);
6220
6221           /* This is copied from the handling of non-local gotos.  */
6222           expand_builtin_setjmp_setup (buf_addr, label_r);
6223           nonlocal_goto_handler_labels
6224             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6225                                  nonlocal_goto_handler_labels);
6226           /* ??? Do not let expand_label treat us as such since we would
6227              not want to be both on the list of non-local labels and on
6228              the list of forced labels.  */
6229           FORCED_LABEL (label) = 0;
6230           return const0_rtx;
6231         }
6232       break;
6233
6234     case BUILT_IN_SETJMP_DISPATCHER:
6235        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6236       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6237         {
6238           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6239           rtx label_r = label_rtx (label);
6240
6241           /* Remove the dispatcher label from the list of non-local labels
6242              since the receiver labels have been added to it above.  */
6243           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6244           return const0_rtx;
6245         }
6246       break;
6247
6248     case BUILT_IN_SETJMP_RECEIVER:
6249        /* __builtin_setjmp_receiver is passed the receiver label.  */
6250       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6251         {
6252           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6253           rtx label_r = label_rtx (label);
6254
6255           expand_builtin_setjmp_receiver (label_r);
6256           return const0_rtx;
6257         }
6258       break;
6259
6260       /* __builtin_longjmp is passed a pointer to an array of five words.
6261          It's similar to the C library longjmp function but works with
6262          __builtin_setjmp above.  */
6263     case BUILT_IN_LONGJMP:
6264       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6265         {
6266           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6267                                       VOIDmode, EXPAND_NORMAL);
6268           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6269
6270           if (value != const1_rtx)
6271             {
6272               error ("%<__builtin_longjmp%> second argument must be 1");
6273               return const0_rtx;
6274             }
6275
6276           expand_builtin_longjmp (buf_addr, value);
6277           return const0_rtx;
6278         }
6279       break;
6280
6281     case BUILT_IN_NONLOCAL_GOTO:
6282       target = expand_builtin_nonlocal_goto (exp);
6283       if (target)
6284         return target;
6285       break;
6286
6287       /* This updates the setjmp buffer that is its argument with the value
6288          of the current stack pointer.  */
6289     case BUILT_IN_UPDATE_SETJMP_BUF:
6290       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6291         {
6292           rtx buf_addr
6293             = expand_normal (CALL_EXPR_ARG (exp, 0));
6294
6295           expand_builtin_update_setjmp_buf (buf_addr);
6296           return const0_rtx;
6297         }
6298       break;
6299
6300     case BUILT_IN_TRAP:
6301       expand_builtin_trap ();
6302       return const0_rtx;
6303
6304     case BUILT_IN_UNREACHABLE:
6305       expand_builtin_unreachable ();
6306       return const0_rtx;
6307
6308     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6309     case BUILT_IN_SIGNBITD32:
6310     case BUILT_IN_SIGNBITD64:
6311     case BUILT_IN_SIGNBITD128:
6312       target = expand_builtin_signbit (exp, target);
6313       if (target)
6314         return target;
6315       break;
6316
6317       /* Various hooks for the DWARF 2 __throw routine.  */
6318     case BUILT_IN_UNWIND_INIT:
6319       expand_builtin_unwind_init ();
6320       return const0_rtx;
6321     case BUILT_IN_DWARF_CFA:
6322       return virtual_cfa_rtx;
6323 #ifdef DWARF2_UNWIND_INFO
6324     case BUILT_IN_DWARF_SP_COLUMN:
6325       return expand_builtin_dwarf_sp_column ();
6326     case BUILT_IN_INIT_DWARF_REG_SIZES:
6327       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6328       return const0_rtx;
6329 #endif
6330     case BUILT_IN_FROB_RETURN_ADDR:
6331       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6332     case BUILT_IN_EXTRACT_RETURN_ADDR:
6333       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6334     case BUILT_IN_EH_RETURN:
6335       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6336                                 CALL_EXPR_ARG (exp, 1));
6337       return const0_rtx;
6338 #ifdef EH_RETURN_DATA_REGNO
6339     case BUILT_IN_EH_RETURN_DATA_REGNO:
6340       return expand_builtin_eh_return_data_regno (exp);
6341 #endif
6342     case BUILT_IN_EXTEND_POINTER:
6343       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6344     case BUILT_IN_EH_POINTER:
6345       return expand_builtin_eh_pointer (exp);
6346     case BUILT_IN_EH_FILTER:
6347       return expand_builtin_eh_filter (exp);
6348     case BUILT_IN_EH_COPY_VALUES:
6349       return expand_builtin_eh_copy_values (exp);
6350
6351     case BUILT_IN_VA_START:
6352       return expand_builtin_va_start (exp);
6353     case BUILT_IN_VA_END:
6354       return expand_builtin_va_end (exp);
6355     case BUILT_IN_VA_COPY:
6356       return expand_builtin_va_copy (exp);
6357     case BUILT_IN_EXPECT:
6358       return expand_builtin_expect (exp, target);
6359     case BUILT_IN_ASSUME_ALIGNED:
6360       return expand_builtin_assume_aligned (exp, target);
6361     case BUILT_IN_PREFETCH:
6362       expand_builtin_prefetch (exp);
6363       return const0_rtx;
6364
6365     case BUILT_IN_INIT_TRAMPOLINE:
6366       return expand_builtin_init_trampoline (exp, true);
6367     case BUILT_IN_INIT_HEAP_TRAMPOLINE:
6368       return expand_builtin_init_trampoline (exp, false);
6369     case BUILT_IN_ADJUST_TRAMPOLINE:
6370       return expand_builtin_adjust_trampoline (exp);
6371
6372     case BUILT_IN_FORK:
6373     case BUILT_IN_EXECL:
6374     case BUILT_IN_EXECV:
6375     case BUILT_IN_EXECLP:
6376     case BUILT_IN_EXECLE:
6377     case BUILT_IN_EXECVP:
6378     case BUILT_IN_EXECVE:
6379       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6380       if (target)
6381         return target;
6382       break;
6383
6384     case BUILT_IN_SYNC_FETCH_AND_ADD_1:
6385     case BUILT_IN_SYNC_FETCH_AND_ADD_2:
6386     case BUILT_IN_SYNC_FETCH_AND_ADD_4:
6387     case BUILT_IN_SYNC_FETCH_AND_ADD_8:
6388     case BUILT_IN_SYNC_FETCH_AND_ADD_16:
6389       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_ADD_1);
6390       target = expand_builtin_sync_operation (mode, exp, PLUS, false, target);
6391       if (target)
6392         return target;
6393       break;
6394
6395     case BUILT_IN_SYNC_FETCH_AND_SUB_1:
6396     case BUILT_IN_SYNC_FETCH_AND_SUB_2:
6397     case BUILT_IN_SYNC_FETCH_AND_SUB_4:
6398     case BUILT_IN_SYNC_FETCH_AND_SUB_8:
6399     case BUILT_IN_SYNC_FETCH_AND_SUB_16:
6400       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_SUB_1);
6401       target = expand_builtin_sync_operation (mode, exp, MINUS, false, target);
6402       if (target)
6403         return target;
6404       break;
6405
6406     case BUILT_IN_SYNC_FETCH_AND_OR_1:
6407     case BUILT_IN_SYNC_FETCH_AND_OR_2:
6408     case BUILT_IN_SYNC_FETCH_AND_OR_4:
6409     case BUILT_IN_SYNC_FETCH_AND_OR_8:
6410     case BUILT_IN_SYNC_FETCH_AND_OR_16:
6411       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_OR_1);
6412       target = expand_builtin_sync_operation (mode, exp, IOR, false, target);
6413       if (target)
6414         return target;
6415       break;
6416
6417     case BUILT_IN_SYNC_FETCH_AND_AND_1:
6418     case BUILT_IN_SYNC_FETCH_AND_AND_2:
6419     case BUILT_IN_SYNC_FETCH_AND_AND_4:
6420     case BUILT_IN_SYNC_FETCH_AND_AND_8:
6421     case BUILT_IN_SYNC_FETCH_AND_AND_16:
6422       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_AND_1);
6423       target = expand_builtin_sync_operation (mode, exp, AND, false, target);
6424       if (target)
6425         return target;
6426       break;
6427
6428     case BUILT_IN_SYNC_FETCH_AND_XOR_1:
6429     case BUILT_IN_SYNC_FETCH_AND_XOR_2:
6430     case BUILT_IN_SYNC_FETCH_AND_XOR_4:
6431     case BUILT_IN_SYNC_FETCH_AND_XOR_8:
6432     case BUILT_IN_SYNC_FETCH_AND_XOR_16:
6433       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_XOR_1);
6434       target = expand_builtin_sync_operation (mode, exp, XOR, false, target);
6435       if (target)
6436         return target;
6437       break;
6438
6439     case BUILT_IN_SYNC_FETCH_AND_NAND_1:
6440     case BUILT_IN_SYNC_FETCH_AND_NAND_2:
6441     case BUILT_IN_SYNC_FETCH_AND_NAND_4:
6442     case BUILT_IN_SYNC_FETCH_AND_NAND_8:
6443     case BUILT_IN_SYNC_FETCH_AND_NAND_16:
6444       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_FETCH_AND_NAND_1);
6445       target = expand_builtin_sync_operation (mode, exp, NOT, false, target);
6446       if (target)
6447         return target;
6448       break;
6449
6450     case BUILT_IN_SYNC_ADD_AND_FETCH_1:
6451     case BUILT_IN_SYNC_ADD_AND_FETCH_2:
6452     case BUILT_IN_SYNC_ADD_AND_FETCH_4:
6453     case BUILT_IN_SYNC_ADD_AND_FETCH_8:
6454     case BUILT_IN_SYNC_ADD_AND_FETCH_16:
6455       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_ADD_AND_FETCH_1);
6456       target = expand_builtin_sync_operation (mode, exp, PLUS, true, target);
6457       if (target)
6458         return target;
6459       break;
6460
6461     case BUILT_IN_SYNC_SUB_AND_FETCH_1:
6462     case BUILT_IN_SYNC_SUB_AND_FETCH_2:
6463     case BUILT_IN_SYNC_SUB_AND_FETCH_4:
6464     case BUILT_IN_SYNC_SUB_AND_FETCH_8:
6465     case BUILT_IN_SYNC_SUB_AND_FETCH_16:
6466       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_SUB_AND_FETCH_1);
6467       target = expand_builtin_sync_operation (mode, exp, MINUS, true, target);
6468       if (target)
6469         return target;
6470       break;
6471
6472     case BUILT_IN_SYNC_OR_AND_FETCH_1:
6473     case BUILT_IN_SYNC_OR_AND_FETCH_2:
6474     case BUILT_IN_SYNC_OR_AND_FETCH_4:
6475     case BUILT_IN_SYNC_OR_AND_FETCH_8:
6476     case BUILT_IN_SYNC_OR_AND_FETCH_16:
6477       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_OR_AND_FETCH_1);
6478       target = expand_builtin_sync_operation (mode, exp, IOR, true, target);
6479       if (target)
6480         return target;
6481       break;
6482
6483     case BUILT_IN_SYNC_AND_AND_FETCH_1:
6484     case BUILT_IN_SYNC_AND_AND_FETCH_2:
6485     case BUILT_IN_SYNC_AND_AND_FETCH_4:
6486     case BUILT_IN_SYNC_AND_AND_FETCH_8:
6487     case BUILT_IN_SYNC_AND_AND_FETCH_16:
6488       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_AND_AND_FETCH_1);
6489       target = expand_builtin_sync_operation (mode, exp, AND, true, target);
6490       if (target)
6491         return target;
6492       break;
6493
6494     case BUILT_IN_SYNC_XOR_AND_FETCH_1:
6495     case BUILT_IN_SYNC_XOR_AND_FETCH_2:
6496     case BUILT_IN_SYNC_XOR_AND_FETCH_4:
6497     case BUILT_IN_SYNC_XOR_AND_FETCH_8:
6498     case BUILT_IN_SYNC_XOR_AND_FETCH_16:
6499       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_XOR_AND_FETCH_1);
6500       target = expand_builtin_sync_operation (mode, exp, XOR, true, target);
6501       if (target)
6502         return target;
6503       break;
6504
6505     case BUILT_IN_SYNC_NAND_AND_FETCH_1:
6506     case BUILT_IN_SYNC_NAND_AND_FETCH_2:
6507     case BUILT_IN_SYNC_NAND_AND_FETCH_4:
6508     case BUILT_IN_SYNC_NAND_AND_FETCH_8:
6509     case BUILT_IN_SYNC_NAND_AND_FETCH_16:
6510       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_NAND_AND_FETCH_1);
6511       target = expand_builtin_sync_operation (mode, exp, NOT, true, target);
6512       if (target)
6513         return target;
6514       break;
6515
6516     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
6517     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
6518     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
6519     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
6520     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
6521       if (mode == VOIDmode)
6522         mode = TYPE_MODE (boolean_type_node);
6523       if (!target || !register_operand (target, mode))
6524         target = gen_reg_rtx (mode);
6525
6526       mode = get_builtin_sync_mode 
6527                                 (fcode - BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1);
6528       target = expand_builtin_compare_and_swap (mode, exp, true, target);
6529       if (target)
6530         return target;
6531       break;
6532
6533     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
6534     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
6535     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
6536     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
6537     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
6538       mode = get_builtin_sync_mode 
6539                                 (fcode - BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1);
6540       target = expand_builtin_compare_and_swap (mode, exp, false, target);
6541       if (target)
6542         return target;
6543       break;
6544
6545     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
6546     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
6547     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
6548     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
6549     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
6550       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_TEST_AND_SET_1);
6551       target = expand_builtin_sync_lock_test_and_set (mode, exp, target);
6552       if (target)
6553         return target;
6554       break;
6555
6556     case BUILT_IN_SYNC_LOCK_RELEASE_1:
6557     case BUILT_IN_SYNC_LOCK_RELEASE_2:
6558     case BUILT_IN_SYNC_LOCK_RELEASE_4:
6559     case BUILT_IN_SYNC_LOCK_RELEASE_8:
6560     case BUILT_IN_SYNC_LOCK_RELEASE_16:
6561       mode = get_builtin_sync_mode (fcode - BUILT_IN_SYNC_LOCK_RELEASE_1);
6562       expand_builtin_sync_lock_release (mode, exp);
6563       return const0_rtx;
6564
6565     case BUILT_IN_SYNC_SYNCHRONIZE:
6566       expand_builtin_sync_synchronize ();
6567       return const0_rtx;
6568
6569     case BUILT_IN_ATOMIC_EXCHANGE_1:
6570     case BUILT_IN_ATOMIC_EXCHANGE_2:
6571     case BUILT_IN_ATOMIC_EXCHANGE_4:
6572     case BUILT_IN_ATOMIC_EXCHANGE_8:
6573     case BUILT_IN_ATOMIC_EXCHANGE_16:
6574       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_EXCHANGE_1);
6575       target = expand_builtin_atomic_exchange (mode, exp, target);
6576       if (target)
6577         return target;
6578       break;
6579
6580     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
6581     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
6582     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
6583     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
6584     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
6585       {
6586         unsigned int nargs, z;
6587         vec<tree, va_gc> *vec;
6588
6589         mode = 
6590             get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1);
6591         target = expand_builtin_atomic_compare_exchange (mode, exp, target);
6592         if (target)
6593           return target;
6594
6595         /* If this is turned into an external library call, the weak parameter
6596            must be dropped to match the expected parameter list.  */
6597         nargs = call_expr_nargs (exp);
6598         vec_alloc (vec, nargs - 1);
6599         for (z = 0; z < 3; z++)
6600           vec->quick_push (CALL_EXPR_ARG (exp, z));
6601         /* Skip the boolean weak parameter.  */
6602         for (z = 4; z < 6; z++)
6603           vec->quick_push (CALL_EXPR_ARG (exp, z));
6604         exp = build_call_vec (TREE_TYPE (exp), CALL_EXPR_FN (exp), vec);
6605         break;
6606       }
6607
6608     case BUILT_IN_ATOMIC_LOAD_1:
6609     case BUILT_IN_ATOMIC_LOAD_2:
6610     case BUILT_IN_ATOMIC_LOAD_4:
6611     case BUILT_IN_ATOMIC_LOAD_8:
6612     case BUILT_IN_ATOMIC_LOAD_16:
6613       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_LOAD_1);
6614       target = expand_builtin_atomic_load (mode, exp, target);
6615       if (target)
6616         return target;
6617       break;
6618
6619     case BUILT_IN_ATOMIC_STORE_1:
6620     case BUILT_IN_ATOMIC_STORE_2:
6621     case BUILT_IN_ATOMIC_STORE_4:
6622     case BUILT_IN_ATOMIC_STORE_8:
6623     case BUILT_IN_ATOMIC_STORE_16:
6624       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_STORE_1);
6625       target = expand_builtin_atomic_store (mode, exp);
6626       if (target)
6627         return const0_rtx;
6628       break;
6629
6630     case BUILT_IN_ATOMIC_ADD_FETCH_1:
6631     case BUILT_IN_ATOMIC_ADD_FETCH_2:
6632     case BUILT_IN_ATOMIC_ADD_FETCH_4:
6633     case BUILT_IN_ATOMIC_ADD_FETCH_8:
6634     case BUILT_IN_ATOMIC_ADD_FETCH_16:
6635       {
6636         enum built_in_function lib;
6637         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1);
6638         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_ADD_1 + 
6639                                        (fcode - BUILT_IN_ATOMIC_ADD_FETCH_1));
6640         target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, true,
6641                                                  ignore, lib);
6642         if (target)
6643           return target;
6644         break;
6645       }
6646     case BUILT_IN_ATOMIC_SUB_FETCH_1:
6647     case BUILT_IN_ATOMIC_SUB_FETCH_2:
6648     case BUILT_IN_ATOMIC_SUB_FETCH_4:
6649     case BUILT_IN_ATOMIC_SUB_FETCH_8:
6650     case BUILT_IN_ATOMIC_SUB_FETCH_16:
6651       {
6652         enum built_in_function lib;
6653         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1);
6654         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_SUB_1 + 
6655                                        (fcode - BUILT_IN_ATOMIC_SUB_FETCH_1));
6656         target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, true,
6657                                                  ignore, lib);
6658         if (target)
6659           return target;
6660         break;
6661       }
6662     case BUILT_IN_ATOMIC_AND_FETCH_1:
6663     case BUILT_IN_ATOMIC_AND_FETCH_2:
6664     case BUILT_IN_ATOMIC_AND_FETCH_4:
6665     case BUILT_IN_ATOMIC_AND_FETCH_8:
6666     case BUILT_IN_ATOMIC_AND_FETCH_16:
6667       {
6668         enum built_in_function lib;
6669         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_AND_FETCH_1);
6670         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_AND_1 + 
6671                                        (fcode - BUILT_IN_ATOMIC_AND_FETCH_1));
6672         target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, true,
6673                                                  ignore, lib);
6674         if (target)
6675           return target;
6676         break;
6677       }
6678     case BUILT_IN_ATOMIC_NAND_FETCH_1:
6679     case BUILT_IN_ATOMIC_NAND_FETCH_2:
6680     case BUILT_IN_ATOMIC_NAND_FETCH_4:
6681     case BUILT_IN_ATOMIC_NAND_FETCH_8:
6682     case BUILT_IN_ATOMIC_NAND_FETCH_16:
6683       {
6684         enum built_in_function lib;
6685         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1);
6686         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_NAND_1 + 
6687                                        (fcode - BUILT_IN_ATOMIC_NAND_FETCH_1));
6688         target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, true,
6689                                                  ignore, lib);
6690         if (target)
6691           return target;
6692         break;
6693       }
6694     case BUILT_IN_ATOMIC_XOR_FETCH_1:
6695     case BUILT_IN_ATOMIC_XOR_FETCH_2:
6696     case BUILT_IN_ATOMIC_XOR_FETCH_4:
6697     case BUILT_IN_ATOMIC_XOR_FETCH_8:
6698     case BUILT_IN_ATOMIC_XOR_FETCH_16:
6699       {
6700         enum built_in_function lib;
6701         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1);
6702         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_XOR_1 + 
6703                                        (fcode - BUILT_IN_ATOMIC_XOR_FETCH_1));
6704         target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, true,
6705                                                  ignore, lib);
6706         if (target)
6707           return target;
6708         break;
6709       }
6710     case BUILT_IN_ATOMIC_OR_FETCH_1:
6711     case BUILT_IN_ATOMIC_OR_FETCH_2:
6712     case BUILT_IN_ATOMIC_OR_FETCH_4:
6713     case BUILT_IN_ATOMIC_OR_FETCH_8:
6714     case BUILT_IN_ATOMIC_OR_FETCH_16:
6715       {
6716         enum built_in_function lib;
6717         mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_OR_FETCH_1);
6718         lib = (enum built_in_function)((int)BUILT_IN_ATOMIC_FETCH_OR_1 + 
6719                                        (fcode - BUILT_IN_ATOMIC_OR_FETCH_1));
6720         target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, true,
6721                                                  ignore, lib);
6722         if (target)
6723           return target;
6724         break;
6725       }
6726     case BUILT_IN_ATOMIC_FETCH_ADD_1:
6727     case BUILT_IN_ATOMIC_FETCH_ADD_2:
6728     case BUILT_IN_ATOMIC_FETCH_ADD_4:
6729     case BUILT_IN_ATOMIC_FETCH_ADD_8:
6730     case BUILT_IN_ATOMIC_FETCH_ADD_16:
6731       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_ADD_1);
6732       target = expand_builtin_atomic_fetch_op (mode, exp, target, PLUS, false,
6733                                                ignore, BUILT_IN_NONE);
6734       if (target)
6735         return target;
6736       break;
6737  
6738     case BUILT_IN_ATOMIC_FETCH_SUB_1:
6739     case BUILT_IN_ATOMIC_FETCH_SUB_2:
6740     case BUILT_IN_ATOMIC_FETCH_SUB_4:
6741     case BUILT_IN_ATOMIC_FETCH_SUB_8:
6742     case BUILT_IN_ATOMIC_FETCH_SUB_16:
6743       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_SUB_1);
6744       target = expand_builtin_atomic_fetch_op (mode, exp, target, MINUS, false,
6745                                                ignore, BUILT_IN_NONE);
6746       if (target)
6747         return target;
6748       break;
6749
6750     case BUILT_IN_ATOMIC_FETCH_AND_1:
6751     case BUILT_IN_ATOMIC_FETCH_AND_2:
6752     case BUILT_IN_ATOMIC_FETCH_AND_4:
6753     case BUILT_IN_ATOMIC_FETCH_AND_8:
6754     case BUILT_IN_ATOMIC_FETCH_AND_16:
6755       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_AND_1);
6756       target = expand_builtin_atomic_fetch_op (mode, exp, target, AND, false,
6757                                                ignore, BUILT_IN_NONE);
6758       if (target)
6759         return target;
6760       break;
6761   
6762     case BUILT_IN_ATOMIC_FETCH_NAND_1:
6763     case BUILT_IN_ATOMIC_FETCH_NAND_2:
6764     case BUILT_IN_ATOMIC_FETCH_NAND_4:
6765     case BUILT_IN_ATOMIC_FETCH_NAND_8:
6766     case BUILT_IN_ATOMIC_FETCH_NAND_16:
6767       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_NAND_1);
6768       target = expand_builtin_atomic_fetch_op (mode, exp, target, NOT, false,
6769                                                ignore, BUILT_IN_NONE);
6770       if (target)
6771         return target;
6772       break;
6773  
6774     case BUILT_IN_ATOMIC_FETCH_XOR_1:
6775     case BUILT_IN_ATOMIC_FETCH_XOR_2:
6776     case BUILT_IN_ATOMIC_FETCH_XOR_4:
6777     case BUILT_IN_ATOMIC_FETCH_XOR_8:
6778     case BUILT_IN_ATOMIC_FETCH_XOR_16:
6779       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_XOR_1);
6780       target = expand_builtin_atomic_fetch_op (mode, exp, target, XOR, false,
6781                                                ignore, BUILT_IN_NONE);
6782       if (target)
6783         return target;
6784       break;
6785  
6786     case BUILT_IN_ATOMIC_FETCH_OR_1:
6787     case BUILT_IN_ATOMIC_FETCH_OR_2:
6788     case BUILT_IN_ATOMIC_FETCH_OR_4:
6789     case BUILT_IN_ATOMIC_FETCH_OR_8:
6790     case BUILT_IN_ATOMIC_FETCH_OR_16:
6791       mode = get_builtin_sync_mode (fcode - BUILT_IN_ATOMIC_FETCH_OR_1);
6792       target = expand_builtin_atomic_fetch_op (mode, exp, target, IOR, false,
6793                                                ignore, BUILT_IN_NONE);
6794       if (target)
6795         return target;
6796       break;
6797
6798     case BUILT_IN_ATOMIC_TEST_AND_SET:
6799       return expand_builtin_atomic_test_and_set (exp, target);
6800
6801     case BUILT_IN_ATOMIC_CLEAR:
6802       return expand_builtin_atomic_clear (exp);
6803  
6804     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
6805       return expand_builtin_atomic_always_lock_free (exp);
6806
6807     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
6808       target = expand_builtin_atomic_is_lock_free (exp);
6809       if (target)
6810         return target;
6811       break;
6812
6813     case BUILT_IN_ATOMIC_THREAD_FENCE:
6814       expand_builtin_atomic_thread_fence (exp);
6815       return const0_rtx;
6816
6817     case BUILT_IN_ATOMIC_SIGNAL_FENCE:
6818       expand_builtin_atomic_signal_fence (exp);
6819       return const0_rtx;
6820
6821     case BUILT_IN_OBJECT_SIZE:
6822       return expand_builtin_object_size (exp);
6823
6824     case BUILT_IN_MEMCPY_CHK:
6825     case BUILT_IN_MEMPCPY_CHK:
6826     case BUILT_IN_MEMMOVE_CHK:
6827     case BUILT_IN_MEMSET_CHK:
6828       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6829       if (target)
6830         return target;
6831       break;
6832
6833     case BUILT_IN_STRCPY_CHK:
6834     case BUILT_IN_STPCPY_CHK:
6835     case BUILT_IN_STRNCPY_CHK:
6836     case BUILT_IN_STPNCPY_CHK:
6837     case BUILT_IN_STRCAT_CHK:
6838     case BUILT_IN_STRNCAT_CHK:
6839     case BUILT_IN_SNPRINTF_CHK:
6840     case BUILT_IN_VSNPRINTF_CHK:
6841       maybe_emit_chk_warning (exp, fcode);
6842       break;
6843
6844     case BUILT_IN_SPRINTF_CHK:
6845     case BUILT_IN_VSPRINTF_CHK:
6846       maybe_emit_sprintf_chk_warning (exp, fcode);
6847       break;
6848
6849     case BUILT_IN_FREE:
6850       if (warn_free_nonheap_object)
6851         maybe_emit_free_warning (exp);
6852       break;
6853
6854     case BUILT_IN_THREAD_POINTER:
6855       return expand_builtin_thread_pointer (exp, target);
6856
6857     case BUILT_IN_SET_THREAD_POINTER:
6858       expand_builtin_set_thread_pointer (exp);
6859       return const0_rtx;
6860
6861     default:    /* just do library call, if unknown builtin */
6862       break;
6863     }
6864
6865   /* The switch statement above can drop through to cause the function
6866      to be called normally.  */
6867   return expand_call (exp, target, ignore);
6868 }
6869
6870 /* Determine whether a tree node represents a call to a built-in
6871    function.  If the tree T is a call to a built-in function with
6872    the right number of arguments of the appropriate types, return
6873    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6874    Otherwise the return value is END_BUILTINS.  */
6875
6876 enum built_in_function
6877 builtin_mathfn_code (const_tree t)
6878 {
6879   const_tree fndecl, arg, parmlist;
6880   const_tree argtype, parmtype;
6881   const_call_expr_arg_iterator iter;
6882
6883   if (TREE_CODE (t) != CALL_EXPR
6884       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6885     return END_BUILTINS;
6886
6887   fndecl = get_callee_fndecl (t);
6888   if (fndecl == NULL_TREE
6889       || TREE_CODE (fndecl) != FUNCTION_DECL
6890       || ! DECL_BUILT_IN (fndecl)
6891       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6892     return END_BUILTINS;
6893
6894   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6895   init_const_call_expr_arg_iterator (t, &iter);
6896   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6897     {
6898       /* If a function doesn't take a variable number of arguments,
6899          the last element in the list will have type `void'.  */
6900       parmtype = TREE_VALUE (parmlist);
6901       if (VOID_TYPE_P (parmtype))
6902         {
6903           if (more_const_call_expr_args_p (&iter))
6904             return END_BUILTINS;
6905           return DECL_FUNCTION_CODE (fndecl);
6906         }
6907
6908       if (! more_const_call_expr_args_p (&iter))
6909         return END_BUILTINS;
6910
6911       arg = next_const_call_expr_arg (&iter);
6912       argtype = TREE_TYPE (arg);
6913
6914       if (SCALAR_FLOAT_TYPE_P (parmtype))
6915         {
6916           if (! SCALAR_FLOAT_TYPE_P (argtype))
6917             return END_BUILTINS;
6918         }
6919       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6920         {
6921           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6922             return END_BUILTINS;
6923         }
6924       else if (POINTER_TYPE_P (parmtype))
6925         {
6926           if (! POINTER_TYPE_P (argtype))
6927             return END_BUILTINS;
6928         }
6929       else if (INTEGRAL_TYPE_P (parmtype))
6930         {
6931           if (! INTEGRAL_TYPE_P (argtype))
6932             return END_BUILTINS;
6933         }
6934       else
6935         return END_BUILTINS;
6936     }
6937
6938   /* Variable-length argument list.  */
6939   return DECL_FUNCTION_CODE (fndecl);
6940 }
6941
6942 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
6943    evaluate to a constant.  */
6944
6945 static tree
6946 fold_builtin_constant_p (tree arg)
6947 {
6948   /* We return 1 for a numeric type that's known to be a constant
6949      value at compile-time or for an aggregate type that's a
6950      literal constant.  */
6951   STRIP_NOPS (arg);
6952
6953   /* If we know this is a constant, emit the constant of one.  */
6954   if (CONSTANT_CLASS_P (arg)
6955       || (TREE_CODE (arg) == CONSTRUCTOR
6956           && TREE_CONSTANT (arg)))
6957     return integer_one_node;
6958   if (TREE_CODE (arg) == ADDR_EXPR)
6959     {
6960        tree op = TREE_OPERAND (arg, 0);
6961        if (TREE_CODE (op) == STRING_CST
6962            || (TREE_CODE (op) == ARRAY_REF
6963                && integer_zerop (TREE_OPERAND (op, 1))
6964                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6965          return integer_one_node;
6966     }
6967
6968   /* If this expression has side effects, show we don't know it to be a
6969      constant.  Likewise if it's a pointer or aggregate type since in
6970      those case we only want literals, since those are only optimized
6971      when generating RTL, not later.
6972      And finally, if we are compiling an initializer, not code, we
6973      need to return a definite result now; there's not going to be any
6974      more optimization done.  */
6975   if (TREE_SIDE_EFFECTS (arg)
6976       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6977       || POINTER_TYPE_P (TREE_TYPE (arg))
6978       || cfun == 0
6979       || folding_initializer)
6980     return integer_zero_node;
6981
6982   return NULL_TREE;
6983 }
6984
6985 /* Create builtin_expect with PRED and EXPECTED as its arguments and
6986    return it as a truthvalue.  */
6987
6988 static tree
6989 build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6990 {
6991   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6992
6993   fn = builtin_decl_explicit (BUILT_IN_EXPECT);
6994   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6995   ret_type = TREE_TYPE (TREE_TYPE (fn));
6996   pred_type = TREE_VALUE (arg_types);
6997   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6998
6999   pred = fold_convert_loc (loc, pred_type, pred);
7000   expected = fold_convert_loc (loc, expected_type, expected);
7001   call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
7002
7003   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7004                  build_int_cst (ret_type, 0));
7005 }
7006
7007 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
7008    NULL_TREE if no simplification is possible.  */
7009
7010 static tree
7011 fold_builtin_expect (location_t loc, tree arg0, tree arg1)
7012 {
7013   tree inner, fndecl, inner_arg0;
7014   enum tree_code code;
7015
7016   /* Distribute the expected value over short-circuiting operators.
7017      See through the cast from truthvalue_type_node to long.  */
7018   inner_arg0 = arg0;
7019   while (TREE_CODE (inner_arg0) == NOP_EXPR
7020          && INTEGRAL_TYPE_P (TREE_TYPE (inner_arg0))
7021          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner_arg0, 0))))
7022     inner_arg0 = TREE_OPERAND (inner_arg0, 0);
7023
7024   /* If this is a builtin_expect within a builtin_expect keep the
7025      inner one.  See through a comparison against a constant.  It
7026      might have been added to create a thruthvalue.  */
7027   inner = inner_arg0;
7028
7029   if (COMPARISON_CLASS_P (inner)
7030       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7031     inner = TREE_OPERAND (inner, 0);
7032
7033   if (TREE_CODE (inner) == CALL_EXPR
7034       && (fndecl = get_callee_fndecl (inner))
7035       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7036       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7037     return arg0;
7038
7039   inner = inner_arg0;
7040   code = TREE_CODE (inner);
7041   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7042     {
7043       tree op0 = TREE_OPERAND (inner, 0);
7044       tree op1 = TREE_OPERAND (inner, 1);
7045
7046       op0 = build_builtin_expect_predicate (loc, op0, arg1);
7047       op1 = build_builtin_expect_predicate (loc, op1, arg1);
7048       inner = build2 (code, TREE_TYPE (inner), op0, op1);
7049
7050       return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
7051     }
7052
7053   /* If the argument isn't invariant then there's nothing else we can do.  */
7054   if (!TREE_CONSTANT (inner_arg0))
7055     return NULL_TREE;
7056
7057   /* If we expect that a comparison against the argument will fold to
7058      a constant return the constant.  In practice, this means a true
7059      constant or the address of a non-weak symbol.  */
7060   inner = inner_arg0;
7061   STRIP_NOPS (inner);
7062   if (TREE_CODE (inner) == ADDR_EXPR)
7063     {
7064       do
7065         {
7066           inner = TREE_OPERAND (inner, 0);
7067         }
7068       while (TREE_CODE (inner) == COMPONENT_REF
7069              || TREE_CODE (inner) == ARRAY_REF);
7070       if ((TREE_CODE (inner) == VAR_DECL
7071            || TREE_CODE (inner) == FUNCTION_DECL)
7072           && DECL_WEAK (inner))
7073         return NULL_TREE;
7074     }
7075
7076   /* Otherwise, ARG0 already has the proper type for the return value.  */
7077   return arg0;
7078 }
7079
7080 /* Fold a call to __builtin_classify_type with argument ARG.  */
7081
7082 static tree
7083 fold_builtin_classify_type (tree arg)
7084 {
7085   if (arg == 0)
7086     return build_int_cst (integer_type_node, no_type_class);
7087
7088   return build_int_cst (integer_type_node, type_to_class (TREE_TYPE (arg)));
7089 }
7090
7091 /* Fold a call to __builtin_strlen with argument ARG.  */
7092
7093 static tree
7094 fold_builtin_strlen (location_t loc, tree type, tree arg)
7095 {
7096   if (!validate_arg (arg, POINTER_TYPE))
7097     return NULL_TREE;
7098   else
7099     {
7100       tree len = c_strlen (arg, 0);
7101
7102       if (len)
7103         return fold_convert_loc (loc, type, len);
7104
7105       return NULL_TREE;
7106     }
7107 }
7108
7109 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
7110
7111 static tree
7112 fold_builtin_inf (location_t loc, tree type, int warn)
7113 {
7114   REAL_VALUE_TYPE real;
7115
7116   /* __builtin_inff is intended to be usable to define INFINITY on all
7117      targets.  If an infinity is not available, INFINITY expands "to a
7118      positive constant of type float that overflows at translation
7119      time", footnote "In this case, using INFINITY will violate the
7120      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7121      Thus we pedwarn to ensure this constraint violation is
7122      diagnosed.  */
7123   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7124     pedwarn (loc, 0, "target format does not support infinity");
7125
7126   real_inf (&real);
7127   return build_real (type, real);
7128 }
7129
7130 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7131
7132 static tree
7133 fold_builtin_nan (tree arg, tree type, int quiet)
7134 {
7135   REAL_VALUE_TYPE real;
7136   const char *str;
7137
7138   if (!validate_arg (arg, POINTER_TYPE))
7139     return NULL_TREE;
7140   str = c_getstr (arg);
7141   if (!str)
7142     return NULL_TREE;
7143
7144   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7145     return NULL_TREE;
7146
7147   return build_real (type, real);
7148 }
7149
7150 /* Return true if the floating point expression T has an integer value.
7151    We also allow +Inf, -Inf and NaN to be considered integer values.  */
7152
7153 static bool
7154 integer_valued_real_p (tree t)
7155 {
7156   switch (TREE_CODE (t))
7157     {
7158     case FLOAT_EXPR:
7159       return true;
7160
7161     case ABS_EXPR:
7162     case SAVE_EXPR:
7163       return integer_valued_real_p (TREE_OPERAND (t, 0));
7164
7165     case COMPOUND_EXPR:
7166     case MODIFY_EXPR:
7167     case BIND_EXPR:
7168       return integer_valued_real_p (TREE_OPERAND (t, 1));
7169
7170     case PLUS_EXPR:
7171     case MINUS_EXPR:
7172     case MULT_EXPR:
7173     case MIN_EXPR:
7174     case MAX_EXPR:
7175       return integer_valued_real_p (TREE_OPERAND (t, 0))
7176              && integer_valued_real_p (TREE_OPERAND (t, 1));
7177
7178     case COND_EXPR:
7179       return integer_valued_real_p (TREE_OPERAND (t, 1))
7180              && integer_valued_real_p (TREE_OPERAND (t, 2));
7181
7182     case REAL_CST:
7183       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7184
7185     case NOP_EXPR:
7186       {
7187         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7188         if (TREE_CODE (type) == INTEGER_TYPE)
7189           return true;
7190         if (TREE_CODE (type) == REAL_TYPE)
7191           return integer_valued_real_p (TREE_OPERAND (t, 0));
7192         break;
7193       }
7194
7195     case CALL_EXPR:
7196       switch (builtin_mathfn_code (t))
7197         {
7198         CASE_FLT_FN (BUILT_IN_CEIL):
7199         CASE_FLT_FN (BUILT_IN_FLOOR):
7200         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7201         CASE_FLT_FN (BUILT_IN_RINT):
7202         CASE_FLT_FN (BUILT_IN_ROUND):
7203         CASE_FLT_FN (BUILT_IN_TRUNC):
7204           return true;
7205
7206         CASE_FLT_FN (BUILT_IN_FMIN):
7207         CASE_FLT_FN (BUILT_IN_FMAX):
7208           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7209             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7210
7211         default:
7212           break;
7213         }
7214       break;
7215
7216     default:
7217       break;
7218     }
7219   return false;
7220 }
7221
7222 /* FNDECL is assumed to be a builtin where truncation can be propagated
7223    across (for instance floor((double)f) == (double)floorf (f).
7224    Do the transformation for a call with argument ARG.  */
7225
7226 static tree
7227 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7228 {
7229   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7230
7231   if (!validate_arg (arg, REAL_TYPE))
7232     return NULL_TREE;
7233
7234   /* Integer rounding functions are idempotent.  */
7235   if (fcode == builtin_mathfn_code (arg))
7236     return arg;
7237
7238   /* If argument is already integer valued, and we don't need to worry
7239      about setting errno, there's no need to perform rounding.  */
7240   if (! flag_errno_math && integer_valued_real_p (arg))
7241     return arg;
7242
7243   if (optimize)
7244     {
7245       tree arg0 = strip_float_extensions (arg);
7246       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7247       tree newtype = TREE_TYPE (arg0);
7248       tree decl;
7249
7250       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7251           && (decl = mathfn_built_in (newtype, fcode)))
7252         return fold_convert_loc (loc, ftype,
7253                                  build_call_expr_loc (loc, decl, 1,
7254                                                   fold_convert_loc (loc,
7255                                                                     newtype,
7256                                                                     arg0)));
7257     }
7258   return NULL_TREE;
7259 }
7260
7261 /* FNDECL is assumed to be builtin which can narrow the FP type of
7262    the argument, for instance lround((double)f) -> lroundf (f).
7263    Do the transformation for a call with argument ARG.  */
7264
7265 static tree
7266 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7267 {
7268   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7269
7270   if (!validate_arg (arg, REAL_TYPE))
7271     return NULL_TREE;
7272
7273   /* If argument is already integer valued, and we don't need to worry
7274      about setting errno, there's no need to perform rounding.  */
7275   if (! flag_errno_math && integer_valued_real_p (arg))
7276     return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7277                         TREE_TYPE (TREE_TYPE (fndecl)), arg);
7278
7279   if (optimize)
7280     {
7281       tree ftype = TREE_TYPE (arg);
7282       tree arg0 = strip_float_extensions (arg);
7283       tree newtype = TREE_TYPE (arg0);
7284       tree decl;
7285
7286       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7287           && (decl = mathfn_built_in (newtype, fcode)))
7288         return build_call_expr_loc (loc, decl, 1,
7289                                 fold_convert_loc (loc, newtype, arg0));
7290     }
7291
7292   /* Canonicalize iround (x) to lround (x) on ILP32 targets where
7293      sizeof (int) == sizeof (long).  */
7294   if (TYPE_PRECISION (integer_type_node)
7295       == TYPE_PRECISION (long_integer_type_node))
7296     {
7297       tree newfn = NULL_TREE;
7298       switch (fcode)
7299         {
7300         CASE_FLT_FN (BUILT_IN_ICEIL):
7301           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7302           break;
7303
7304         CASE_FLT_FN (BUILT_IN_IFLOOR):
7305           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7306           break;
7307
7308         CASE_FLT_FN (BUILT_IN_IROUND):
7309           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7310           break;
7311
7312         CASE_FLT_FN (BUILT_IN_IRINT):
7313           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7314           break;
7315
7316         default:
7317           break;
7318         }
7319
7320       if (newfn)
7321         {
7322           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7323           return fold_convert_loc (loc,
7324                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7325         }
7326     }
7327
7328   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7329      sizeof (long long) == sizeof (long).  */
7330   if (TYPE_PRECISION (long_long_integer_type_node)
7331       == TYPE_PRECISION (long_integer_type_node))
7332     {
7333       tree newfn = NULL_TREE;
7334       switch (fcode)
7335         {
7336         CASE_FLT_FN (BUILT_IN_LLCEIL):
7337           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7338           break;
7339
7340         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7341           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7342           break;
7343
7344         CASE_FLT_FN (BUILT_IN_LLROUND):
7345           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7346           break;
7347
7348         CASE_FLT_FN (BUILT_IN_LLRINT):
7349           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7350           break;
7351
7352         default:
7353           break;
7354         }
7355
7356       if (newfn)
7357         {
7358           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7359           return fold_convert_loc (loc,
7360                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7361         }
7362     }
7363
7364   return NULL_TREE;
7365 }
7366
7367 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7368    return type.  Return NULL_TREE if no simplification can be made.  */
7369
7370 static tree
7371 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7372 {
7373   tree res;
7374
7375   if (!validate_arg (arg, COMPLEX_TYPE)
7376       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7377     return NULL_TREE;
7378
7379   /* Calculate the result when the argument is a constant.  */
7380   if (TREE_CODE (arg) == COMPLEX_CST
7381       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7382                               type, mpfr_hypot)))
7383     return res;
7384
7385   if (TREE_CODE (arg) == COMPLEX_EXPR)
7386     {
7387       tree real = TREE_OPERAND (arg, 0);
7388       tree imag = TREE_OPERAND (arg, 1);
7389
7390       /* If either part is zero, cabs is fabs of the other.  */
7391       if (real_zerop (real))
7392         return fold_build1_loc (loc, ABS_EXPR, type, imag);
7393       if (real_zerop (imag))
7394         return fold_build1_loc (loc, ABS_EXPR, type, real);
7395
7396       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7397       if (flag_unsafe_math_optimizations
7398           && operand_equal_p (real, imag, OEP_PURE_SAME))
7399         {
7400           const REAL_VALUE_TYPE sqrt2_trunc
7401             = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7402           STRIP_NOPS (real);
7403           return fold_build2_loc (loc, MULT_EXPR, type,
7404                               fold_build1_loc (loc, ABS_EXPR, type, real),
7405                               build_real (type, sqrt2_trunc));
7406         }
7407     }
7408
7409   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7410   if (TREE_CODE (arg) == NEGATE_EXPR
7411       || TREE_CODE (arg) == CONJ_EXPR)
7412     return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7413
7414   /* Don't do this when optimizing for size.  */
7415   if (flag_unsafe_math_optimizations
7416       && optimize && optimize_function_for_speed_p (cfun))
7417     {
7418       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7419
7420       if (sqrtfn != NULL_TREE)
7421         {
7422           tree rpart, ipart, result;
7423
7424           arg = builtin_save_expr (arg);
7425
7426           rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7427           ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7428
7429           rpart = builtin_save_expr (rpart);
7430           ipart = builtin_save_expr (ipart);
7431
7432           result = fold_build2_loc (loc, PLUS_EXPR, type,
7433                                 fold_build2_loc (loc, MULT_EXPR, type,
7434                                              rpart, rpart),
7435                                 fold_build2_loc (loc, MULT_EXPR, type,
7436                                              ipart, ipart));
7437
7438           return build_call_expr_loc (loc, sqrtfn, 1, result);
7439         }
7440     }
7441
7442   return NULL_TREE;
7443 }
7444
7445 /* Build a complex (inf +- 0i) for the result of cproj.  TYPE is the
7446    complex tree type of the result.  If NEG is true, the imaginary
7447    zero is negative.  */
7448
7449 static tree
7450 build_complex_cproj (tree type, bool neg)
7451 {
7452   REAL_VALUE_TYPE rinf, rzero = dconst0;
7453   
7454   real_inf (&rinf);
7455   rzero.sign = neg;
7456   return build_complex (type, build_real (TREE_TYPE (type), rinf),
7457                         build_real (TREE_TYPE (type), rzero));
7458 }
7459
7460 /* Fold call to builtin cproj, cprojf or cprojl with argument ARG.  TYPE is the
7461    return type.  Return NULL_TREE if no simplification can be made.  */
7462
7463 static tree
7464 fold_builtin_cproj (location_t loc, tree arg, tree type)
7465 {
7466   if (!validate_arg (arg, COMPLEX_TYPE)
7467       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7468     return NULL_TREE;
7469
7470   /* If there are no infinities, return arg.  */
7471   if (! HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (type))))
7472     return non_lvalue_loc (loc, arg);
7473
7474   /* Calculate the result when the argument is a constant.  */
7475   if (TREE_CODE (arg) == COMPLEX_CST)
7476     {
7477       const REAL_VALUE_TYPE *real = TREE_REAL_CST_PTR (TREE_REALPART (arg));
7478       const REAL_VALUE_TYPE *imag = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
7479       
7480       if (real_isinf (real) || real_isinf (imag))
7481         return build_complex_cproj (type, imag->sign);
7482       else
7483         return arg;
7484     }
7485   else if (TREE_CODE (arg) == COMPLEX_EXPR)
7486     {
7487       tree real = TREE_OPERAND (arg, 0);
7488       tree imag = TREE_OPERAND (arg, 1);
7489
7490       STRIP_NOPS (real);
7491       STRIP_NOPS (imag);
7492       
7493       /* If the real part is inf and the imag part is known to be
7494          nonnegative, return (inf + 0i).  Remember side-effects are
7495          possible in the imag part.  */
7496       if (TREE_CODE (real) == REAL_CST
7497           && real_isinf (TREE_REAL_CST_PTR (real))
7498           && tree_expr_nonnegative_p (imag))
7499         return omit_one_operand_loc (loc, type,
7500                                      build_complex_cproj (type, false),
7501                                      arg);
7502       
7503       /* If the imag part is inf, return (inf+I*copysign(0,imag)).
7504          Remember side-effects are possible in the real part.  */
7505       if (TREE_CODE (imag) == REAL_CST
7506           && real_isinf (TREE_REAL_CST_PTR (imag)))
7507         return
7508           omit_one_operand_loc (loc, type,
7509                                 build_complex_cproj (type, TREE_REAL_CST_PTR
7510                                                      (imag)->sign), arg);
7511     }
7512
7513   return NULL_TREE;
7514 }
7515
7516 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7517    Return NULL_TREE if no simplification can be made.  */
7518
7519 static tree
7520 fold_builtin_sqrt (location_t loc, tree arg, tree type)
7521 {
7522
7523   enum built_in_function fcode;
7524   tree res;
7525
7526   if (!validate_arg (arg, REAL_TYPE))
7527     return NULL_TREE;
7528
7529   /* Calculate the result when the argument is a constant.  */
7530   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7531     return res;
7532
7533   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7534   fcode = builtin_mathfn_code (arg);
7535   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7536     {
7537       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7538       arg = fold_build2_loc (loc, MULT_EXPR, type,
7539                          CALL_EXPR_ARG (arg, 0),
7540                          build_real (type, dconsthalf));
7541       return build_call_expr_loc (loc, expfn, 1, arg);
7542     }
7543
7544   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7545   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7546     {
7547       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7548
7549       if (powfn)
7550         {
7551           tree arg0 = CALL_EXPR_ARG (arg, 0);
7552           tree tree_root;
7553           /* The inner root was either sqrt or cbrt.  */
7554           /* This was a conditional expression but it triggered a bug
7555              in Sun C 5.5.  */
7556           REAL_VALUE_TYPE dconstroot;
7557           if (BUILTIN_SQRT_P (fcode))
7558             dconstroot = dconsthalf;
7559           else
7560             dconstroot = dconst_third ();
7561
7562           /* Adjust for the outer root.  */
7563           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7564           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7565           tree_root = build_real (type, dconstroot);
7566           return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7567         }
7568     }
7569
7570   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7571   if (flag_unsafe_math_optimizations
7572       && (fcode == BUILT_IN_POW
7573           || fcode == BUILT_IN_POWF
7574           || fcode == BUILT_IN_POWL))
7575     {
7576       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7577       tree arg0 = CALL_EXPR_ARG (arg, 0);
7578       tree arg1 = CALL_EXPR_ARG (arg, 1);
7579       tree narg1;
7580       if (!tree_expr_nonnegative_p (arg0))
7581         arg0 = build1 (ABS_EXPR, type, arg0);
7582       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7583                            build_real (type, dconsthalf));
7584       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7585     }
7586
7587   return NULL_TREE;
7588 }
7589
7590 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7591    Return NULL_TREE if no simplification can be made.  */
7592
7593 static tree
7594 fold_builtin_cbrt (location_t loc, tree arg, tree type)
7595 {
7596   const enum built_in_function fcode = builtin_mathfn_code (arg);
7597   tree res;
7598
7599   if (!validate_arg (arg, REAL_TYPE))
7600     return NULL_TREE;
7601
7602   /* Calculate the result when the argument is a constant.  */
7603   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7604     return res;
7605
7606   if (flag_unsafe_math_optimizations)
7607     {
7608       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7609       if (BUILTIN_EXPONENT_P (fcode))
7610         {
7611           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7612           const REAL_VALUE_TYPE third_trunc =
7613             real_value_truncate (TYPE_MODE (type), dconst_third ());
7614           arg = fold_build2_loc (loc, MULT_EXPR, type,
7615                              CALL_EXPR_ARG (arg, 0),
7616                              build_real (type, third_trunc));
7617           return build_call_expr_loc (loc, expfn, 1, arg);
7618         }
7619
7620       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7621       if (BUILTIN_SQRT_P (fcode))
7622         {
7623           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7624
7625           if (powfn)
7626             {
7627               tree arg0 = CALL_EXPR_ARG (arg, 0);
7628               tree tree_root;
7629               REAL_VALUE_TYPE dconstroot = dconst_third ();
7630
7631               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7632               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7633               tree_root = build_real (type, dconstroot);
7634               return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7635             }
7636         }
7637
7638       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7639       if (BUILTIN_CBRT_P (fcode))
7640         {
7641           tree arg0 = CALL_EXPR_ARG (arg, 0);
7642           if (tree_expr_nonnegative_p (arg0))
7643             {
7644               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7645
7646               if (powfn)
7647                 {
7648                   tree tree_root;
7649                   REAL_VALUE_TYPE dconstroot;
7650
7651                   real_arithmetic (&dconstroot, MULT_EXPR,
7652                                    dconst_third_ptr (), dconst_third_ptr ());
7653                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7654                   tree_root = build_real (type, dconstroot);
7655                   return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7656                 }
7657             }
7658         }
7659
7660       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7661       if (fcode == BUILT_IN_POW
7662           || fcode == BUILT_IN_POWF
7663           || fcode == BUILT_IN_POWL)
7664         {
7665           tree arg00 = CALL_EXPR_ARG (arg, 0);
7666           tree arg01 = CALL_EXPR_ARG (arg, 1);
7667           if (tree_expr_nonnegative_p (arg00))
7668             {
7669               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7670               const REAL_VALUE_TYPE dconstroot
7671                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7672               tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7673                                          build_real (type, dconstroot));
7674               return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7675             }
7676         }
7677     }
7678   return NULL_TREE;
7679 }
7680
7681 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7682    TYPE is the type of the return value.  Return NULL_TREE if no
7683    simplification can be made.  */
7684
7685 static tree
7686 fold_builtin_cos (location_t loc,
7687                   tree arg, tree type, tree fndecl)
7688 {
7689   tree res, narg;
7690
7691   if (!validate_arg (arg, REAL_TYPE))
7692     return NULL_TREE;
7693
7694   /* Calculate the result when the argument is a constant.  */
7695   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7696     return res;
7697
7698   /* Optimize cos(-x) into cos (x).  */
7699   if ((narg = fold_strip_sign_ops (arg)))
7700     return build_call_expr_loc (loc, fndecl, 1, narg);
7701
7702   return NULL_TREE;
7703 }
7704
7705 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7706    Return NULL_TREE if no simplification can be made.  */
7707
7708 static tree
7709 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7710 {
7711   if (validate_arg (arg, REAL_TYPE))
7712     {
7713       tree res, narg;
7714
7715       /* Calculate the result when the argument is a constant.  */
7716       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7717         return res;
7718
7719       /* Optimize cosh(-x) into cosh (x).  */
7720       if ((narg = fold_strip_sign_ops (arg)))
7721         return build_call_expr_loc (loc, fndecl, 1, narg);
7722     }
7723
7724   return NULL_TREE;
7725 }
7726
7727 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7728    argument ARG.  TYPE is the type of the return value.  Return
7729    NULL_TREE if no simplification can be made.  */
7730
7731 static tree
7732 fold_builtin_ccos (location_t loc, tree arg, tree type, tree fndecl,
7733                    bool hyper)
7734 {
7735   if (validate_arg (arg, COMPLEX_TYPE)
7736       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7737     {
7738       tree tmp;
7739
7740       /* Calculate the result when the argument is a constant.  */
7741       if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7742         return tmp;
7743
7744       /* Optimize fn(-x) into fn(x).  */
7745       if ((tmp = fold_strip_sign_ops (arg)))
7746         return build_call_expr_loc (loc, fndecl, 1, tmp);
7747     }
7748
7749   return NULL_TREE;
7750 }
7751
7752 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7753    Return NULL_TREE if no simplification can be made.  */
7754
7755 static tree
7756 fold_builtin_tan (tree arg, tree type)
7757 {
7758   enum built_in_function fcode;
7759   tree res;
7760
7761   if (!validate_arg (arg, REAL_TYPE))
7762     return NULL_TREE;
7763
7764   /* Calculate the result when the argument is a constant.  */
7765   if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7766     return res;
7767
7768   /* Optimize tan(atan(x)) = x.  */
7769   fcode = builtin_mathfn_code (arg);
7770   if (flag_unsafe_math_optimizations
7771       && (fcode == BUILT_IN_ATAN
7772           || fcode == BUILT_IN_ATANF
7773           || fcode == BUILT_IN_ATANL))
7774     return CALL_EXPR_ARG (arg, 0);
7775
7776   return NULL_TREE;
7777 }
7778
7779 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7780    NULL_TREE if no simplification can be made.  */
7781
7782 static tree
7783 fold_builtin_sincos (location_t loc,
7784                      tree arg0, tree arg1, tree arg2)
7785 {
7786   tree type;
7787   tree res, fn, call;
7788
7789   if (!validate_arg (arg0, REAL_TYPE)
7790       || !validate_arg (arg1, POINTER_TYPE)
7791       || !validate_arg (arg2, POINTER_TYPE))
7792     return NULL_TREE;
7793
7794   type = TREE_TYPE (arg0);
7795
7796   /* Calculate the result when the argument is a constant.  */
7797   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7798     return res;
7799
7800   /* Canonicalize sincos to cexpi.  */
7801   if (!TARGET_C99_FUNCTIONS)
7802     return NULL_TREE;
7803   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7804   if (!fn)
7805     return NULL_TREE;
7806
7807   call = build_call_expr_loc (loc, fn, 1, arg0);
7808   call = builtin_save_expr (call);
7809
7810   return build2 (COMPOUND_EXPR, void_type_node,
7811                  build2 (MODIFY_EXPR, void_type_node,
7812                          build_fold_indirect_ref_loc (loc, arg1),
7813                          build1 (IMAGPART_EXPR, type, call)),
7814                  build2 (MODIFY_EXPR, void_type_node,
7815                          build_fold_indirect_ref_loc (loc, arg2),
7816                          build1 (REALPART_EXPR, type, call)));
7817 }
7818
7819 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7820    NULL_TREE if no simplification can be made.  */
7821
7822 static tree
7823 fold_builtin_cexp (location_t loc, tree arg0, tree type)
7824 {
7825   tree rtype;
7826   tree realp, imagp, ifn;
7827   tree res;
7828
7829   if (!validate_arg (arg0, COMPLEX_TYPE)
7830       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7831     return NULL_TREE;
7832
7833   /* Calculate the result when the argument is a constant.  */
7834   if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7835     return res;
7836
7837   rtype = TREE_TYPE (TREE_TYPE (arg0));
7838
7839   /* In case we can figure out the real part of arg0 and it is constant zero
7840      fold to cexpi.  */
7841   if (!TARGET_C99_FUNCTIONS)
7842     return NULL_TREE;
7843   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7844   if (!ifn)
7845     return NULL_TREE;
7846
7847   if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7848       && real_zerop (realp))
7849     {
7850       tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7851       return build_call_expr_loc (loc, ifn, 1, narg);
7852     }
7853
7854   /* In case we can easily decompose real and imaginary parts split cexp
7855      to exp (r) * cexpi (i).  */
7856   if (flag_unsafe_math_optimizations
7857       && realp)
7858     {
7859       tree rfn, rcall, icall;
7860
7861       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7862       if (!rfn)
7863         return NULL_TREE;
7864
7865       imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7866       if (!imagp)
7867         return NULL_TREE;
7868
7869       icall = build_call_expr_loc (loc, ifn, 1, imagp);
7870       icall = builtin_save_expr (icall);
7871       rcall = build_call_expr_loc (loc, rfn, 1, realp);
7872       rcall = builtin_save_expr (rcall);
7873       return fold_build2_loc (loc, COMPLEX_EXPR, type,
7874                           fold_build2_loc (loc, MULT_EXPR, rtype,
7875                                        rcall,
7876                                        fold_build1_loc (loc, REALPART_EXPR,
7877                                                     rtype, icall)),
7878                           fold_build2_loc (loc, MULT_EXPR, rtype,
7879                                        rcall,
7880                                        fold_build1_loc (loc, IMAGPART_EXPR,
7881                                                     rtype, icall)));
7882     }
7883
7884   return NULL_TREE;
7885 }
7886
7887 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7888    Return NULL_TREE if no simplification can be made.  */
7889
7890 static tree
7891 fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7892 {
7893   if (!validate_arg (arg, REAL_TYPE))
7894     return NULL_TREE;
7895
7896   /* Optimize trunc of constant value.  */
7897   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7898     {
7899       REAL_VALUE_TYPE r, x;
7900       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7901
7902       x = TREE_REAL_CST (arg);
7903       real_trunc (&r, TYPE_MODE (type), &x);
7904       return build_real (type, r);
7905     }
7906
7907   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7908 }
7909
7910 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7911    Return NULL_TREE if no simplification can be made.  */
7912
7913 static tree
7914 fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7915 {
7916   if (!validate_arg (arg, REAL_TYPE))
7917     return NULL_TREE;
7918
7919   /* Optimize floor of constant value.  */
7920   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7921     {
7922       REAL_VALUE_TYPE x;
7923
7924       x = TREE_REAL_CST (arg);
7925       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7926         {
7927           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7928           REAL_VALUE_TYPE r;
7929
7930           real_floor (&r, TYPE_MODE (type), &x);
7931           return build_real (type, r);
7932         }
7933     }
7934
7935   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7936   if (tree_expr_nonnegative_p (arg))
7937     {
7938       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7939       if (truncfn)
7940         return build_call_expr_loc (loc, truncfn, 1, arg);
7941     }
7942
7943   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7944 }
7945
7946 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7947    Return NULL_TREE if no simplification can be made.  */
7948
7949 static tree
7950 fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7951 {
7952   if (!validate_arg (arg, REAL_TYPE))
7953     return NULL_TREE;
7954
7955   /* Optimize ceil of constant value.  */
7956   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7957     {
7958       REAL_VALUE_TYPE x;
7959
7960       x = TREE_REAL_CST (arg);
7961       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7962         {
7963           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7964           REAL_VALUE_TYPE r;
7965
7966           real_ceil (&r, TYPE_MODE (type), &x);
7967           return build_real (type, r);
7968         }
7969     }
7970
7971   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7972 }
7973
7974 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7975    Return NULL_TREE if no simplification can be made.  */
7976
7977 static tree
7978 fold_builtin_round (location_t loc, tree fndecl, tree arg)
7979 {
7980   if (!validate_arg (arg, REAL_TYPE))
7981     return NULL_TREE;
7982
7983   /* Optimize round of constant value.  */
7984   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7985     {
7986       REAL_VALUE_TYPE x;
7987
7988       x = TREE_REAL_CST (arg);
7989       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7990         {
7991           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7992           REAL_VALUE_TYPE r;
7993
7994           real_round (&r, TYPE_MODE (type), &x);
7995           return build_real (type, r);
7996         }
7997     }
7998
7999   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
8000 }
8001
8002 /* Fold function call to builtin lround, lroundf or lroundl (or the
8003    corresponding long long versions) and other rounding functions.  ARG
8004    is the argument to the call.  Return NULL_TREE if no simplification
8005    can be made.  */
8006
8007 static tree
8008 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
8009 {
8010   if (!validate_arg (arg, REAL_TYPE))
8011     return NULL_TREE;
8012
8013   /* Optimize lround of constant value.  */
8014   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8015     {
8016       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8017
8018       if (real_isfinite (&x))
8019         {
8020           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
8021           tree ftype = TREE_TYPE (arg);
8022           double_int val;
8023           REAL_VALUE_TYPE r;
8024
8025           switch (DECL_FUNCTION_CODE (fndecl))
8026             {
8027             CASE_FLT_FN (BUILT_IN_IFLOOR):
8028             CASE_FLT_FN (BUILT_IN_LFLOOR):
8029             CASE_FLT_FN (BUILT_IN_LLFLOOR):
8030               real_floor (&r, TYPE_MODE (ftype), &x);
8031               break;
8032
8033             CASE_FLT_FN (BUILT_IN_ICEIL):
8034             CASE_FLT_FN (BUILT_IN_LCEIL):
8035             CASE_FLT_FN (BUILT_IN_LLCEIL):
8036               real_ceil (&r, TYPE_MODE (ftype), &x);
8037               break;
8038
8039             CASE_FLT_FN (BUILT_IN_IROUND):
8040             CASE_FLT_FN (BUILT_IN_LROUND):
8041             CASE_FLT_FN (BUILT_IN_LLROUND):
8042               real_round (&r, TYPE_MODE (ftype), &x);
8043               break;
8044
8045             default:
8046               gcc_unreachable ();
8047             }
8048
8049           real_to_integer2 ((HOST_WIDE_INT *)&val.low, &val.high, &r);
8050           if (double_int_fits_to_tree_p (itype, val))
8051             return double_int_to_tree (itype, val);
8052         }
8053     }
8054
8055   switch (DECL_FUNCTION_CODE (fndecl))
8056     {
8057     CASE_FLT_FN (BUILT_IN_LFLOOR):
8058     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8059       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8060       if (tree_expr_nonnegative_p (arg))
8061         return fold_build1_loc (loc, FIX_TRUNC_EXPR,
8062                             TREE_TYPE (TREE_TYPE (fndecl)), arg);
8063       break;
8064     default:;
8065     }
8066
8067   return fold_fixed_mathfn (loc, fndecl, arg);
8068 }
8069
8070 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8071    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8072    the argument to the call.  Return NULL_TREE if no simplification can
8073    be made.  */
8074
8075 static tree
8076 fold_builtin_bitop (tree fndecl, tree arg)
8077 {
8078   if (!validate_arg (arg, INTEGER_TYPE))
8079     return NULL_TREE;
8080
8081   /* Optimize for constant argument.  */
8082   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8083     {
8084       HOST_WIDE_INT hi, width, result;
8085       unsigned HOST_WIDE_INT lo;
8086       tree type;
8087
8088       type = TREE_TYPE (arg);
8089       width = TYPE_PRECISION (type);
8090       lo = TREE_INT_CST_LOW (arg);
8091
8092       /* Clear all the bits that are beyond the type's precision.  */
8093       if (width > HOST_BITS_PER_WIDE_INT)
8094         {
8095           hi = TREE_INT_CST_HIGH (arg);
8096           if (width < HOST_BITS_PER_DOUBLE_INT)
8097             hi &= ~((unsigned HOST_WIDE_INT) (-1)
8098                     << (width - HOST_BITS_PER_WIDE_INT));
8099         }
8100       else
8101         {
8102           hi = 0;
8103           if (width < HOST_BITS_PER_WIDE_INT)
8104             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8105         }
8106
8107       switch (DECL_FUNCTION_CODE (fndecl))
8108         {
8109         CASE_INT_FN (BUILT_IN_FFS):
8110           if (lo != 0)
8111             result = ffs_hwi (lo);
8112           else if (hi != 0)
8113             result = HOST_BITS_PER_WIDE_INT + ffs_hwi (hi);
8114           else
8115             result = 0;
8116           break;
8117
8118         CASE_INT_FN (BUILT_IN_CLZ):
8119           if (hi != 0)
8120             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8121           else if (lo != 0)
8122             result = width - floor_log2 (lo) - 1;
8123           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8124             result = width;
8125           break;
8126
8127         CASE_INT_FN (BUILT_IN_CTZ):
8128           if (lo != 0)
8129             result = ctz_hwi (lo);
8130           else if (hi != 0)
8131             result = HOST_BITS_PER_WIDE_INT + ctz_hwi (hi);
8132           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8133             result = width;
8134           break;
8135
8136         CASE_INT_FN (BUILT_IN_CLRSB):
8137           if (width > HOST_BITS_PER_WIDE_INT
8138               && (hi & ((unsigned HOST_WIDE_INT) 1
8139                         << (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
8140             {
8141               hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
8142                            << (width - HOST_BITS_PER_WIDE_INT - 1));
8143               lo = ~lo;
8144             }
8145           else if (width <= HOST_BITS_PER_WIDE_INT
8146                    && (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
8147             lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
8148           if (hi != 0)
8149             result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
8150           else if (lo != 0)
8151             result = width - floor_log2 (lo) - 2;
8152           else
8153             result = width - 1;
8154           break;
8155
8156         CASE_INT_FN (BUILT_IN_POPCOUNT):
8157           result = 0;
8158           while (lo)
8159             result++, lo &= lo - 1;
8160           while (hi)
8161             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8162           break;
8163
8164         CASE_INT_FN (BUILT_IN_PARITY):
8165           result = 0;
8166           while (lo)
8167             result++, lo &= lo - 1;
8168           while (hi)
8169             result++, hi &= (unsigned HOST_WIDE_INT) hi - 1;
8170           result &= 1;
8171           break;
8172
8173         default:
8174           gcc_unreachable ();
8175         }
8176
8177       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8178     }
8179
8180   return NULL_TREE;
8181 }
8182
8183 /* Fold function call to builtin_bswap and the short, long and long long
8184    variants.  Return NULL_TREE if no simplification can be made.  */
8185 static tree
8186 fold_builtin_bswap (tree fndecl, tree arg)
8187 {
8188   if (! validate_arg (arg, INTEGER_TYPE))
8189     return NULL_TREE;
8190
8191   /* Optimize constant value.  */
8192   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8193     {
8194       HOST_WIDE_INT hi, width, r_hi = 0;
8195       unsigned HOST_WIDE_INT lo, r_lo = 0;
8196       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8197
8198       width = TYPE_PRECISION (type);
8199       lo = TREE_INT_CST_LOW (arg);
8200       hi = TREE_INT_CST_HIGH (arg);
8201
8202       switch (DECL_FUNCTION_CODE (fndecl))
8203         {
8204           case BUILT_IN_BSWAP16:
8205           case BUILT_IN_BSWAP32:
8206           case BUILT_IN_BSWAP64:
8207             {
8208               int s;
8209
8210               for (s = 0; s < width; s += 8)
8211                 {
8212                   int d = width - s - 8;
8213                   unsigned HOST_WIDE_INT byte;
8214
8215                   if (s < HOST_BITS_PER_WIDE_INT)
8216                     byte = (lo >> s) & 0xff;
8217                   else
8218                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8219
8220                   if (d < HOST_BITS_PER_WIDE_INT)
8221                     r_lo |= byte << d;
8222                   else
8223                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8224                 }
8225             }
8226
8227             break;
8228
8229         default:
8230           gcc_unreachable ();
8231         }
8232
8233       if (width < HOST_BITS_PER_WIDE_INT)
8234         return build_int_cst (type, r_lo);
8235       else
8236         return build_int_cst_wide (type, r_lo, r_hi);
8237     }
8238
8239   return NULL_TREE;
8240 }
8241
8242 /* A subroutine of fold_builtin to fold the various logarithmic
8243    functions.  Return NULL_TREE if no simplification can me made.
8244    FUNC is the corresponding MPFR logarithm function.  */
8245
8246 static tree
8247 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
8248                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8249 {
8250   if (validate_arg (arg, REAL_TYPE))
8251     {
8252       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8253       tree res;
8254       const enum built_in_function fcode = builtin_mathfn_code (arg);
8255
8256       /* Calculate the result when the argument is a constant.  */
8257       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8258         return res;
8259
8260       /* Special case, optimize logN(expN(x)) = x.  */
8261       if (flag_unsafe_math_optimizations
8262           && ((func == mpfr_log
8263                && (fcode == BUILT_IN_EXP
8264                    || fcode == BUILT_IN_EXPF
8265                    || fcode == BUILT_IN_EXPL))
8266               || (func == mpfr_log2
8267                   && (fcode == BUILT_IN_EXP2
8268                       || fcode == BUILT_IN_EXP2F
8269                       || fcode == BUILT_IN_EXP2L))
8270               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8271         return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8272
8273       /* Optimize logN(func()) for various exponential functions.  We
8274          want to determine the value "x" and the power "exponent" in
8275          order to transform logN(x**exponent) into exponent*logN(x).  */
8276       if (flag_unsafe_math_optimizations)
8277         {
8278           tree exponent = 0, x = 0;
8279
8280           switch (fcode)
8281           {
8282           CASE_FLT_FN (BUILT_IN_EXP):
8283             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8284             x = build_real (type, real_value_truncate (TYPE_MODE (type),
8285                                                        dconst_e ()));
8286             exponent = CALL_EXPR_ARG (arg, 0);
8287             break;
8288           CASE_FLT_FN (BUILT_IN_EXP2):
8289             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8290             x = build_real (type, dconst2);
8291             exponent = CALL_EXPR_ARG (arg, 0);
8292             break;
8293           CASE_FLT_FN (BUILT_IN_EXP10):
8294           CASE_FLT_FN (BUILT_IN_POW10):
8295             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8296             {
8297               REAL_VALUE_TYPE dconst10;
8298               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8299               x = build_real (type, dconst10);
8300             }
8301             exponent = CALL_EXPR_ARG (arg, 0);
8302             break;
8303           CASE_FLT_FN (BUILT_IN_SQRT):
8304             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8305             x = CALL_EXPR_ARG (arg, 0);
8306             exponent = build_real (type, dconsthalf);
8307             break;
8308           CASE_FLT_FN (BUILT_IN_CBRT):
8309             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8310             x = CALL_EXPR_ARG (arg, 0);
8311             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8312                                                               dconst_third ()));
8313             break;
8314           CASE_FLT_FN (BUILT_IN_POW):
8315             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8316             x = CALL_EXPR_ARG (arg, 0);
8317             exponent = CALL_EXPR_ARG (arg, 1);
8318             break;
8319           default:
8320             break;
8321           }
8322
8323           /* Now perform the optimization.  */
8324           if (x && exponent)
8325             {
8326               tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8327               return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8328             }
8329         }
8330     }
8331
8332   return NULL_TREE;
8333 }
8334
8335 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8336    NULL_TREE if no simplification can be made.  */
8337
8338 static tree
8339 fold_builtin_hypot (location_t loc, tree fndecl,
8340                     tree arg0, tree arg1, tree type)
8341 {
8342   tree res, narg0, narg1;
8343
8344   if (!validate_arg (arg0, REAL_TYPE)
8345       || !validate_arg (arg1, REAL_TYPE))
8346     return NULL_TREE;
8347
8348   /* Calculate the result when the argument is a constant.  */
8349   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8350     return res;
8351
8352   /* If either argument to hypot has a negate or abs, strip that off.
8353      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8354   narg0 = fold_strip_sign_ops (arg0);
8355   narg1 = fold_strip_sign_ops (arg1);
8356   if (narg0 || narg1)
8357     {
8358       return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0,
8359                               narg1 ? narg1 : arg1);
8360     }
8361
8362   /* If either argument is zero, hypot is fabs of the other.  */
8363   if (real_zerop (arg0))
8364     return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8365   else if (real_zerop (arg1))
8366     return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8367
8368   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8369   if (flag_unsafe_math_optimizations
8370       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8371     {
8372       const REAL_VALUE_TYPE sqrt2_trunc
8373         = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8374       return fold_build2_loc (loc, MULT_EXPR, type,
8375                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
8376                           build_real (type, sqrt2_trunc));
8377     }
8378
8379   return NULL_TREE;
8380 }
8381
8382
8383 /* Fold a builtin function call to pow, powf, or powl.  Return
8384    NULL_TREE if no simplification can be made.  */
8385 static tree
8386 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8387 {
8388   tree res;
8389
8390   if (!validate_arg (arg0, REAL_TYPE)
8391        || !validate_arg (arg1, REAL_TYPE))
8392     return NULL_TREE;
8393
8394   /* Calculate the result when the argument is a constant.  */
8395   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8396     return res;
8397
8398   /* Optimize pow(1.0,y) = 1.0.  */
8399   if (real_onep (arg0))
8400     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8401
8402   if (TREE_CODE (arg1) == REAL_CST
8403       && !TREE_OVERFLOW (arg1))
8404     {
8405       REAL_VALUE_TYPE cint;
8406       REAL_VALUE_TYPE c;
8407       HOST_WIDE_INT n;
8408
8409       c = TREE_REAL_CST (arg1);
8410
8411       /* Optimize pow(x,0.0) = 1.0.  */
8412       if (REAL_VALUES_EQUAL (c, dconst0))
8413         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8414                                  arg0);
8415
8416       /* Optimize pow(x,1.0) = x.  */
8417       if (REAL_VALUES_EQUAL (c, dconst1))
8418         return arg0;
8419
8420       /* Optimize pow(x,-1.0) = 1.0/x.  */
8421       if (REAL_VALUES_EQUAL (c, dconstm1))
8422         return fold_build2_loc (loc, RDIV_EXPR, type,
8423                             build_real (type, dconst1), arg0);
8424
8425       /* Optimize pow(x,0.5) = sqrt(x).  */
8426       if (flag_unsafe_math_optimizations
8427           && REAL_VALUES_EQUAL (c, dconsthalf))
8428         {
8429           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8430
8431           if (sqrtfn != NULL_TREE)
8432             return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8433         }
8434
8435       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8436       if (flag_unsafe_math_optimizations)
8437         {
8438           const REAL_VALUE_TYPE dconstroot
8439             = real_value_truncate (TYPE_MODE (type), dconst_third ());
8440
8441           if (REAL_VALUES_EQUAL (c, dconstroot))
8442             {
8443               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8444               if (cbrtfn != NULL_TREE)
8445                 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8446             }
8447         }
8448
8449       /* Check for an integer exponent.  */
8450       n = real_to_integer (&c);
8451       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8452       if (real_identical (&c, &cint))
8453         {
8454           /* Attempt to evaluate pow at compile-time, unless this should
8455              raise an exception.  */
8456           if (TREE_CODE (arg0) == REAL_CST
8457               && !TREE_OVERFLOW (arg0)
8458               && (n > 0
8459                   || (!flag_trapping_math && !flag_errno_math)
8460                   || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8461             {
8462               REAL_VALUE_TYPE x;
8463               bool inexact;
8464
8465               x = TREE_REAL_CST (arg0);
8466               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8467               if (flag_unsafe_math_optimizations || !inexact)
8468                 return build_real (type, x);
8469             }
8470
8471           /* Strip sign ops from even integer powers.  */
8472           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8473             {
8474               tree narg0 = fold_strip_sign_ops (arg0);
8475               if (narg0)
8476                 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8477             }
8478         }
8479     }
8480
8481   if (flag_unsafe_math_optimizations)
8482     {
8483       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8484
8485       /* Optimize pow(expN(x),y) = expN(x*y).  */
8486       if (BUILTIN_EXPONENT_P (fcode))
8487         {
8488           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8489           tree arg = CALL_EXPR_ARG (arg0, 0);
8490           arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8491           return build_call_expr_loc (loc, expfn, 1, arg);
8492         }
8493
8494       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8495       if (BUILTIN_SQRT_P (fcode))
8496         {
8497           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8498           tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8499                                     build_real (type, dconsthalf));
8500           return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8501         }
8502
8503       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8504       if (BUILTIN_CBRT_P (fcode))
8505         {
8506           tree arg = CALL_EXPR_ARG (arg0, 0);
8507           if (tree_expr_nonnegative_p (arg))
8508             {
8509               const REAL_VALUE_TYPE dconstroot
8510                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8511               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8512                                         build_real (type, dconstroot));
8513               return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8514             }
8515         }
8516
8517       /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative.  */
8518       if (fcode == BUILT_IN_POW
8519           || fcode == BUILT_IN_POWF
8520           || fcode == BUILT_IN_POWL)
8521         {
8522           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8523           if (tree_expr_nonnegative_p (arg00))
8524             {
8525               tree arg01 = CALL_EXPR_ARG (arg0, 1);
8526               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8527               return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8528             }
8529         }
8530     }
8531
8532   return NULL_TREE;
8533 }
8534
8535 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8536    Return NULL_TREE if no simplification can be made.  */
8537 static tree
8538 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8539                    tree arg0, tree arg1, tree type)
8540 {
8541   if (!validate_arg (arg0, REAL_TYPE)
8542       || !validate_arg (arg1, INTEGER_TYPE))
8543     return NULL_TREE;
8544
8545   /* Optimize pow(1.0,y) = 1.0.  */
8546   if (real_onep (arg0))
8547     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8548
8549   if (host_integerp (arg1, 0))
8550     {
8551       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8552
8553       /* Evaluate powi at compile-time.  */
8554       if (TREE_CODE (arg0) == REAL_CST
8555           && !TREE_OVERFLOW (arg0))
8556         {
8557           REAL_VALUE_TYPE x;
8558           x = TREE_REAL_CST (arg0);
8559           real_powi (&x, TYPE_MODE (type), &x, c);
8560           return build_real (type, x);
8561         }
8562
8563       /* Optimize pow(x,0) = 1.0.  */
8564       if (c == 0)
8565         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8566                                  arg0);
8567
8568       /* Optimize pow(x,1) = x.  */
8569       if (c == 1)
8570         return arg0;
8571
8572       /* Optimize pow(x,-1) = 1.0/x.  */
8573       if (c == -1)
8574         return fold_build2_loc (loc, RDIV_EXPR, type,
8575                            build_real (type, dconst1), arg0);
8576     }
8577
8578   return NULL_TREE;
8579 }
8580
8581 /* A subroutine of fold_builtin to fold the various exponent
8582    functions.  Return NULL_TREE if no simplification can be made.
8583    FUNC is the corresponding MPFR exponent function.  */
8584
8585 static tree
8586 fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8587                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8588 {
8589   if (validate_arg (arg, REAL_TYPE))
8590     {
8591       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8592       tree res;
8593
8594       /* Calculate the result when the argument is a constant.  */
8595       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8596         return res;
8597
8598       /* Optimize expN(logN(x)) = x.  */
8599       if (flag_unsafe_math_optimizations)
8600         {
8601           const enum built_in_function fcode = builtin_mathfn_code (arg);
8602
8603           if ((func == mpfr_exp
8604                && (fcode == BUILT_IN_LOG
8605                    || fcode == BUILT_IN_LOGF
8606                    || fcode == BUILT_IN_LOGL))
8607               || (func == mpfr_exp2
8608                   && (fcode == BUILT_IN_LOG2
8609                       || fcode == BUILT_IN_LOG2F
8610                       || fcode == BUILT_IN_LOG2L))
8611               || (func == mpfr_exp10
8612                   && (fcode == BUILT_IN_LOG10
8613                       || fcode == BUILT_IN_LOG10F
8614                       || fcode == BUILT_IN_LOG10L)))
8615             return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8616         }
8617     }
8618
8619   return NULL_TREE;
8620 }
8621
8622 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8623
8624 static bool
8625 var_decl_component_p (tree var)
8626 {
8627   tree inner = var;
8628   while (handled_component_p (inner))
8629     inner = TREE_OPERAND (inner, 0);
8630   return SSA_VAR_P (inner);
8631 }
8632
8633 /* Fold function call to builtin memset.  Return
8634    NULL_TREE if no simplification can be made.  */
8635
8636 static tree
8637 fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8638                      tree type, bool ignore)
8639 {
8640   tree var, ret, etype;
8641   unsigned HOST_WIDE_INT length, cval;
8642
8643   if (! validate_arg (dest, POINTER_TYPE)
8644       || ! validate_arg (c, INTEGER_TYPE)
8645       || ! validate_arg (len, INTEGER_TYPE))
8646     return NULL_TREE;
8647
8648   if (! host_integerp (len, 1))
8649     return NULL_TREE;
8650
8651   /* If the LEN parameter is zero, return DEST.  */
8652   if (integer_zerop (len))
8653     return omit_one_operand_loc (loc, type, dest, c);
8654
8655   if (TREE_CODE (c) != INTEGER_CST || TREE_SIDE_EFFECTS (dest))
8656     return NULL_TREE;
8657
8658   var = dest;
8659   STRIP_NOPS (var);
8660   if (TREE_CODE (var) != ADDR_EXPR)
8661     return NULL_TREE;
8662
8663   var = TREE_OPERAND (var, 0);
8664   if (TREE_THIS_VOLATILE (var))
8665     return NULL_TREE;
8666
8667   etype = TREE_TYPE (var);
8668   if (TREE_CODE (etype) == ARRAY_TYPE)
8669     etype = TREE_TYPE (etype);
8670
8671   if (!INTEGRAL_TYPE_P (etype)
8672       && !POINTER_TYPE_P (etype))
8673     return NULL_TREE;
8674
8675   if (! var_decl_component_p (var))
8676     return NULL_TREE;
8677
8678   length = tree_low_cst (len, 1);
8679   if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8680       || get_pointer_alignment (dest) / BITS_PER_UNIT < length)
8681     return NULL_TREE;
8682
8683   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8684     return NULL_TREE;
8685
8686   if (integer_zerop (c))
8687     cval = 0;
8688   else
8689     {
8690       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8691         return NULL_TREE;
8692
8693       cval = TREE_INT_CST_LOW (c);
8694       cval &= 0xff;
8695       cval |= cval << 8;
8696       cval |= cval << 16;
8697       cval |= (cval << 31) << 1;
8698     }
8699
8700   ret = build_int_cst_type (etype, cval);
8701   var = build_fold_indirect_ref_loc (loc,
8702                                  fold_convert_loc (loc,
8703                                                    build_pointer_type (etype),
8704                                                    dest));
8705   ret = build2 (MODIFY_EXPR, etype, var, ret);
8706   if (ignore)
8707     return ret;
8708
8709   return omit_one_operand_loc (loc, type, dest, ret);
8710 }
8711
8712 /* Fold function call to builtin memset.  Return
8713    NULL_TREE if no simplification can be made.  */
8714
8715 static tree
8716 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8717 {
8718   if (! validate_arg (dest, POINTER_TYPE)
8719       || ! validate_arg (size, INTEGER_TYPE))
8720     return NULL_TREE;
8721
8722   if (!ignore)
8723     return NULL_TREE;
8724
8725   /* New argument list transforming bzero(ptr x, int y) to
8726      memset(ptr x, int 0, size_t y).   This is done this way
8727      so that if it isn't expanded inline, we fallback to
8728      calling bzero instead of memset.  */
8729
8730   return fold_builtin_memset (loc, dest, integer_zero_node,
8731                               fold_convert_loc (loc, size_type_node, size),
8732                               void_type_node, ignore);
8733 }
8734
8735 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8736    NULL_TREE if no simplification can be made.
8737    If ENDP is 0, return DEST (like memcpy).
8738    If ENDP is 1, return DEST+LEN (like mempcpy).
8739    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8740    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8741    (memmove).   */
8742
8743 static tree
8744 fold_builtin_memory_op (location_t loc, tree dest, tree src,
8745                         tree len, tree type, bool ignore, int endp)
8746 {
8747   tree destvar, srcvar, expr;
8748
8749   if (! validate_arg (dest, POINTER_TYPE)
8750       || ! validate_arg (src, POINTER_TYPE)
8751       || ! validate_arg (len, INTEGER_TYPE))
8752     return NULL_TREE;
8753
8754   /* If the LEN parameter is zero, return DEST.  */
8755   if (integer_zerop (len))
8756     return omit_one_operand_loc (loc, type, dest, src);
8757
8758   /* If SRC and DEST are the same (and not volatile), return
8759      DEST{,+LEN,+LEN-1}.  */
8760   if (operand_equal_p (src, dest, 0))
8761     expr = len;
8762   else
8763     {
8764       tree srctype, desttype;
8765       unsigned int src_align, dest_align;
8766       tree off0;
8767
8768       if (endp == 3)
8769         {
8770           src_align = get_pointer_alignment (src);
8771           dest_align = get_pointer_alignment (dest);
8772
8773           /* Both DEST and SRC must be pointer types.
8774              ??? This is what old code did.  Is the testing for pointer types
8775              really mandatory?
8776
8777              If either SRC is readonly or length is 1, we can use memcpy.  */
8778           if (!dest_align || !src_align)
8779             return NULL_TREE;
8780           if (readonly_data_expr (src)
8781               || (host_integerp (len, 1)
8782                   && (MIN (src_align, dest_align) / BITS_PER_UNIT
8783                       >= (unsigned HOST_WIDE_INT) tree_low_cst (len, 1))))
8784             {
8785               tree fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8786               if (!fn)
8787                 return NULL_TREE;
8788               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8789             }
8790
8791           /* If *src and *dest can't overlap, optimize into memcpy as well.  */
8792           if (TREE_CODE (src) == ADDR_EXPR
8793               && TREE_CODE (dest) == ADDR_EXPR)
8794             {
8795               tree src_base, dest_base, fn;
8796               HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8797               HOST_WIDE_INT size = -1;
8798               HOST_WIDE_INT maxsize = -1;
8799
8800               srcvar = TREE_OPERAND (src, 0);
8801               src_base = get_ref_base_and_extent (srcvar, &src_offset,
8802                                                   &size, &maxsize);
8803               destvar = TREE_OPERAND (dest, 0);
8804               dest_base = get_ref_base_and_extent (destvar, &dest_offset,
8805                                                    &size, &maxsize);
8806               if (host_integerp (len, 1))
8807                 maxsize = tree_low_cst (len, 1);
8808               else
8809                 maxsize = -1;
8810               src_offset /= BITS_PER_UNIT;
8811               dest_offset /= BITS_PER_UNIT;
8812               if (SSA_VAR_P (src_base)
8813                   && SSA_VAR_P (dest_base))
8814                 {
8815                   if (operand_equal_p (src_base, dest_base, 0)
8816                       && ranges_overlap_p (src_offset, maxsize,
8817                                            dest_offset, maxsize))
8818                     return NULL_TREE;
8819                 }
8820               else if (TREE_CODE (src_base) == MEM_REF
8821                        && TREE_CODE (dest_base) == MEM_REF)
8822                 {
8823                   double_int off;
8824                   if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8825                                          TREE_OPERAND (dest_base, 0), 0))
8826                     return NULL_TREE;
8827                   off = mem_ref_offset (src_base) +
8828                                         double_int::from_shwi (src_offset);
8829                   if (!off.fits_shwi ())
8830                     return NULL_TREE;
8831                   src_offset = off.low;
8832                   off = mem_ref_offset (dest_base) +
8833                                         double_int::from_shwi (dest_offset);
8834                   if (!off.fits_shwi ())
8835                     return NULL_TREE;
8836                   dest_offset = off.low;
8837                   if (ranges_overlap_p (src_offset, maxsize,
8838                                         dest_offset, maxsize))
8839                     return NULL_TREE;
8840                 }
8841               else
8842                 return NULL_TREE;
8843
8844               fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8845               if (!fn)
8846                 return NULL_TREE;
8847               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8848             }
8849
8850           /* If the destination and source do not alias optimize into
8851              memcpy as well.  */
8852           if ((is_gimple_min_invariant (dest)
8853                || TREE_CODE (dest) == SSA_NAME)
8854               && (is_gimple_min_invariant (src)
8855                   || TREE_CODE (src) == SSA_NAME))
8856             {
8857               ao_ref destr, srcr;
8858               ao_ref_init_from_ptr_and_size (&destr, dest, len);
8859               ao_ref_init_from_ptr_and_size (&srcr, src, len);
8860               if (!refs_may_alias_p_1 (&destr, &srcr, false))
8861                 {
8862                   tree fn;
8863                   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
8864                   if (!fn)
8865                     return NULL_TREE;
8866                   return build_call_expr_loc (loc, fn, 3, dest, src, len);
8867                 }
8868             }
8869
8870           return NULL_TREE;
8871         }
8872
8873       if (!host_integerp (len, 0))
8874         return NULL_TREE;
8875       /* FIXME:
8876          This logic lose for arguments like (type *)malloc (sizeof (type)),
8877          since we strip the casts of up to VOID return value from malloc.
8878          Perhaps we ought to inherit type from non-VOID argument here?  */
8879       STRIP_NOPS (src);
8880       STRIP_NOPS (dest);
8881       if (!POINTER_TYPE_P (TREE_TYPE (src))
8882           || !POINTER_TYPE_P (TREE_TYPE (dest)))
8883         return NULL_TREE;
8884       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
8885       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8886         {
8887           tree tem = TREE_OPERAND (src, 0);
8888           STRIP_NOPS (tem);
8889           if (tem != TREE_OPERAND (src, 0))
8890             src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8891         }
8892       if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8893         {
8894           tree tem = TREE_OPERAND (dest, 0);
8895           STRIP_NOPS (tem);
8896           if (tem != TREE_OPERAND (dest, 0))
8897             dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8898         }
8899       srctype = TREE_TYPE (TREE_TYPE (src));
8900       if (TREE_CODE (srctype) == ARRAY_TYPE
8901           && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8902         {
8903           srctype = TREE_TYPE (srctype);
8904           STRIP_NOPS (src);
8905           src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8906         }
8907       desttype = TREE_TYPE (TREE_TYPE (dest));
8908       if (TREE_CODE (desttype) == ARRAY_TYPE
8909           && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8910         {
8911           desttype = TREE_TYPE (desttype);
8912           STRIP_NOPS (dest);
8913           dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8914         }
8915       if (TREE_ADDRESSABLE (srctype)
8916           || TREE_ADDRESSABLE (desttype))
8917         return NULL_TREE;
8918
8919       src_align = get_pointer_alignment (src);
8920       dest_align = get_pointer_alignment (dest);
8921       if (dest_align < TYPE_ALIGN (desttype)
8922           || src_align < TYPE_ALIGN (srctype))
8923         return NULL_TREE;
8924
8925       if (!ignore)
8926         dest = builtin_save_expr (dest);
8927
8928       /* Build accesses at offset zero with a ref-all character type.  */
8929       off0 = build_int_cst (build_pointer_type_for_mode (char_type_node,
8930                                                          ptr_mode, true), 0);
8931
8932       destvar = dest;
8933       STRIP_NOPS (destvar);
8934       if (TREE_CODE (destvar) == ADDR_EXPR
8935           && var_decl_component_p (TREE_OPERAND (destvar, 0))
8936           && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8937         destvar = fold_build2 (MEM_REF, desttype, destvar, off0);
8938       else
8939         destvar = NULL_TREE;
8940
8941       srcvar = src;
8942       STRIP_NOPS (srcvar);
8943       if (TREE_CODE (srcvar) == ADDR_EXPR
8944           && var_decl_component_p (TREE_OPERAND (srcvar, 0))
8945           && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8946         {
8947           if (!destvar
8948               || src_align >= TYPE_ALIGN (desttype))
8949             srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
8950                                   srcvar, off0);
8951           else if (!STRICT_ALIGNMENT)
8952             {
8953               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8954                                             src_align);
8955               srcvar = fold_build2 (MEM_REF, srctype, srcvar, off0);
8956             }
8957           else
8958             srcvar = NULL_TREE;
8959         }
8960       else
8961         srcvar = NULL_TREE;
8962
8963       if (srcvar == NULL_TREE && destvar == NULL_TREE)
8964         return NULL_TREE;
8965
8966       if (srcvar == NULL_TREE)
8967         {
8968           STRIP_NOPS (src);
8969           if (src_align >= TYPE_ALIGN (desttype))
8970             srcvar = fold_build2 (MEM_REF, desttype, src, off0);
8971           else
8972             {
8973               if (STRICT_ALIGNMENT)
8974                 return NULL_TREE;
8975               srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype),
8976                                             src_align);
8977               srcvar = fold_build2 (MEM_REF, srctype, src, off0);
8978             }
8979         }
8980       else if (destvar == NULL_TREE)
8981         {
8982           STRIP_NOPS (dest);
8983           if (dest_align >= TYPE_ALIGN (srctype))
8984             destvar = fold_build2 (MEM_REF, srctype, dest, off0);
8985           else
8986             {
8987               if (STRICT_ALIGNMENT)
8988                 return NULL_TREE;
8989               desttype = build_aligned_type (TYPE_MAIN_VARIANT (srctype),
8990                                              dest_align);
8991               destvar = fold_build2 (MEM_REF, desttype, dest, off0);
8992             }
8993         }
8994
8995       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, srcvar);
8996     }
8997
8998   if (ignore)
8999     return expr;
9000
9001   if (endp == 0 || endp == 3)
9002     return omit_one_operand_loc (loc, type, dest, expr);
9003
9004   if (expr == len)
9005     expr = NULL_TREE;
9006
9007   if (endp == 2)
9008     len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
9009                        ssize_int (1));
9010
9011   dest = fold_build_pointer_plus_loc (loc, dest, len);
9012   dest = fold_convert_loc (loc, type, dest);
9013   if (expr)
9014     dest = omit_one_operand_loc (loc, type, dest, expr);
9015   return dest;
9016 }
9017
9018 /* Fold function call to builtin strcpy with arguments DEST and SRC.
9019    If LEN is not NULL, it represents the length of the string to be
9020    copied.  Return NULL_TREE if no simplification can be made.  */
9021
9022 tree
9023 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
9024 {
9025   tree fn;
9026
9027   if (!validate_arg (dest, POINTER_TYPE)
9028       || !validate_arg (src, POINTER_TYPE))
9029     return NULL_TREE;
9030
9031   /* If SRC and DEST are the same (and not volatile), return DEST.  */
9032   if (operand_equal_p (src, dest, 0))
9033     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
9034
9035   if (optimize_function_for_size_p (cfun))
9036     return NULL_TREE;
9037
9038   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9039   if (!fn)
9040     return NULL_TREE;
9041
9042   if (!len)
9043     {
9044       len = c_strlen (src, 1);
9045       if (! len || TREE_SIDE_EFFECTS (len))
9046         return NULL_TREE;
9047     }
9048
9049   len = fold_convert_loc (loc, size_type_node, len);
9050   len = size_binop_loc (loc, PLUS_EXPR, len, build_int_cst (size_type_node, 1));
9051   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9052                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9053 }
9054
9055 /* Fold function call to builtin stpcpy with arguments DEST and SRC.
9056    Return NULL_TREE if no simplification can be made.  */
9057
9058 static tree
9059 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
9060 {
9061   tree fn, len, lenp1, call, type;
9062
9063   if (!validate_arg (dest, POINTER_TYPE)
9064       || !validate_arg (src, POINTER_TYPE))
9065     return NULL_TREE;
9066
9067   len = c_strlen (src, 1);
9068   if (!len
9069       || TREE_CODE (len) != INTEGER_CST)
9070     return NULL_TREE;
9071
9072   if (optimize_function_for_size_p (cfun)
9073       /* If length is zero it's small enough.  */
9074       && !integer_zerop (len))
9075     return NULL_TREE;
9076
9077   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9078   if (!fn)
9079     return NULL_TREE;
9080
9081   lenp1 = size_binop_loc (loc, PLUS_EXPR,
9082                           fold_convert_loc (loc, size_type_node, len),
9083                           build_int_cst (size_type_node, 1));
9084   /* We use dest twice in building our expression.  Save it from
9085      multiple expansions.  */
9086   dest = builtin_save_expr (dest);
9087   call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
9088
9089   type = TREE_TYPE (TREE_TYPE (fndecl));
9090   dest = fold_build_pointer_plus_loc (loc, dest, len);
9091   dest = fold_convert_loc (loc, type, dest);
9092   dest = omit_one_operand_loc (loc, type, dest, call);
9093   return dest;
9094 }
9095
9096 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9097    If SLEN is not NULL, it represents the length of the source string.
9098    Return NULL_TREE if no simplification can be made.  */
9099
9100 tree
9101 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
9102                       tree src, tree len, tree slen)
9103 {
9104   tree fn;
9105
9106   if (!validate_arg (dest, POINTER_TYPE)
9107       || !validate_arg (src, POINTER_TYPE)
9108       || !validate_arg (len, INTEGER_TYPE))
9109     return NULL_TREE;
9110
9111   /* If the LEN parameter is zero, return DEST.  */
9112   if (integer_zerop (len))
9113     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9114
9115   /* We can't compare slen with len as constants below if len is not a
9116      constant.  */
9117   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9118     return NULL_TREE;
9119
9120   if (!slen)
9121     slen = c_strlen (src, 1);
9122
9123   /* Now, we must be passed a constant src ptr parameter.  */
9124   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9125     return NULL_TREE;
9126
9127   slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
9128
9129   /* We do not support simplification of this case, though we do
9130      support it when expanding trees into RTL.  */
9131   /* FIXME: generate a call to __builtin_memset.  */
9132   if (tree_int_cst_lt (slen, len))
9133     return NULL_TREE;
9134
9135   /* OK transform into builtin memcpy.  */
9136   fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
9137   if (!fn)
9138     return NULL_TREE;
9139
9140   len = fold_convert_loc (loc, size_type_node, len);
9141   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
9142                            build_call_expr_loc (loc, fn, 3, dest, src, len));
9143 }
9144
9145 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
9146    arguments to the call, and TYPE is its return type.
9147    Return NULL_TREE if no simplification can be made.  */
9148
9149 static tree
9150 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
9151 {
9152   if (!validate_arg (arg1, POINTER_TYPE)
9153       || !validate_arg (arg2, INTEGER_TYPE)
9154       || !validate_arg (len, INTEGER_TYPE))
9155     return NULL_TREE;
9156   else
9157     {
9158       const char *p1;
9159
9160       if (TREE_CODE (arg2) != INTEGER_CST
9161           || !host_integerp (len, 1))
9162         return NULL_TREE;
9163
9164       p1 = c_getstr (arg1);
9165       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9166         {
9167           char c;
9168           const char *r;
9169           tree tem;
9170
9171           if (target_char_cast (arg2, &c))
9172             return NULL_TREE;
9173
9174           r = (const char *) memchr (p1, c, tree_low_cst (len, 1));
9175
9176           if (r == NULL)
9177             return build_int_cst (TREE_TYPE (arg1), 0);
9178
9179           tem = fold_build_pointer_plus_hwi_loc (loc, arg1, r - p1);
9180           return fold_convert_loc (loc, type, tem);
9181         }
9182       return NULL_TREE;
9183     }
9184 }
9185
9186 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9187    Return NULL_TREE if no simplification can be made.  */
9188
9189 static tree
9190 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
9191 {
9192   const char *p1, *p2;
9193
9194   if (!validate_arg (arg1, POINTER_TYPE)
9195       || !validate_arg (arg2, POINTER_TYPE)
9196       || !validate_arg (len, INTEGER_TYPE))
9197     return NULL_TREE;
9198
9199   /* If the LEN parameter is zero, return zero.  */
9200   if (integer_zerop (len))
9201     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9202                               arg1, arg2);
9203
9204   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9205   if (operand_equal_p (arg1, arg2, 0))
9206     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9207
9208   p1 = c_getstr (arg1);
9209   p2 = c_getstr (arg2);
9210
9211   /* If all arguments are constant, and the value of len is not greater
9212      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9213   if (host_integerp (len, 1) && p1 && p2
9214       && compare_tree_int (len, strlen (p1) + 1) <= 0
9215       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9216     {
9217       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9218
9219       if (r > 0)
9220         return integer_one_node;
9221       else if (r < 0)
9222         return integer_minus_one_node;
9223       else
9224         return integer_zero_node;
9225     }
9226
9227   /* If len parameter is one, return an expression corresponding to
9228      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9229   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9230     {
9231       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9232       tree cst_uchar_ptr_node
9233         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9234
9235       tree ind1
9236         = fold_convert_loc (loc, integer_type_node,
9237                             build1 (INDIRECT_REF, cst_uchar_node,
9238                                     fold_convert_loc (loc,
9239                                                       cst_uchar_ptr_node,
9240                                                       arg1)));
9241       tree ind2
9242         = fold_convert_loc (loc, integer_type_node,
9243                             build1 (INDIRECT_REF, cst_uchar_node,
9244                                     fold_convert_loc (loc,
9245                                                       cst_uchar_ptr_node,
9246                                                       arg2)));
9247       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9248     }
9249
9250   return NULL_TREE;
9251 }
9252
9253 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9254    Return NULL_TREE if no simplification can be made.  */
9255
9256 static tree
9257 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
9258 {
9259   const char *p1, *p2;
9260
9261   if (!validate_arg (arg1, POINTER_TYPE)
9262       || !validate_arg (arg2, POINTER_TYPE))
9263     return NULL_TREE;
9264
9265   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9266   if (operand_equal_p (arg1, arg2, 0))
9267     return integer_zero_node;
9268
9269   p1 = c_getstr (arg1);
9270   p2 = c_getstr (arg2);
9271
9272   if (p1 && p2)
9273     {
9274       const int i = strcmp (p1, p2);
9275       if (i < 0)
9276         return integer_minus_one_node;
9277       else if (i > 0)
9278         return integer_one_node;
9279       else
9280         return integer_zero_node;
9281     }
9282
9283   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9284   if (p2 && *p2 == '\0')
9285     {
9286       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9287       tree cst_uchar_ptr_node
9288         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9289
9290       return fold_convert_loc (loc, integer_type_node,
9291                                build1 (INDIRECT_REF, cst_uchar_node,
9292                                        fold_convert_loc (loc,
9293                                                          cst_uchar_ptr_node,
9294                                                          arg1)));
9295     }
9296
9297   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9298   if (p1 && *p1 == '\0')
9299     {
9300       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9301       tree cst_uchar_ptr_node
9302         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9303
9304       tree temp
9305         = fold_convert_loc (loc, integer_type_node,
9306                             build1 (INDIRECT_REF, cst_uchar_node,
9307                                     fold_convert_loc (loc,
9308                                                       cst_uchar_ptr_node,
9309                                                       arg2)));
9310       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9311     }
9312
9313   return NULL_TREE;
9314 }
9315
9316 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9317    Return NULL_TREE if no simplification can be made.  */
9318
9319 static tree
9320 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9321 {
9322   const char *p1, *p2;
9323
9324   if (!validate_arg (arg1, POINTER_TYPE)
9325       || !validate_arg (arg2, POINTER_TYPE)
9326       || !validate_arg (len, INTEGER_TYPE))
9327     return NULL_TREE;
9328
9329   /* If the LEN parameter is zero, return zero.  */
9330   if (integer_zerop (len))
9331     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9332                               arg1, arg2);
9333
9334   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9335   if (operand_equal_p (arg1, arg2, 0))
9336     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9337
9338   p1 = c_getstr (arg1);
9339   p2 = c_getstr (arg2);
9340
9341   if (host_integerp (len, 1) && p1 && p2)
9342     {
9343       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9344       if (i > 0)
9345         return integer_one_node;
9346       else if (i < 0)
9347         return integer_minus_one_node;
9348       else
9349         return integer_zero_node;
9350     }
9351
9352   /* If the second arg is "", and the length is greater than zero,
9353      return *(const unsigned char*)arg1.  */
9354   if (p2 && *p2 == '\0'
9355       && TREE_CODE (len) == INTEGER_CST
9356       && tree_int_cst_sgn (len) == 1)
9357     {
9358       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9359       tree cst_uchar_ptr_node
9360         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9361
9362       return fold_convert_loc (loc, integer_type_node,
9363                                build1 (INDIRECT_REF, cst_uchar_node,
9364                                        fold_convert_loc (loc,
9365                                                          cst_uchar_ptr_node,
9366                                                          arg1)));
9367     }
9368
9369   /* If the first arg is "", and the length is greater than zero,
9370      return -*(const unsigned char*)arg2.  */
9371   if (p1 && *p1 == '\0'
9372       && TREE_CODE (len) == INTEGER_CST
9373       && tree_int_cst_sgn (len) == 1)
9374     {
9375       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9376       tree cst_uchar_ptr_node
9377         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9378
9379       tree temp = fold_convert_loc (loc, integer_type_node,
9380                                     build1 (INDIRECT_REF, cst_uchar_node,
9381                                             fold_convert_loc (loc,
9382                                                               cst_uchar_ptr_node,
9383                                                               arg2)));
9384       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9385     }
9386
9387   /* If len parameter is one, return an expression corresponding to
9388      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9389   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9390     {
9391       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9392       tree cst_uchar_ptr_node
9393         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9394
9395       tree ind1 = fold_convert_loc (loc, integer_type_node,
9396                                     build1 (INDIRECT_REF, cst_uchar_node,
9397                                             fold_convert_loc (loc,
9398                                                               cst_uchar_ptr_node,
9399                                                               arg1)));
9400       tree ind2 = fold_convert_loc (loc, integer_type_node,
9401                                     build1 (INDIRECT_REF, cst_uchar_node,
9402                                             fold_convert_loc (loc,
9403                                                               cst_uchar_ptr_node,
9404                                                               arg2)));
9405       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9406     }
9407
9408   return NULL_TREE;
9409 }
9410
9411 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9412    ARG.  Return NULL_TREE if no simplification can be made.  */
9413
9414 static tree
9415 fold_builtin_signbit (location_t loc, tree arg, tree type)
9416 {
9417   if (!validate_arg (arg, REAL_TYPE))
9418     return NULL_TREE;
9419
9420   /* If ARG is a compile-time constant, determine the result.  */
9421   if (TREE_CODE (arg) == REAL_CST
9422       && !TREE_OVERFLOW (arg))
9423     {
9424       REAL_VALUE_TYPE c;
9425
9426       c = TREE_REAL_CST (arg);
9427       return (REAL_VALUE_NEGATIVE (c)
9428               ? build_one_cst (type)
9429               : build_zero_cst (type));
9430     }
9431
9432   /* If ARG is non-negative, the result is always zero.  */
9433   if (tree_expr_nonnegative_p (arg))
9434     return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9435
9436   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9437   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9438     return fold_convert (type,
9439                          fold_build2_loc (loc, LT_EXPR, boolean_type_node, arg,
9440                         build_real (TREE_TYPE (arg), dconst0)));
9441
9442   return NULL_TREE;
9443 }
9444
9445 /* Fold function call to builtin copysign, copysignf or copysignl with
9446    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9447    be made.  */
9448
9449 static tree
9450 fold_builtin_copysign (location_t loc, tree fndecl,
9451                        tree arg1, tree arg2, tree type)
9452 {
9453   tree tem;
9454
9455   if (!validate_arg (arg1, REAL_TYPE)
9456       || !validate_arg (arg2, REAL_TYPE))
9457     return NULL_TREE;
9458
9459   /* copysign(X,X) is X.  */
9460   if (operand_equal_p (arg1, arg2, 0))
9461     return fold_convert_loc (loc, type, arg1);
9462
9463   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9464   if (TREE_CODE (arg1) == REAL_CST
9465       && TREE_CODE (arg2) == REAL_CST
9466       && !TREE_OVERFLOW (arg1)
9467       && !TREE_OVERFLOW (arg2))
9468     {
9469       REAL_VALUE_TYPE c1, c2;
9470
9471       c1 = TREE_REAL_CST (arg1);
9472       c2 = TREE_REAL_CST (arg2);
9473       /* c1.sign := c2.sign.  */
9474       real_copysign (&c1, &c2);
9475       return build_real (type, c1);
9476     }
9477
9478   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9479      Remember to evaluate Y for side-effects.  */
9480   if (tree_expr_nonnegative_p (arg2))
9481     return omit_one_operand_loc (loc, type,
9482                              fold_build1_loc (loc, ABS_EXPR, type, arg1),
9483                              arg2);
9484
9485   /* Strip sign changing operations for the first argument.  */
9486   tem = fold_strip_sign_ops (arg1);
9487   if (tem)
9488     return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9489
9490   return NULL_TREE;
9491 }
9492
9493 /* Fold a call to builtin isascii with argument ARG.  */
9494
9495 static tree
9496 fold_builtin_isascii (location_t loc, tree arg)
9497 {
9498   if (!validate_arg (arg, INTEGER_TYPE))
9499     return NULL_TREE;
9500   else
9501     {
9502       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9503       arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9504                          build_int_cst (integer_type_node,
9505                                         ~ (unsigned HOST_WIDE_INT) 0x7f));
9506       return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9507                               arg, integer_zero_node);
9508     }
9509 }
9510
9511 /* Fold a call to builtin toascii with argument ARG.  */
9512
9513 static tree
9514 fold_builtin_toascii (location_t loc, tree arg)
9515 {
9516   if (!validate_arg (arg, INTEGER_TYPE))
9517     return NULL_TREE;
9518
9519   /* Transform toascii(c) -> (c & 0x7f).  */
9520   return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9521                           build_int_cst (integer_type_node, 0x7f));
9522 }
9523
9524 /* Fold a call to builtin isdigit with argument ARG.  */
9525
9526 static tree
9527 fold_builtin_isdigit (location_t loc, tree arg)
9528 {
9529   if (!validate_arg (arg, INTEGER_TYPE))
9530     return NULL_TREE;
9531   else
9532     {
9533       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9534       /* According to the C standard, isdigit is unaffected by locale.
9535          However, it definitely is affected by the target character set.  */
9536       unsigned HOST_WIDE_INT target_digit0
9537         = lang_hooks.to_target_charset ('0');
9538
9539       if (target_digit0 == 0)
9540         return NULL_TREE;
9541
9542       arg = fold_convert_loc (loc, unsigned_type_node, arg);
9543       arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9544                          build_int_cst (unsigned_type_node, target_digit0));
9545       return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9546                           build_int_cst (unsigned_type_node, 9));
9547     }
9548 }
9549
9550 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9551
9552 static tree
9553 fold_builtin_fabs (location_t loc, tree arg, tree type)
9554 {
9555   if (!validate_arg (arg, REAL_TYPE))
9556     return NULL_TREE;
9557
9558   arg = fold_convert_loc (loc, type, arg);
9559   if (TREE_CODE (arg) == REAL_CST)
9560     return fold_abs_const (arg, type);
9561   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9562 }
9563
9564 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9565
9566 static tree
9567 fold_builtin_abs (location_t loc, tree arg, tree type)
9568 {
9569   if (!validate_arg (arg, INTEGER_TYPE))
9570     return NULL_TREE;
9571
9572   arg = fold_convert_loc (loc, type, arg);
9573   if (TREE_CODE (arg) == INTEGER_CST)
9574     return fold_abs_const (arg, type);
9575   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9576 }
9577
9578 /* Fold a fma operation with arguments ARG[012].  */
9579
9580 tree
9581 fold_fma (location_t loc ATTRIBUTE_UNUSED,
9582           tree type, tree arg0, tree arg1, tree arg2)
9583 {
9584   if (TREE_CODE (arg0) == REAL_CST
9585       && TREE_CODE (arg1) == REAL_CST
9586       && TREE_CODE (arg2) == REAL_CST)
9587     return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
9588
9589   return NULL_TREE;
9590 }
9591
9592 /* Fold a call to fma, fmaf, or fmal with arguments ARG[012].  */
9593
9594 static tree
9595 fold_builtin_fma (location_t loc, tree arg0, tree arg1, tree arg2, tree type)
9596 {
9597   if (validate_arg (arg0, REAL_TYPE)
9598       && validate_arg(arg1, REAL_TYPE)
9599       && validate_arg(arg2, REAL_TYPE))
9600     {
9601       tree tem = fold_fma (loc, type, arg0, arg1, arg2);
9602       if (tem)
9603         return tem;
9604
9605       /* ??? Only expand to FMA_EXPR if it's directly supported.  */
9606       if (optab_handler (fma_optab, TYPE_MODE (type)) != CODE_FOR_nothing)
9607         return fold_build3_loc (loc, FMA_EXPR, type, arg0, arg1, arg2);
9608     }
9609   return NULL_TREE;
9610 }
9611
9612 /* Fold a call to builtin fmin or fmax.  */
9613
9614 static tree
9615 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9616                         tree type, bool max)
9617 {
9618   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9619     {
9620       /* Calculate the result when the argument is a constant.  */
9621       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9622
9623       if (res)
9624         return res;
9625
9626       /* If either argument is NaN, return the other one.  Avoid the
9627          transformation if we get (and honor) a signalling NaN.  Using
9628          omit_one_operand() ensures we create a non-lvalue.  */
9629       if (TREE_CODE (arg0) == REAL_CST
9630           && real_isnan (&TREE_REAL_CST (arg0))
9631           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9632               || ! TREE_REAL_CST (arg0).signalling))
9633         return omit_one_operand_loc (loc, type, arg1, arg0);
9634       if (TREE_CODE (arg1) == REAL_CST
9635           && real_isnan (&TREE_REAL_CST (arg1))
9636           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9637               || ! TREE_REAL_CST (arg1).signalling))
9638         return omit_one_operand_loc (loc, type, arg0, arg1);
9639
9640       /* Transform fmin/fmax(x,x) -> x.  */
9641       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9642         return omit_one_operand_loc (loc, type, arg0, arg1);
9643
9644       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9645          functions to return the numeric arg if the other one is NaN.
9646          These tree codes don't honor that, so only transform if
9647          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9648          handled, so we don't have to worry about it either.  */
9649       if (flag_finite_math_only)
9650         return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9651                             fold_convert_loc (loc, type, arg0),
9652                             fold_convert_loc (loc, type, arg1));
9653     }
9654   return NULL_TREE;
9655 }
9656
9657 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9658
9659 static tree
9660 fold_builtin_carg (location_t loc, tree arg, tree type)
9661 {
9662   if (validate_arg (arg, COMPLEX_TYPE)
9663       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9664     {
9665       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9666
9667       if (atan2_fn)
9668         {
9669           tree new_arg = builtin_save_expr (arg);
9670           tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9671           tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9672           return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9673         }
9674     }
9675
9676   return NULL_TREE;
9677 }
9678
9679 /* Fold a call to builtin logb/ilogb.  */
9680
9681 static tree
9682 fold_builtin_logb (location_t loc, tree arg, tree rettype)
9683 {
9684   if (! validate_arg (arg, REAL_TYPE))
9685     return NULL_TREE;
9686
9687   STRIP_NOPS (arg);
9688
9689   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9690     {
9691       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9692
9693       switch (value->cl)
9694       {
9695       case rvc_nan:
9696       case rvc_inf:
9697         /* If arg is Inf or NaN and we're logb, return it.  */
9698         if (TREE_CODE (rettype) == REAL_TYPE)
9699           return fold_convert_loc (loc, rettype, arg);
9700         /* Fall through... */
9701       case rvc_zero:
9702         /* Zero may set errno and/or raise an exception for logb, also
9703            for ilogb we don't know FP_ILOGB0.  */
9704         return NULL_TREE;
9705       case rvc_normal:
9706         /* For normal numbers, proceed iff radix == 2.  In GCC,
9707            normalized significands are in the range [0.5, 1.0).  We
9708            want the exponent as if they were [1.0, 2.0) so get the
9709            exponent and subtract 1.  */
9710         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9711           return fold_convert_loc (loc, rettype,
9712                                    build_int_cst (integer_type_node,
9713                                                   REAL_EXP (value)-1));
9714         break;
9715       }
9716     }
9717
9718   return NULL_TREE;
9719 }
9720
9721 /* Fold a call to builtin significand, if radix == 2.  */
9722
9723 static tree
9724 fold_builtin_significand (location_t loc, tree arg, tree rettype)
9725 {
9726   if (! validate_arg (arg, REAL_TYPE))
9727     return NULL_TREE;
9728
9729   STRIP_NOPS (arg);
9730
9731   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9732     {
9733       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9734
9735       switch (value->cl)
9736       {
9737       case rvc_zero:
9738       case rvc_nan:
9739       case rvc_inf:
9740         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9741         return fold_convert_loc (loc, rettype, arg);
9742       case rvc_normal:
9743         /* For normal numbers, proceed iff radix == 2.  */
9744         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9745           {
9746             REAL_VALUE_TYPE result = *value;
9747             /* In GCC, normalized significands are in the range [0.5,
9748                1.0).  We want them to be [1.0, 2.0) so set the
9749                exponent to 1.  */
9750             SET_REAL_EXP (&result, 1);
9751             return build_real (rettype, result);
9752           }
9753         break;
9754       }
9755     }
9756
9757   return NULL_TREE;
9758 }
9759
9760 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9761
9762 static tree
9763 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9764 {
9765   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9766     return NULL_TREE;
9767
9768   STRIP_NOPS (arg0);
9769
9770   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9771     return NULL_TREE;
9772
9773   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9774
9775   /* Proceed if a valid pointer type was passed in.  */
9776   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9777     {
9778       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9779       tree frac, exp;
9780
9781       switch (value->cl)
9782       {
9783       case rvc_zero:
9784         /* For +-0, return (*exp = 0, +-0).  */
9785         exp = integer_zero_node;
9786         frac = arg0;
9787         break;
9788       case rvc_nan:
9789       case rvc_inf:
9790         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9791         return omit_one_operand_loc (loc, rettype, arg0, arg1);
9792       case rvc_normal:
9793         {
9794           /* Since the frexp function always expects base 2, and in
9795              GCC normalized significands are already in the range
9796              [0.5, 1.0), we have exactly what frexp wants.  */
9797           REAL_VALUE_TYPE frac_rvt = *value;
9798           SET_REAL_EXP (&frac_rvt, 0);
9799           frac = build_real (rettype, frac_rvt);
9800           exp = build_int_cst (integer_type_node, REAL_EXP (value));
9801         }
9802         break;
9803       default:
9804         gcc_unreachable ();
9805       }
9806
9807       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9808       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9809       TREE_SIDE_EFFECTS (arg1) = 1;
9810       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9811     }
9812
9813   return NULL_TREE;
9814 }
9815
9816 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9817    then we can assume the base is two.  If it's false, then we have to
9818    check the mode of the TYPE parameter in certain cases.  */
9819
9820 static tree
9821 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9822                             tree type, bool ldexp)
9823 {
9824   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9825     {
9826       STRIP_NOPS (arg0);
9827       STRIP_NOPS (arg1);
9828
9829       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9830       if (real_zerop (arg0) || integer_zerop (arg1)
9831           || (TREE_CODE (arg0) == REAL_CST
9832               && !real_isfinite (&TREE_REAL_CST (arg0))))
9833         return omit_one_operand_loc (loc, type, arg0, arg1);
9834
9835       /* If both arguments are constant, then try to evaluate it.  */
9836       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9837           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9838           && host_integerp (arg1, 0))
9839         {
9840           /* Bound the maximum adjustment to twice the range of the
9841              mode's valid exponents.  Use abs to ensure the range is
9842              positive as a sanity check.  */
9843           const long max_exp_adj = 2 *
9844             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9845                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9846
9847           /* Get the user-requested adjustment.  */
9848           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9849
9850           /* The requested adjustment must be inside this range.  This
9851              is a preliminary cap to avoid things like overflow, we
9852              may still fail to compute the result for other reasons.  */
9853           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9854             {
9855               REAL_VALUE_TYPE initial_result;
9856
9857               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9858
9859               /* Ensure we didn't overflow.  */
9860               if (! real_isinf (&initial_result))
9861                 {
9862                   const REAL_VALUE_TYPE trunc_result
9863                     = real_value_truncate (TYPE_MODE (type), initial_result);
9864
9865                   /* Only proceed if the target mode can hold the
9866                      resulting value.  */
9867                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9868                     return build_real (type, trunc_result);
9869                 }
9870             }
9871         }
9872     }
9873
9874   return NULL_TREE;
9875 }
9876
9877 /* Fold a call to builtin modf.  */
9878
9879 static tree
9880 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9881 {
9882   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9883     return NULL_TREE;
9884
9885   STRIP_NOPS (arg0);
9886
9887   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9888     return NULL_TREE;
9889
9890   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9891
9892   /* Proceed if a valid pointer type was passed in.  */
9893   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9894     {
9895       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9896       REAL_VALUE_TYPE trunc, frac;
9897
9898       switch (value->cl)
9899       {
9900       case rvc_nan:
9901       case rvc_zero:
9902         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9903         trunc = frac = *value;
9904         break;
9905       case rvc_inf:
9906         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9907         frac = dconst0;
9908         frac.sign = value->sign;
9909         trunc = *value;
9910         break;
9911       case rvc_normal:
9912         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9913         real_trunc (&trunc, VOIDmode, value);
9914         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9915         /* If the original number was negative and already
9916            integral, then the fractional part is -0.0.  */
9917         if (value->sign && frac.cl == rvc_zero)
9918           frac.sign = value->sign;
9919         break;
9920       }
9921
9922       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9923       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9924                           build_real (rettype, trunc));
9925       TREE_SIDE_EFFECTS (arg1) = 1;
9926       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9927                           build_real (rettype, frac));
9928     }
9929
9930   return NULL_TREE;
9931 }
9932
9933 /* Given a location LOC, an interclass builtin function decl FNDECL
9934    and its single argument ARG, return an folded expression computing
9935    the same, or NULL_TREE if we either couldn't or didn't want to fold
9936    (the latter happen if there's an RTL instruction available).  */
9937
9938 static tree
9939 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9940 {
9941   enum machine_mode mode;
9942
9943   if (!validate_arg (arg, REAL_TYPE))
9944     return NULL_TREE;
9945
9946   if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9947     return NULL_TREE;
9948
9949   mode = TYPE_MODE (TREE_TYPE (arg));
9950
9951   /* If there is no optab, try generic code.  */
9952   switch (DECL_FUNCTION_CODE (fndecl))
9953     {
9954       tree result;
9955
9956     CASE_FLT_FN (BUILT_IN_ISINF):
9957       {
9958         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
9959         tree const isgr_fn = builtin_decl_explicit (BUILT_IN_ISGREATER);
9960         tree const type = TREE_TYPE (arg);
9961         REAL_VALUE_TYPE r;
9962         char buf[128];
9963
9964         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9965         real_from_string (&r, buf);
9966         result = build_call_expr (isgr_fn, 2,
9967                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9968                                   build_real (type, r));
9969         return result;
9970       }
9971     CASE_FLT_FN (BUILT_IN_FINITE):
9972     case BUILT_IN_ISFINITE:
9973       {
9974         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
9975         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9976         tree const type = TREE_TYPE (arg);
9977         REAL_VALUE_TYPE r;
9978         char buf[128];
9979
9980         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9981         real_from_string (&r, buf);
9982         result = build_call_expr (isle_fn, 2,
9983                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9984                                   build_real (type, r));
9985         /*result = fold_build2_loc (loc, UNGT_EXPR,
9986                                   TREE_TYPE (TREE_TYPE (fndecl)),
9987                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9988                                   build_real (type, r));
9989         result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9990                                   TREE_TYPE (TREE_TYPE (fndecl)),
9991                                   result);*/
9992         return result;
9993       }
9994     case BUILT_IN_ISNORMAL:
9995       {
9996         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9997            islessequal(fabs(x),DBL_MAX).  */
9998         tree const isle_fn = builtin_decl_explicit (BUILT_IN_ISLESSEQUAL);
9999         tree const isge_fn = builtin_decl_explicit (BUILT_IN_ISGREATEREQUAL);
10000         tree const type = TREE_TYPE (arg);
10001         REAL_VALUE_TYPE rmax, rmin;
10002         char buf[128];
10003
10004         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
10005         real_from_string (&rmax, buf);
10006         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10007         real_from_string (&rmin, buf);
10008         arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10009         result = build_call_expr (isle_fn, 2, arg,
10010                                   build_real (type, rmax));
10011         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
10012                               build_call_expr (isge_fn, 2, arg,
10013                                                build_real (type, rmin)));
10014         return result;
10015       }
10016     default:
10017       break;
10018     }
10019
10020   return NULL_TREE;
10021 }
10022
10023 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
10024    ARG is the argument for the call.  */
10025
10026 static tree
10027 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
10028 {
10029   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10030   REAL_VALUE_TYPE r;
10031
10032   if (!validate_arg (arg, REAL_TYPE))
10033     return NULL_TREE;
10034
10035   switch (builtin_index)
10036     {
10037     case BUILT_IN_ISINF:
10038       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10039         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10040
10041       if (TREE_CODE (arg) == REAL_CST)
10042         {
10043           r = TREE_REAL_CST (arg);
10044           if (real_isinf (&r))
10045             return real_compare (GT_EXPR, &r, &dconst0)
10046                    ? integer_one_node : integer_minus_one_node;
10047           else
10048             return integer_zero_node;
10049         }
10050
10051       return NULL_TREE;
10052
10053     case BUILT_IN_ISINF_SIGN:
10054       {
10055         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
10056         /* In a boolean context, GCC will fold the inner COND_EXPR to
10057            1.  So e.g. "if (isinf_sign(x))" would be folded to just
10058            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
10059         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
10060         tree isinf_fn = builtin_decl_explicit (BUILT_IN_ISINF);
10061         tree tmp = NULL_TREE;
10062
10063         arg = builtin_save_expr (arg);
10064
10065         if (signbit_fn && isinf_fn)
10066           {
10067             tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
10068             tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
10069
10070             signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10071                                         signbit_call, integer_zero_node);
10072             isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
10073                                       isinf_call, integer_zero_node);
10074
10075             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
10076                                integer_minus_one_node, integer_one_node);
10077             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10078                                isinf_call, tmp,
10079                                integer_zero_node);
10080           }
10081
10082         return tmp;
10083       }
10084
10085     case BUILT_IN_ISFINITE:
10086       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
10087           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
10088         return omit_one_operand_loc (loc, type, integer_one_node, arg);
10089
10090       if (TREE_CODE (arg) == REAL_CST)
10091         {
10092           r = TREE_REAL_CST (arg);
10093           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
10094         }
10095
10096       return NULL_TREE;
10097
10098     case BUILT_IN_ISNAN:
10099       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
10100         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
10101
10102       if (TREE_CODE (arg) == REAL_CST)
10103         {
10104           r = TREE_REAL_CST (arg);
10105           return real_isnan (&r) ? integer_one_node : integer_zero_node;
10106         }
10107
10108       arg = builtin_save_expr (arg);
10109       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
10110
10111     default:
10112       gcc_unreachable ();
10113     }
10114 }
10115
10116 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
10117    This builtin will generate code to return the appropriate floating
10118    point classification depending on the value of the floating point
10119    number passed in.  The possible return values must be supplied as
10120    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
10121    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
10122    one floating point argument which is "type generic".  */
10123
10124 static tree
10125 fold_builtin_fpclassify (location_t loc, tree exp)
10126 {
10127   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
10128     arg, type, res, tmp;
10129   enum machine_mode mode;
10130   REAL_VALUE_TYPE r;
10131   char buf[128];
10132
10133   /* Verify the required arguments in the original call.  */
10134   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
10135                          INTEGER_TYPE, INTEGER_TYPE,
10136                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
10137     return NULL_TREE;
10138
10139   fp_nan = CALL_EXPR_ARG (exp, 0);
10140   fp_infinite = CALL_EXPR_ARG (exp, 1);
10141   fp_normal = CALL_EXPR_ARG (exp, 2);
10142   fp_subnormal = CALL_EXPR_ARG (exp, 3);
10143   fp_zero = CALL_EXPR_ARG (exp, 4);
10144   arg = CALL_EXPR_ARG (exp, 5);
10145   type = TREE_TYPE (arg);
10146   mode = TYPE_MODE (type);
10147   arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
10148
10149   /* fpclassify(x) ->
10150        isnan(x) ? FP_NAN :
10151          (fabs(x) == Inf ? FP_INFINITE :
10152            (fabs(x) >= DBL_MIN ? FP_NORMAL :
10153              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
10154
10155   tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10156                      build_real (type, dconst0));
10157   res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
10158                      tmp, fp_zero, fp_subnormal);
10159
10160   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
10161   real_from_string (&r, buf);
10162   tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
10163                      arg, build_real (type, r));
10164   res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
10165
10166   if (HONOR_INFINITIES (mode))
10167     {
10168       real_inf (&r);
10169       tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
10170                          build_real (type, r));
10171       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
10172                          fp_infinite, res);
10173     }
10174
10175   if (HONOR_NANS (mode))
10176     {
10177       tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
10178       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
10179     }
10180
10181   return res;
10182 }
10183
10184 /* Fold a call to an unordered comparison function such as
10185    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
10186    being called and ARG0 and ARG1 are the arguments for the call.
10187    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10188    the opposite of the desired result.  UNORDERED_CODE is used
10189    for modes that can hold NaNs and ORDERED_CODE is used for
10190    the rest.  */
10191
10192 static tree
10193 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
10194                             enum tree_code unordered_code,
10195                             enum tree_code ordered_code)
10196 {
10197   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10198   enum tree_code code;
10199   tree type0, type1;
10200   enum tree_code code0, code1;
10201   tree cmp_type = NULL_TREE;
10202
10203   type0 = TREE_TYPE (arg0);
10204   type1 = TREE_TYPE (arg1);
10205
10206   code0 = TREE_CODE (type0);
10207   code1 = TREE_CODE (type1);
10208
10209   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10210     /* Choose the wider of two real types.  */
10211     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10212       ? type0 : type1;
10213   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10214     cmp_type = type0;
10215   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10216     cmp_type = type1;
10217
10218   arg0 = fold_convert_loc (loc, cmp_type, arg0);
10219   arg1 = fold_convert_loc (loc, cmp_type, arg1);
10220
10221   if (unordered_code == UNORDERED_EXPR)
10222     {
10223       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10224         return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
10225       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
10226     }
10227
10228   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10229                                                    : ordered_code;
10230   return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
10231                       fold_build2_loc (loc, code, type, arg0, arg1));
10232 }
10233
10234 /* Fold a call to built-in function FNDECL with 0 arguments.
10235    IGNORE is true if the result of the function call is ignored.  This
10236    function returns NULL_TREE if no simplification was possible.  */
10237
10238 static tree
10239 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10240 {
10241   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10242   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10243   switch (fcode)
10244     {
10245     CASE_FLT_FN (BUILT_IN_INF):
10246     case BUILT_IN_INFD32:
10247     case BUILT_IN_INFD64:
10248     case BUILT_IN_INFD128:
10249       return fold_builtin_inf (loc, type, true);
10250
10251     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10252       return fold_builtin_inf (loc, type, false);
10253
10254     case BUILT_IN_CLASSIFY_TYPE:
10255       return fold_builtin_classify_type (NULL_TREE);
10256
10257     default:
10258       break;
10259     }
10260   return NULL_TREE;
10261 }
10262
10263 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10264    IGNORE is true if the result of the function call is ignored.  This
10265    function returns NULL_TREE if no simplification was possible.  */
10266
10267 static tree
10268 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
10269 {
10270   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10271   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10272   switch (fcode)
10273     {
10274     case BUILT_IN_CONSTANT_P:
10275       {
10276         tree val = fold_builtin_constant_p (arg0);
10277
10278         /* Gimplification will pull the CALL_EXPR for the builtin out of
10279            an if condition.  When not optimizing, we'll not CSE it back.
10280            To avoid link error types of regressions, return false now.  */
10281         if (!val && !optimize)
10282           val = integer_zero_node;
10283
10284         return val;
10285       }
10286
10287     case BUILT_IN_CLASSIFY_TYPE:
10288       return fold_builtin_classify_type (arg0);
10289
10290     case BUILT_IN_STRLEN:
10291       return fold_builtin_strlen (loc, type, arg0);
10292
10293     CASE_FLT_FN (BUILT_IN_FABS):
10294       return fold_builtin_fabs (loc, arg0, type);
10295
10296     case BUILT_IN_ABS:
10297     case BUILT_IN_LABS:
10298     case BUILT_IN_LLABS:
10299     case BUILT_IN_IMAXABS:
10300       return fold_builtin_abs (loc, arg0, type);
10301
10302     CASE_FLT_FN (BUILT_IN_CONJ):
10303       if (validate_arg (arg0, COMPLEX_TYPE)
10304         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10305         return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
10306     break;
10307
10308     CASE_FLT_FN (BUILT_IN_CREAL):
10309       if (validate_arg (arg0, COMPLEX_TYPE)
10310         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10311         return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10312     break;
10313
10314     CASE_FLT_FN (BUILT_IN_CIMAG):
10315       if (validate_arg (arg0, COMPLEX_TYPE)
10316           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10317         return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10318     break;
10319
10320     CASE_FLT_FN (BUILT_IN_CCOS):
10321       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10322
10323     CASE_FLT_FN (BUILT_IN_CCOSH):
10324       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10325
10326     CASE_FLT_FN (BUILT_IN_CPROJ):
10327       return fold_builtin_cproj(loc, arg0, type);
10328
10329     CASE_FLT_FN (BUILT_IN_CSIN):
10330       if (validate_arg (arg0, COMPLEX_TYPE)
10331           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10332         return do_mpc_arg1 (arg0, type, mpc_sin);
10333     break;
10334
10335     CASE_FLT_FN (BUILT_IN_CSINH):
10336       if (validate_arg (arg0, COMPLEX_TYPE)
10337           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10338         return do_mpc_arg1 (arg0, type, mpc_sinh);
10339     break;
10340
10341     CASE_FLT_FN (BUILT_IN_CTAN):
10342       if (validate_arg (arg0, COMPLEX_TYPE)
10343           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10344         return do_mpc_arg1 (arg0, type, mpc_tan);
10345     break;
10346
10347     CASE_FLT_FN (BUILT_IN_CTANH):
10348       if (validate_arg (arg0, COMPLEX_TYPE)
10349           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10350         return do_mpc_arg1 (arg0, type, mpc_tanh);
10351     break;
10352
10353     CASE_FLT_FN (BUILT_IN_CLOG):
10354       if (validate_arg (arg0, COMPLEX_TYPE)
10355           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10356         return do_mpc_arg1 (arg0, type, mpc_log);
10357     break;
10358
10359     CASE_FLT_FN (BUILT_IN_CSQRT):
10360       if (validate_arg (arg0, COMPLEX_TYPE)
10361           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10362         return do_mpc_arg1 (arg0, type, mpc_sqrt);
10363     break;
10364
10365     CASE_FLT_FN (BUILT_IN_CASIN):
10366       if (validate_arg (arg0, COMPLEX_TYPE)
10367           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10368         return do_mpc_arg1 (arg0, type, mpc_asin);
10369     break;
10370
10371     CASE_FLT_FN (BUILT_IN_CACOS):
10372       if (validate_arg (arg0, COMPLEX_TYPE)
10373           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10374         return do_mpc_arg1 (arg0, type, mpc_acos);
10375     break;
10376
10377     CASE_FLT_FN (BUILT_IN_CATAN):
10378       if (validate_arg (arg0, COMPLEX_TYPE)
10379           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10380         return do_mpc_arg1 (arg0, type, mpc_atan);
10381     break;
10382
10383     CASE_FLT_FN (BUILT_IN_CASINH):
10384       if (validate_arg (arg0, COMPLEX_TYPE)
10385           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10386         return do_mpc_arg1 (arg0, type, mpc_asinh);
10387     break;
10388
10389     CASE_FLT_FN (BUILT_IN_CACOSH):
10390       if (validate_arg (arg0, COMPLEX_TYPE)
10391           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10392         return do_mpc_arg1 (arg0, type, mpc_acosh);
10393     break;
10394
10395     CASE_FLT_FN (BUILT_IN_CATANH):
10396       if (validate_arg (arg0, COMPLEX_TYPE)
10397           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10398         return do_mpc_arg1 (arg0, type, mpc_atanh);
10399     break;
10400
10401     CASE_FLT_FN (BUILT_IN_CABS):
10402       return fold_builtin_cabs (loc, arg0, type, fndecl);
10403
10404     CASE_FLT_FN (BUILT_IN_CARG):
10405       return fold_builtin_carg (loc, arg0, type);
10406
10407     CASE_FLT_FN (BUILT_IN_SQRT):
10408       return fold_builtin_sqrt (loc, arg0, type);
10409
10410     CASE_FLT_FN (BUILT_IN_CBRT):
10411       return fold_builtin_cbrt (loc, arg0, type);
10412
10413     CASE_FLT_FN (BUILT_IN_ASIN):
10414       if (validate_arg (arg0, REAL_TYPE))
10415         return do_mpfr_arg1 (arg0, type, mpfr_asin,
10416                              &dconstm1, &dconst1, true);
10417     break;
10418
10419     CASE_FLT_FN (BUILT_IN_ACOS):
10420       if (validate_arg (arg0, REAL_TYPE))
10421         return do_mpfr_arg1 (arg0, type, mpfr_acos,
10422                              &dconstm1, &dconst1, true);
10423     break;
10424
10425     CASE_FLT_FN (BUILT_IN_ATAN):
10426       if (validate_arg (arg0, REAL_TYPE))
10427         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10428     break;
10429
10430     CASE_FLT_FN (BUILT_IN_ASINH):
10431       if (validate_arg (arg0, REAL_TYPE))
10432         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10433     break;
10434
10435     CASE_FLT_FN (BUILT_IN_ACOSH):
10436       if (validate_arg (arg0, REAL_TYPE))
10437         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10438                              &dconst1, NULL, true);
10439     break;
10440
10441     CASE_FLT_FN (BUILT_IN_ATANH):
10442       if (validate_arg (arg0, REAL_TYPE))
10443         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10444                              &dconstm1, &dconst1, false);
10445     break;
10446
10447     CASE_FLT_FN (BUILT_IN_SIN):
10448       if (validate_arg (arg0, REAL_TYPE))
10449         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10450     break;
10451
10452     CASE_FLT_FN (BUILT_IN_COS):
10453       return fold_builtin_cos (loc, arg0, type, fndecl);
10454
10455     CASE_FLT_FN (BUILT_IN_TAN):
10456       return fold_builtin_tan (arg0, type);
10457
10458     CASE_FLT_FN (BUILT_IN_CEXP):
10459       return fold_builtin_cexp (loc, arg0, type);
10460
10461     CASE_FLT_FN (BUILT_IN_CEXPI):
10462       if (validate_arg (arg0, REAL_TYPE))
10463         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10464     break;
10465
10466     CASE_FLT_FN (BUILT_IN_SINH):
10467       if (validate_arg (arg0, REAL_TYPE))
10468         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10469     break;
10470
10471     CASE_FLT_FN (BUILT_IN_COSH):
10472       return fold_builtin_cosh (loc, arg0, type, fndecl);
10473
10474     CASE_FLT_FN (BUILT_IN_TANH):
10475       if (validate_arg (arg0, REAL_TYPE))
10476         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10477     break;
10478
10479     CASE_FLT_FN (BUILT_IN_ERF):
10480       if (validate_arg (arg0, REAL_TYPE))
10481         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10482     break;
10483
10484     CASE_FLT_FN (BUILT_IN_ERFC):
10485       if (validate_arg (arg0, REAL_TYPE))
10486         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10487     break;
10488
10489     CASE_FLT_FN (BUILT_IN_TGAMMA):
10490       if (validate_arg (arg0, REAL_TYPE))
10491         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10492     break;
10493
10494     CASE_FLT_FN (BUILT_IN_EXP):
10495       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10496
10497     CASE_FLT_FN (BUILT_IN_EXP2):
10498       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10499
10500     CASE_FLT_FN (BUILT_IN_EXP10):
10501     CASE_FLT_FN (BUILT_IN_POW10):
10502       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10503
10504     CASE_FLT_FN (BUILT_IN_EXPM1):
10505       if (validate_arg (arg0, REAL_TYPE))
10506         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10507     break;
10508
10509     CASE_FLT_FN (BUILT_IN_LOG):
10510     return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10511
10512     CASE_FLT_FN (BUILT_IN_LOG2):
10513       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10514
10515     CASE_FLT_FN (BUILT_IN_LOG10):
10516       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10517
10518     CASE_FLT_FN (BUILT_IN_LOG1P):
10519       if (validate_arg (arg0, REAL_TYPE))
10520         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10521                              &dconstm1, NULL, false);
10522     break;
10523
10524     CASE_FLT_FN (BUILT_IN_J0):
10525       if (validate_arg (arg0, REAL_TYPE))
10526         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10527                              NULL, NULL, 0);
10528     break;
10529
10530     CASE_FLT_FN (BUILT_IN_J1):
10531       if (validate_arg (arg0, REAL_TYPE))
10532         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10533                              NULL, NULL, 0);
10534     break;
10535
10536     CASE_FLT_FN (BUILT_IN_Y0):
10537       if (validate_arg (arg0, REAL_TYPE))
10538         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10539                              &dconst0, NULL, false);
10540     break;
10541
10542     CASE_FLT_FN (BUILT_IN_Y1):
10543       if (validate_arg (arg0, REAL_TYPE))
10544         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10545                              &dconst0, NULL, false);
10546     break;
10547
10548     CASE_FLT_FN (BUILT_IN_NAN):
10549     case BUILT_IN_NAND32:
10550     case BUILT_IN_NAND64:
10551     case BUILT_IN_NAND128:
10552       return fold_builtin_nan (arg0, type, true);
10553
10554     CASE_FLT_FN (BUILT_IN_NANS):
10555       return fold_builtin_nan (arg0, type, false);
10556
10557     CASE_FLT_FN (BUILT_IN_FLOOR):
10558       return fold_builtin_floor (loc, fndecl, arg0);
10559
10560     CASE_FLT_FN (BUILT_IN_CEIL):
10561       return fold_builtin_ceil (loc, fndecl, arg0);
10562
10563     CASE_FLT_FN (BUILT_IN_TRUNC):
10564       return fold_builtin_trunc (loc, fndecl, arg0);
10565
10566     CASE_FLT_FN (BUILT_IN_ROUND):
10567       return fold_builtin_round (loc, fndecl, arg0);
10568
10569     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10570     CASE_FLT_FN (BUILT_IN_RINT):
10571       return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10572
10573     CASE_FLT_FN (BUILT_IN_ICEIL):
10574     CASE_FLT_FN (BUILT_IN_LCEIL):
10575     CASE_FLT_FN (BUILT_IN_LLCEIL):
10576     CASE_FLT_FN (BUILT_IN_LFLOOR):
10577     CASE_FLT_FN (BUILT_IN_IFLOOR):
10578     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10579     CASE_FLT_FN (BUILT_IN_IROUND):
10580     CASE_FLT_FN (BUILT_IN_LROUND):
10581     CASE_FLT_FN (BUILT_IN_LLROUND):
10582       return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10583
10584     CASE_FLT_FN (BUILT_IN_IRINT):
10585     CASE_FLT_FN (BUILT_IN_LRINT):
10586     CASE_FLT_FN (BUILT_IN_LLRINT):
10587       return fold_fixed_mathfn (loc, fndecl, arg0);
10588
10589     case BUILT_IN_BSWAP16:
10590     case BUILT_IN_BSWAP32:
10591     case BUILT_IN_BSWAP64:
10592       return fold_builtin_bswap (fndecl, arg0);
10593
10594     CASE_INT_FN (BUILT_IN_FFS):
10595     CASE_INT_FN (BUILT_IN_CLZ):
10596     CASE_INT_FN (BUILT_IN_CTZ):
10597     CASE_INT_FN (BUILT_IN_CLRSB):
10598     CASE_INT_FN (BUILT_IN_POPCOUNT):
10599     CASE_INT_FN (BUILT_IN_PARITY):
10600       return fold_builtin_bitop (fndecl, arg0);
10601
10602     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10603       return fold_builtin_signbit (loc, arg0, type);
10604
10605     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10606       return fold_builtin_significand (loc, arg0, type);
10607
10608     CASE_FLT_FN (BUILT_IN_ILOGB):
10609     CASE_FLT_FN (BUILT_IN_LOGB):
10610       return fold_builtin_logb (loc, arg0, type);
10611
10612     case BUILT_IN_ISASCII:
10613       return fold_builtin_isascii (loc, arg0);
10614
10615     case BUILT_IN_TOASCII:
10616       return fold_builtin_toascii (loc, arg0);
10617
10618     case BUILT_IN_ISDIGIT:
10619       return fold_builtin_isdigit (loc, arg0);
10620
10621     CASE_FLT_FN (BUILT_IN_FINITE):
10622     case BUILT_IN_FINITED32:
10623     case BUILT_IN_FINITED64:
10624     case BUILT_IN_FINITED128:
10625     case BUILT_IN_ISFINITE:
10626       {
10627         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10628         if (ret)
10629           return ret;
10630         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10631       }
10632
10633     CASE_FLT_FN (BUILT_IN_ISINF):
10634     case BUILT_IN_ISINFD32:
10635     case BUILT_IN_ISINFD64:
10636     case BUILT_IN_ISINFD128:
10637       {
10638         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10639         if (ret)
10640           return ret;
10641         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10642       }
10643
10644     case BUILT_IN_ISNORMAL:
10645       return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10646
10647     case BUILT_IN_ISINF_SIGN:
10648       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10649
10650     CASE_FLT_FN (BUILT_IN_ISNAN):
10651     case BUILT_IN_ISNAND32:
10652     case BUILT_IN_ISNAND64:
10653     case BUILT_IN_ISNAND128:
10654       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10655
10656     case BUILT_IN_PRINTF:
10657     case BUILT_IN_PRINTF_UNLOCKED:
10658     case BUILT_IN_VPRINTF:
10659       return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10660
10661     case BUILT_IN_FREE:
10662       if (integer_zerop (arg0))
10663         return build_empty_stmt (loc);
10664       break;
10665
10666     default:
10667       break;
10668     }
10669
10670   return NULL_TREE;
10671
10672 }
10673
10674 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10675    IGNORE is true if the result of the function call is ignored.  This
10676    function returns NULL_TREE if no simplification was possible.  */
10677
10678 static tree
10679 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10680 {
10681   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10682   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10683
10684   switch (fcode)
10685     {
10686     CASE_FLT_FN (BUILT_IN_JN):
10687       if (validate_arg (arg0, INTEGER_TYPE)
10688           && validate_arg (arg1, REAL_TYPE))
10689         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10690     break;
10691
10692     CASE_FLT_FN (BUILT_IN_YN):
10693       if (validate_arg (arg0, INTEGER_TYPE)
10694           && validate_arg (arg1, REAL_TYPE))
10695         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10696                                  &dconst0, false);
10697     break;
10698
10699     CASE_FLT_FN (BUILT_IN_DREM):
10700     CASE_FLT_FN (BUILT_IN_REMAINDER):
10701       if (validate_arg (arg0, REAL_TYPE)
10702           && validate_arg(arg1, REAL_TYPE))
10703         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10704     break;
10705
10706     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10707     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10708       if (validate_arg (arg0, REAL_TYPE)
10709           && validate_arg(arg1, POINTER_TYPE))
10710         return do_mpfr_lgamma_r (arg0, arg1, type);
10711     break;
10712
10713     CASE_FLT_FN (BUILT_IN_ATAN2):
10714       if (validate_arg (arg0, REAL_TYPE)
10715           && validate_arg(arg1, REAL_TYPE))
10716         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10717     break;
10718
10719     CASE_FLT_FN (BUILT_IN_FDIM):
10720       if (validate_arg (arg0, REAL_TYPE)
10721           && validate_arg(arg1, REAL_TYPE))
10722         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10723     break;
10724
10725     CASE_FLT_FN (BUILT_IN_HYPOT):
10726       return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10727
10728     CASE_FLT_FN (BUILT_IN_CPOW):
10729       if (validate_arg (arg0, COMPLEX_TYPE)
10730           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10731           && validate_arg (arg1, COMPLEX_TYPE)
10732           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE)
10733         return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10734     break;
10735
10736     CASE_FLT_FN (BUILT_IN_LDEXP):
10737       return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10738     CASE_FLT_FN (BUILT_IN_SCALBN):
10739     CASE_FLT_FN (BUILT_IN_SCALBLN):
10740       return fold_builtin_load_exponent (loc, arg0, arg1,
10741                                          type, /*ldexp=*/false);
10742
10743     CASE_FLT_FN (BUILT_IN_FREXP):
10744       return fold_builtin_frexp (loc, arg0, arg1, type);
10745
10746     CASE_FLT_FN (BUILT_IN_MODF):
10747       return fold_builtin_modf (loc, arg0, arg1, type);
10748
10749     case BUILT_IN_BZERO:
10750       return fold_builtin_bzero (loc, arg0, arg1, ignore);
10751
10752     case BUILT_IN_FPUTS:
10753       return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10754
10755     case BUILT_IN_FPUTS_UNLOCKED:
10756       return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10757
10758     case BUILT_IN_STRSTR:
10759       return fold_builtin_strstr (loc, arg0, arg1, type);
10760
10761     case BUILT_IN_STRCAT:
10762       return fold_builtin_strcat (loc, arg0, arg1);
10763
10764     case BUILT_IN_STRSPN:
10765       return fold_builtin_strspn (loc, arg0, arg1);
10766
10767     case BUILT_IN_STRCSPN:
10768       return fold_builtin_strcspn (loc, arg0, arg1);
10769
10770     case BUILT_IN_STRCHR:
10771     case BUILT_IN_INDEX:
10772       return fold_builtin_strchr (loc, arg0, arg1, type);
10773
10774     case BUILT_IN_STRRCHR:
10775     case BUILT_IN_RINDEX:
10776       return fold_builtin_strrchr (loc, arg0, arg1, type);
10777
10778     case BUILT_IN_STRCPY:
10779       return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10780
10781     case BUILT_IN_STPCPY:
10782       if (ignore)
10783         {
10784           tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
10785           if (!fn)
10786             break;
10787
10788           return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10789         }
10790       else
10791         return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10792       break;
10793
10794     case BUILT_IN_STRCMP:
10795       return fold_builtin_strcmp (loc, arg0, arg1);
10796
10797     case BUILT_IN_STRPBRK:
10798       return fold_builtin_strpbrk (loc, arg0, arg1, type);
10799
10800     case BUILT_IN_EXPECT:
10801       return fold_builtin_expect (loc, arg0, arg1);
10802
10803     CASE_FLT_FN (BUILT_IN_POW):
10804       return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10805
10806     CASE_FLT_FN (BUILT_IN_POWI):
10807       return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10808
10809     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10810       return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10811
10812     CASE_FLT_FN (BUILT_IN_FMIN):
10813       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10814
10815     CASE_FLT_FN (BUILT_IN_FMAX):
10816       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10817
10818     case BUILT_IN_ISGREATER:
10819       return fold_builtin_unordered_cmp (loc, fndecl,
10820                                          arg0, arg1, UNLE_EXPR, LE_EXPR);
10821     case BUILT_IN_ISGREATEREQUAL:
10822       return fold_builtin_unordered_cmp (loc, fndecl,
10823                                          arg0, arg1, UNLT_EXPR, LT_EXPR);
10824     case BUILT_IN_ISLESS:
10825       return fold_builtin_unordered_cmp (loc, fndecl,
10826                                          arg0, arg1, UNGE_EXPR, GE_EXPR);
10827     case BUILT_IN_ISLESSEQUAL:
10828       return fold_builtin_unordered_cmp (loc, fndecl,
10829                                          arg0, arg1, UNGT_EXPR, GT_EXPR);
10830     case BUILT_IN_ISLESSGREATER:
10831       return fold_builtin_unordered_cmp (loc, fndecl,
10832                                          arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10833     case BUILT_IN_ISUNORDERED:
10834       return fold_builtin_unordered_cmp (loc, fndecl,
10835                                          arg0, arg1, UNORDERED_EXPR,
10836                                          NOP_EXPR);
10837
10838       /* We do the folding for va_start in the expander.  */
10839     case BUILT_IN_VA_START:
10840       break;
10841
10842     case BUILT_IN_SPRINTF:
10843       return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10844
10845     case BUILT_IN_OBJECT_SIZE:
10846       return fold_builtin_object_size (arg0, arg1);
10847
10848     case BUILT_IN_PRINTF:
10849     case BUILT_IN_PRINTF_UNLOCKED:
10850     case BUILT_IN_VPRINTF:
10851       return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10852
10853     case BUILT_IN_PRINTF_CHK:
10854     case BUILT_IN_VPRINTF_CHK:
10855       if (!validate_arg (arg0, INTEGER_TYPE)
10856           || TREE_SIDE_EFFECTS (arg0))
10857         return NULL_TREE;
10858       else
10859         return fold_builtin_printf (loc, fndecl,
10860                                     arg1, NULL_TREE, ignore, fcode);
10861     break;
10862
10863     case BUILT_IN_FPRINTF:
10864     case BUILT_IN_FPRINTF_UNLOCKED:
10865     case BUILT_IN_VFPRINTF:
10866       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10867                                    ignore, fcode);
10868
10869     case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
10870       return fold_builtin_atomic_always_lock_free (arg0, arg1);
10871
10872     case BUILT_IN_ATOMIC_IS_LOCK_FREE:
10873       return fold_builtin_atomic_is_lock_free (arg0, arg1);
10874
10875     default:
10876       break;
10877     }
10878   return NULL_TREE;
10879 }
10880
10881 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10882    and ARG2.  IGNORE is true if the result of the function call is ignored.
10883    This function returns NULL_TREE if no simplification was possible.  */
10884
10885 static tree
10886 fold_builtin_3 (location_t loc, tree fndecl,
10887                 tree arg0, tree arg1, tree arg2, bool ignore)
10888 {
10889   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10890   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10891   switch (fcode)
10892     {
10893
10894     CASE_FLT_FN (BUILT_IN_SINCOS):
10895       return fold_builtin_sincos (loc, arg0, arg1, arg2);
10896
10897     CASE_FLT_FN (BUILT_IN_FMA):
10898       return fold_builtin_fma (loc, arg0, arg1, arg2, type);
10899     break;
10900
10901     CASE_FLT_FN (BUILT_IN_REMQUO):
10902       if (validate_arg (arg0, REAL_TYPE)
10903           && validate_arg(arg1, REAL_TYPE)
10904           && validate_arg(arg2, POINTER_TYPE))
10905         return do_mpfr_remquo (arg0, arg1, arg2);
10906     break;
10907
10908     case BUILT_IN_MEMSET:
10909       return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10910
10911     case BUILT_IN_BCOPY:
10912       return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10913                                      void_type_node, true, /*endp=*/3);
10914
10915     case BUILT_IN_MEMCPY:
10916       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10917                                      type, ignore, /*endp=*/0);
10918
10919     case BUILT_IN_MEMPCPY:
10920       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10921                                      type, ignore, /*endp=*/1);
10922
10923     case BUILT_IN_MEMMOVE:
10924       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10925                                      type, ignore, /*endp=*/3);
10926
10927     case BUILT_IN_STRNCAT:
10928       return fold_builtin_strncat (loc, arg0, arg1, arg2);
10929
10930     case BUILT_IN_STRNCPY:
10931       return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10932
10933     case BUILT_IN_STRNCMP:
10934       return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10935
10936     case BUILT_IN_MEMCHR:
10937       return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10938
10939     case BUILT_IN_BCMP:
10940     case BUILT_IN_MEMCMP:
10941       return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10942
10943     case BUILT_IN_SPRINTF:
10944       return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10945
10946     case BUILT_IN_SNPRINTF:
10947       return fold_builtin_snprintf (loc, arg0, arg1, arg2, NULL_TREE, ignore);
10948
10949     case BUILT_IN_STRCPY_CHK:
10950     case BUILT_IN_STPCPY_CHK:
10951       return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10952                                       ignore, fcode);
10953
10954     case BUILT_IN_STRCAT_CHK:
10955       return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10956
10957     case BUILT_IN_PRINTF_CHK:
10958     case BUILT_IN_VPRINTF_CHK:
10959       if (!validate_arg (arg0, INTEGER_TYPE)
10960           || TREE_SIDE_EFFECTS (arg0))
10961         return NULL_TREE;
10962       else
10963         return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10964     break;
10965
10966     case BUILT_IN_FPRINTF:
10967     case BUILT_IN_FPRINTF_UNLOCKED:
10968     case BUILT_IN_VFPRINTF:
10969       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10970                                    ignore, fcode);
10971
10972     case BUILT_IN_FPRINTF_CHK:
10973     case BUILT_IN_VFPRINTF_CHK:
10974       if (!validate_arg (arg1, INTEGER_TYPE)
10975           || TREE_SIDE_EFFECTS (arg1))
10976         return NULL_TREE;
10977       else
10978         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
10979                                      ignore, fcode);
10980
10981     default:
10982       break;
10983     }
10984   return NULL_TREE;
10985 }
10986
10987 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10988    ARG2, and ARG3.  IGNORE is true if the result of the function call is
10989    ignored.  This function returns NULL_TREE if no simplification was
10990    possible.  */
10991
10992 static tree
10993 fold_builtin_4 (location_t loc, tree fndecl,
10994                 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
10995 {
10996   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10997
10998   switch (fcode)
10999     {
11000     case BUILT_IN_MEMCPY_CHK:
11001     case BUILT_IN_MEMPCPY_CHK:
11002     case BUILT_IN_MEMMOVE_CHK:
11003     case BUILT_IN_MEMSET_CHK:
11004       return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
11005                                       NULL_TREE, ignore,
11006                                       DECL_FUNCTION_CODE (fndecl));
11007
11008     case BUILT_IN_STRNCPY_CHK:
11009     case BUILT_IN_STPNCPY_CHK:
11010       return fold_builtin_stxncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE,
11011                                        ignore, fcode);
11012
11013     case BUILT_IN_STRNCAT_CHK:
11014       return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
11015
11016     case BUILT_IN_SNPRINTF:
11017       return fold_builtin_snprintf (loc, arg0, arg1, arg2, arg3, ignore);
11018
11019     case BUILT_IN_FPRINTF_CHK:
11020     case BUILT_IN_VFPRINTF_CHK:
11021       if (!validate_arg (arg1, INTEGER_TYPE)
11022           || TREE_SIDE_EFFECTS (arg1))
11023         return NULL_TREE;
11024       else
11025         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
11026                                      ignore, fcode);
11027     break;
11028
11029     default:
11030       break;
11031     }
11032   return NULL_TREE;
11033 }
11034
11035 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
11036     arguments, where NARGS <= 4.  IGNORE is true if the result of the
11037     function call is ignored.  This function returns NULL_TREE if no
11038     simplification was possible.  Note that this only folds builtins with
11039     fixed argument patterns.  Foldings that do varargs-to-varargs
11040     transformations, or that match calls with more than 4 arguments,
11041     need to be handled with fold_builtin_varargs instead.  */
11042
11043 #define MAX_ARGS_TO_FOLD_BUILTIN 4
11044
11045 static tree
11046 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
11047 {
11048   tree ret = NULL_TREE;
11049
11050   switch (nargs)
11051     {
11052     case 0:
11053       ret = fold_builtin_0 (loc, fndecl, ignore);
11054       break;
11055     case 1:
11056       ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
11057       break;
11058     case 2:
11059       ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
11060       break;
11061     case 3:
11062       ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
11063       break;
11064     case 4:
11065       ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
11066                             ignore);
11067       break;
11068     default:
11069       break;
11070     }
11071   if (ret)
11072     {
11073       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11074       SET_EXPR_LOCATION (ret, loc);
11075       TREE_NO_WARNING (ret) = 1;
11076       return ret;
11077     }
11078   return NULL_TREE;
11079 }
11080
11081 /* Builtins with folding operations that operate on "..." arguments
11082    need special handling; we need to store the arguments in a convenient
11083    data structure before attempting any folding.  Fortunately there are
11084    only a few builtins that fall into this category.  FNDECL is the
11085    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
11086    result of the function call is ignored.  */
11087
11088 static tree
11089 fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
11090                       bool ignore ATTRIBUTE_UNUSED)
11091 {
11092   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
11093   tree ret = NULL_TREE;
11094
11095   switch (fcode)
11096     {
11097     case BUILT_IN_SPRINTF_CHK:
11098     case BUILT_IN_VSPRINTF_CHK:
11099       ret = fold_builtin_sprintf_chk (loc, exp, fcode);
11100       break;
11101
11102     case BUILT_IN_SNPRINTF_CHK:
11103     case BUILT_IN_VSNPRINTF_CHK:
11104       ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
11105       break;
11106
11107     case BUILT_IN_FPCLASSIFY:
11108       ret = fold_builtin_fpclassify (loc, exp);
11109       break;
11110
11111     default:
11112       break;
11113     }
11114   if (ret)
11115     {
11116       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
11117       SET_EXPR_LOCATION (ret, loc);
11118       TREE_NO_WARNING (ret) = 1;
11119       return ret;
11120     }
11121   return NULL_TREE;
11122 }
11123
11124 /* Return true if FNDECL shouldn't be folded right now.
11125    If a built-in function has an inline attribute always_inline
11126    wrapper, defer folding it after always_inline functions have
11127    been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
11128    might not be performed.  */
11129
11130 bool
11131 avoid_folding_inline_builtin (tree fndecl)
11132 {
11133   return (DECL_DECLARED_INLINE_P (fndecl)
11134           && DECL_DISREGARD_INLINE_LIMITS (fndecl)
11135           && cfun
11136           && !cfun->always_inline_functions_inlined
11137           && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
11138 }
11139
11140 /* A wrapper function for builtin folding that prevents warnings for
11141    "statement without effect" and the like, caused by removing the
11142    call node earlier than the warning is generated.  */
11143
11144 tree
11145 fold_call_expr (location_t loc, tree exp, bool ignore)
11146 {
11147   tree ret = NULL_TREE;
11148   tree fndecl = get_callee_fndecl (exp);
11149   if (fndecl
11150       && TREE_CODE (fndecl) == FUNCTION_DECL
11151       && DECL_BUILT_IN (fndecl)
11152       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
11153          yet.  Defer folding until we see all the arguments
11154          (after inlining).  */
11155       && !CALL_EXPR_VA_ARG_PACK (exp))
11156     {
11157       int nargs = call_expr_nargs (exp);
11158
11159       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
11160          instead last argument is __builtin_va_arg_pack ().  Defer folding
11161          even in that case, until arguments are finalized.  */
11162       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
11163         {
11164           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
11165           if (fndecl2
11166               && TREE_CODE (fndecl2) == FUNCTION_DECL
11167               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11168               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11169             return NULL_TREE;
11170         }
11171
11172       if (avoid_folding_inline_builtin (fndecl))
11173         return NULL_TREE;
11174
11175       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11176         return targetm.fold_builtin (fndecl, call_expr_nargs (exp),
11177                                      CALL_EXPR_ARGP (exp), ignore);
11178       else
11179         {
11180           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
11181             {
11182               tree *args = CALL_EXPR_ARGP (exp);
11183               ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
11184             }
11185           if (!ret)
11186             ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
11187           if (ret)
11188             return ret;
11189         }
11190     }
11191   return NULL_TREE;
11192 }
11193
11194 /* Conveniently construct a function call expression.  FNDECL names the
11195    function to be called and N arguments are passed in the array
11196    ARGARRAY.  */
11197
11198 tree
11199 build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
11200 {
11201   tree fntype = TREE_TYPE (fndecl);
11202   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11203  
11204   return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
11205 }
11206
11207 /* Conveniently construct a function call expression.  FNDECL names the
11208    function to be called and the arguments are passed in the vector
11209    VEC.  */
11210
11211 tree
11212 build_call_expr_loc_vec (location_t loc, tree fndecl, vec<tree, va_gc> *vec)
11213 {
11214   return build_call_expr_loc_array (loc, fndecl, vec_safe_length (vec),
11215                                     vec_safe_address (vec));
11216 }
11217
11218
11219 /* Conveniently construct a function call expression.  FNDECL names the
11220    function to be called, N is the number of arguments, and the "..."
11221    parameters are the argument expressions.  */
11222
11223 tree
11224 build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
11225 {
11226   va_list ap;
11227   tree *argarray = XALLOCAVEC (tree, n);
11228   int i;
11229
11230   va_start (ap, n);
11231   for (i = 0; i < n; i++)
11232     argarray[i] = va_arg (ap, tree);
11233   va_end (ap);
11234   return build_call_expr_loc_array (loc, fndecl, n, argarray);
11235 }
11236
11237 /* Like build_call_expr_loc (UNKNOWN_LOCATION, ...).  Duplicated because
11238    varargs macros aren't supported by all bootstrap compilers.  */
11239
11240 tree
11241 build_call_expr (tree fndecl, int n, ...)
11242 {
11243   va_list ap;
11244   tree *argarray = XALLOCAVEC (tree, n);
11245   int i;
11246
11247   va_start (ap, n);
11248   for (i = 0; i < n; i++)
11249     argarray[i] = va_arg (ap, tree);
11250   va_end (ap);
11251   return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
11252 }
11253
11254 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
11255    N arguments are passed in the array ARGARRAY.  */
11256
11257 tree
11258 fold_builtin_call_array (location_t loc, tree type,
11259                          tree fn,
11260                          int n,
11261                          tree *argarray)
11262 {
11263   tree ret = NULL_TREE;
11264    tree exp;
11265
11266   if (TREE_CODE (fn) == ADDR_EXPR)
11267   {
11268     tree fndecl = TREE_OPERAND (fn, 0);
11269     if (TREE_CODE (fndecl) == FUNCTION_DECL
11270         && DECL_BUILT_IN (fndecl))
11271       {
11272         /* If last argument is __builtin_va_arg_pack (), arguments to this
11273            function are not finalized yet.  Defer folding until they are.  */
11274         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
11275           {
11276             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
11277             if (fndecl2
11278                 && TREE_CODE (fndecl2) == FUNCTION_DECL
11279                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
11280                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
11281               return build_call_array_loc (loc, type, fn, n, argarray);
11282           }
11283         if (avoid_folding_inline_builtin (fndecl))
11284           return build_call_array_loc (loc, type, fn, n, argarray);
11285         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
11286           {
11287             ret = targetm.fold_builtin (fndecl, n, argarray, false);
11288             if (ret)
11289               return ret;
11290
11291             return build_call_array_loc (loc, type, fn, n, argarray);
11292           }
11293         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
11294           {
11295             /* First try the transformations that don't require consing up
11296                an exp.  */
11297             ret = fold_builtin_n (loc, fndecl, argarray, n, false);
11298             if (ret)
11299               return ret;
11300           }
11301
11302         /* If we got this far, we need to build an exp.  */
11303         exp = build_call_array_loc (loc, type, fn, n, argarray);
11304         ret = fold_builtin_varargs (loc, fndecl, exp, false);
11305         return ret ? ret : exp;
11306       }
11307   }
11308
11309   return build_call_array_loc (loc, type, fn, n, argarray);
11310 }
11311
11312 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11313    list ARGS along with N new arguments in NEWARGS.  SKIP is the number
11314    of arguments in ARGS to be omitted.  OLDNARGS is the number of
11315    elements in ARGS.  */
11316
11317 static tree
11318 rewrite_call_expr_valist (location_t loc, int oldnargs, tree *args,
11319                           int skip, tree fndecl, int n, va_list newargs)
11320 {
11321   int nargs = oldnargs - skip + n;
11322   tree *buffer;
11323
11324   if (n > 0)
11325     {
11326       int i, j;
11327
11328       buffer = XALLOCAVEC (tree, nargs);
11329       for (i = 0; i < n; i++)
11330         buffer[i] = va_arg (newargs, tree);
11331       for (j = skip; j < oldnargs; j++, i++)
11332         buffer[i] = args[j];
11333     }
11334   else
11335     buffer = args + skip;
11336
11337   return build_call_expr_loc_array (loc, fndecl, nargs, buffer);
11338 }
11339
11340 /* Construct a new CALL_EXPR to FNDECL using the tail of the argument
11341    list ARGS along with N new arguments specified as the "..."
11342    parameters.  SKIP is the number of arguments in ARGS to be omitted.
11343    OLDNARGS is the number of elements in ARGS.  */
11344
11345 static tree
11346 rewrite_call_expr_array (location_t loc, int oldnargs, tree *args,
11347                          int skip, tree fndecl, int n, ...)
11348 {
11349   va_list ap;
11350   tree t;
11351
11352   va_start (ap, n);
11353   t = rewrite_call_expr_valist (loc, oldnargs, args, skip, fndecl, n, ap);
11354   va_end (ap);
11355
11356   return t;
11357 }
11358
11359 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
11360    along with N new arguments specified as the "..." parameters.  SKIP
11361    is the number of arguments in EXP to be omitted.  This function is used
11362    to do varargs-to-varargs transformations.  */
11363
11364 static tree
11365 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
11366 {
11367   va_list ap;
11368   tree t;
11369
11370   va_start (ap, n);
11371   t = rewrite_call_expr_valist (loc, call_expr_nargs (exp),
11372                                 CALL_EXPR_ARGP (exp), skip, fndecl, n, ap);
11373   va_end (ap);
11374
11375   return t;
11376 }
11377
11378 /* Validate a single argument ARG against a tree code CODE representing
11379    a type.  */
11380
11381 static bool
11382 validate_arg (const_tree arg, enum tree_code code)
11383 {
11384   if (!arg)
11385     return false;
11386   else if (code == POINTER_TYPE)
11387     return POINTER_TYPE_P (TREE_TYPE (arg));
11388   else if (code == INTEGER_TYPE)
11389     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11390   return code == TREE_CODE (TREE_TYPE (arg));
11391 }
11392
11393 /* This function validates the types of a function call argument list
11394    against a specified list of tree_codes.  If the last specifier is a 0,
11395    that represents an ellipses, otherwise the last specifier must be a
11396    VOID_TYPE.
11397
11398    This is the GIMPLE version of validate_arglist.  Eventually we want to
11399    completely convert builtins.c to work from GIMPLEs and the tree based
11400    validate_arglist will then be removed.  */
11401
11402 bool
11403 validate_gimple_arglist (const_gimple call, ...)
11404 {
11405   enum tree_code code;
11406   bool res = 0;
11407   va_list ap;
11408   const_tree arg;
11409   size_t i;
11410
11411   va_start (ap, call);
11412   i = 0;
11413
11414   do
11415     {
11416       code = (enum tree_code) va_arg (ap, int);
11417       switch (code)
11418         {
11419         case 0:
11420           /* This signifies an ellipses, any further arguments are all ok.  */
11421           res = true;
11422           goto end;
11423         case VOID_TYPE:
11424           /* This signifies an endlink, if no arguments remain, return
11425              true, otherwise return false.  */
11426           res = (i == gimple_call_num_args (call));
11427           goto end;
11428         default:
11429           /* If no parameters remain or the parameter's code does not
11430              match the specified code, return false.  Otherwise continue
11431              checking any remaining arguments.  */
11432           arg = gimple_call_arg (call, i++);
11433           if (!validate_arg (arg, code))
11434             goto end;
11435           break;
11436         }
11437     }
11438   while (1);
11439
11440   /* We need gotos here since we can only have one VA_CLOSE in a
11441      function.  */
11442  end: ;
11443   va_end (ap);
11444
11445   return res;
11446 }
11447
11448 /* This function validates the types of a function call argument list
11449    against a specified list of tree_codes.  If the last specifier is a 0,
11450    that represents an ellipses, otherwise the last specifier must be a
11451    VOID_TYPE.  */
11452
11453 bool
11454 validate_arglist (const_tree callexpr, ...)
11455 {
11456   enum tree_code code;
11457   bool res = 0;
11458   va_list ap;
11459   const_call_expr_arg_iterator iter;
11460   const_tree arg;
11461
11462   va_start (ap, callexpr);
11463   init_const_call_expr_arg_iterator (callexpr, &iter);
11464
11465   do
11466     {
11467       code = (enum tree_code) va_arg (ap, int);
11468       switch (code)
11469         {
11470         case 0:
11471           /* This signifies an ellipses, any further arguments are all ok.  */
11472           res = true;
11473           goto end;
11474         case VOID_TYPE:
11475           /* This signifies an endlink, if no arguments remain, return
11476              true, otherwise return false.  */
11477           res = !more_const_call_expr_args_p (&iter);
11478           goto end;
11479         default:
11480           /* If no parameters remain or the parameter's code does not
11481              match the specified code, return false.  Otherwise continue
11482              checking any remaining arguments.  */
11483           arg = next_const_call_expr_arg (&iter);
11484           if (!validate_arg (arg, code))
11485             goto end;
11486           break;
11487         }
11488     }
11489   while (1);
11490
11491   /* We need gotos here since we can only have one VA_CLOSE in a
11492      function.  */
11493  end: ;
11494   va_end (ap);
11495
11496   return res;
11497 }
11498
11499 /* Default target-specific builtin expander that does nothing.  */
11500
11501 rtx
11502 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11503                         rtx target ATTRIBUTE_UNUSED,
11504                         rtx subtarget ATTRIBUTE_UNUSED,
11505                         enum machine_mode mode ATTRIBUTE_UNUSED,
11506                         int ignore ATTRIBUTE_UNUSED)
11507 {
11508   return NULL_RTX;
11509 }
11510
11511 /* Returns true is EXP represents data that would potentially reside
11512    in a readonly section.  */
11513
11514 static bool
11515 readonly_data_expr (tree exp)
11516 {
11517   STRIP_NOPS (exp);
11518
11519   if (TREE_CODE (exp) != ADDR_EXPR)
11520     return false;
11521
11522   exp = get_base_address (TREE_OPERAND (exp, 0));
11523   if (!exp)
11524     return false;
11525
11526   /* Make sure we call decl_readonly_section only for trees it
11527      can handle (since it returns true for everything it doesn't
11528      understand).  */
11529   if (TREE_CODE (exp) == STRING_CST
11530       || TREE_CODE (exp) == CONSTRUCTOR
11531       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11532     return decl_readonly_section (exp, 0);
11533   else
11534     return false;
11535 }
11536
11537 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11538    to the call, and TYPE is its return type.
11539
11540    Return NULL_TREE if no simplification was possible, otherwise return the
11541    simplified form of the call as a tree.
11542
11543    The simplified form may be a constant or other expression which
11544    computes the same value, but in a more efficient manner (including
11545    calls to other builtin functions).
11546
11547    The call may contain arguments which need to be evaluated, but
11548    which are not useful to determine the result of the call.  In
11549    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11550    COMPOUND_EXPR will be an argument which must be evaluated.
11551    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11552    COMPOUND_EXPR in the chain will contain the tree for the simplified
11553    form of the builtin function call.  */
11554
11555 static tree
11556 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11557 {
11558   if (!validate_arg (s1, POINTER_TYPE)
11559       || !validate_arg (s2, POINTER_TYPE))
11560     return NULL_TREE;
11561   else
11562     {
11563       tree fn;
11564       const char *p1, *p2;
11565
11566       p2 = c_getstr (s2);
11567       if (p2 == NULL)
11568         return NULL_TREE;
11569
11570       p1 = c_getstr (s1);
11571       if (p1 != NULL)
11572         {
11573           const char *r = strstr (p1, p2);
11574           tree tem;
11575
11576           if (r == NULL)
11577             return build_int_cst (TREE_TYPE (s1), 0);
11578
11579           /* Return an offset into the constant string argument.  */
11580           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11581           return fold_convert_loc (loc, type, tem);
11582         }
11583
11584       /* The argument is const char *, and the result is char *, so we need
11585          a type conversion here to avoid a warning.  */
11586       if (p2[0] == '\0')
11587         return fold_convert_loc (loc, type, s1);
11588
11589       if (p2[1] != '\0')
11590         return NULL_TREE;
11591
11592       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11593       if (!fn)
11594         return NULL_TREE;
11595
11596       /* New argument list transforming strstr(s1, s2) to
11597          strchr(s1, s2[0]).  */
11598       return build_call_expr_loc (loc, fn, 2, s1,
11599                                   build_int_cst (integer_type_node, p2[0]));
11600     }
11601 }
11602
11603 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11604    the call, and TYPE is its return type.
11605
11606    Return NULL_TREE if no simplification was possible, otherwise return the
11607    simplified form of the call as a tree.
11608
11609    The simplified form may be a constant or other expression which
11610    computes the same value, but in a more efficient manner (including
11611    calls to other builtin functions).
11612
11613    The call may contain arguments which need to be evaluated, but
11614    which are not useful to determine the result of the call.  In
11615    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11616    COMPOUND_EXPR will be an argument which must be evaluated.
11617    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11618    COMPOUND_EXPR in the chain will contain the tree for the simplified
11619    form of the builtin function call.  */
11620
11621 static tree
11622 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11623 {
11624   if (!validate_arg (s1, POINTER_TYPE)
11625       || !validate_arg (s2, INTEGER_TYPE))
11626     return NULL_TREE;
11627   else
11628     {
11629       const char *p1;
11630
11631       if (TREE_CODE (s2) != INTEGER_CST)
11632         return NULL_TREE;
11633
11634       p1 = c_getstr (s1);
11635       if (p1 != NULL)
11636         {
11637           char c;
11638           const char *r;
11639           tree tem;
11640
11641           if (target_char_cast (s2, &c))
11642             return NULL_TREE;
11643
11644           r = strchr (p1, c);
11645
11646           if (r == NULL)
11647             return build_int_cst (TREE_TYPE (s1), 0);
11648
11649           /* Return an offset into the constant string argument.  */
11650           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11651           return fold_convert_loc (loc, type, tem);
11652         }
11653       return NULL_TREE;
11654     }
11655 }
11656
11657 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11658    the call, and TYPE is its return type.
11659
11660    Return NULL_TREE if no simplification was possible, otherwise return the
11661    simplified form of the call as a tree.
11662
11663    The simplified form may be a constant or other expression which
11664    computes the same value, but in a more efficient manner (including
11665    calls to other builtin functions).
11666
11667    The call may contain arguments which need to be evaluated, but
11668    which are not useful to determine the result of the call.  In
11669    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11670    COMPOUND_EXPR will be an argument which must be evaluated.
11671    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11672    COMPOUND_EXPR in the chain will contain the tree for the simplified
11673    form of the builtin function call.  */
11674
11675 static tree
11676 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11677 {
11678   if (!validate_arg (s1, POINTER_TYPE)
11679       || !validate_arg (s2, INTEGER_TYPE))
11680     return NULL_TREE;
11681   else
11682     {
11683       tree fn;
11684       const char *p1;
11685
11686       if (TREE_CODE (s2) != INTEGER_CST)
11687         return NULL_TREE;
11688
11689       p1 = c_getstr (s1);
11690       if (p1 != NULL)
11691         {
11692           char c;
11693           const char *r;
11694           tree tem;
11695
11696           if (target_char_cast (s2, &c))
11697             return NULL_TREE;
11698
11699           r = strrchr (p1, c);
11700
11701           if (r == NULL)
11702             return build_int_cst (TREE_TYPE (s1), 0);
11703
11704           /* Return an offset into the constant string argument.  */
11705           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11706           return fold_convert_loc (loc, type, tem);
11707         }
11708
11709       if (! integer_zerop (s2))
11710         return NULL_TREE;
11711
11712       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11713       if (!fn)
11714         return NULL_TREE;
11715
11716       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11717       return build_call_expr_loc (loc, fn, 2, s1, s2);
11718     }
11719 }
11720
11721 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11722    to the call, and TYPE is its return type.
11723
11724    Return NULL_TREE if no simplification was possible, otherwise return the
11725    simplified form of the call as a tree.
11726
11727    The simplified form may be a constant or other expression which
11728    computes the same value, but in a more efficient manner (including
11729    calls to other builtin functions).
11730
11731    The call may contain arguments which need to be evaluated, but
11732    which are not useful to determine the result of the call.  In
11733    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11734    COMPOUND_EXPR will be an argument which must be evaluated.
11735    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11736    COMPOUND_EXPR in the chain will contain the tree for the simplified
11737    form of the builtin function call.  */
11738
11739 static tree
11740 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11741 {
11742   if (!validate_arg (s1, POINTER_TYPE)
11743       || !validate_arg (s2, POINTER_TYPE))
11744     return NULL_TREE;
11745   else
11746     {
11747       tree fn;
11748       const char *p1, *p2;
11749
11750       p2 = c_getstr (s2);
11751       if (p2 == NULL)
11752         return NULL_TREE;
11753
11754       p1 = c_getstr (s1);
11755       if (p1 != NULL)
11756         {
11757           const char *r = strpbrk (p1, p2);
11758           tree tem;
11759
11760           if (r == NULL)
11761             return build_int_cst (TREE_TYPE (s1), 0);
11762
11763           /* Return an offset into the constant string argument.  */
11764           tem = fold_build_pointer_plus_hwi_loc (loc, s1, r - p1);
11765           return fold_convert_loc (loc, type, tem);
11766         }
11767
11768       if (p2[0] == '\0')
11769         /* strpbrk(x, "") == NULL.
11770            Evaluate and ignore s1 in case it had side-effects.  */
11771         return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11772
11773       if (p2[1] != '\0')
11774         return NULL_TREE;  /* Really call strpbrk.  */
11775
11776       fn = builtin_decl_implicit (BUILT_IN_STRCHR);
11777       if (!fn)
11778         return NULL_TREE;
11779
11780       /* New argument list transforming strpbrk(s1, s2) to
11781          strchr(s1, s2[0]).  */
11782       return build_call_expr_loc (loc, fn, 2, s1,
11783                                   build_int_cst (integer_type_node, p2[0]));
11784     }
11785 }
11786
11787 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11788    to the call.
11789
11790    Return NULL_TREE if no simplification was possible, otherwise return the
11791    simplified form of the call as a tree.
11792
11793    The simplified form may be a constant or other expression which
11794    computes the same value, but in a more efficient manner (including
11795    calls to other builtin functions).
11796
11797    The call may contain arguments which need to be evaluated, but
11798    which are not useful to determine the result of the call.  In
11799    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11800    COMPOUND_EXPR will be an argument which must be evaluated.
11801    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11802    COMPOUND_EXPR in the chain will contain the tree for the simplified
11803    form of the builtin function call.  */
11804
11805 static tree
11806 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11807 {
11808   if (!validate_arg (dst, POINTER_TYPE)
11809       || !validate_arg (src, POINTER_TYPE))
11810     return NULL_TREE;
11811   else
11812     {
11813       const char *p = c_getstr (src);
11814
11815       /* If the string length is zero, return the dst parameter.  */
11816       if (p && *p == '\0')
11817         return dst;
11818
11819       if (optimize_insn_for_speed_p ())
11820         {
11821           /* See if we can store by pieces into (dst + strlen(dst)).  */
11822           tree newdst, call;
11823           tree strlen_fn = builtin_decl_implicit (BUILT_IN_STRLEN);
11824           tree strcpy_fn = builtin_decl_implicit (BUILT_IN_STRCPY);
11825
11826           if (!strlen_fn || !strcpy_fn)
11827             return NULL_TREE;
11828
11829           /* If we don't have a movstr we don't want to emit an strcpy
11830              call.  We have to do that if the length of the source string
11831              isn't computable (in that case we can use memcpy probably
11832              later expanding to a sequence of mov instructions).  If we
11833              have movstr instructions we can emit strcpy calls.  */
11834           if (!HAVE_movstr)
11835             {
11836               tree len = c_strlen (src, 1);
11837               if (! len || TREE_SIDE_EFFECTS (len))
11838                 return NULL_TREE;
11839             }
11840
11841           /* Stabilize the argument list.  */
11842           dst = builtin_save_expr (dst);
11843
11844           /* Create strlen (dst).  */
11845           newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11846           /* Create (dst p+ strlen (dst)).  */
11847
11848           newdst = fold_build_pointer_plus_loc (loc, dst, newdst);
11849           newdst = builtin_save_expr (newdst);
11850
11851           call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11852           return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11853         }
11854       return NULL_TREE;
11855     }
11856 }
11857
11858 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11859    arguments to the call.
11860
11861    Return NULL_TREE if no simplification was possible, otherwise return the
11862    simplified form of the call as a tree.
11863
11864    The simplified form may be a constant or other expression which
11865    computes the same value, but in a more efficient manner (including
11866    calls to other builtin functions).
11867
11868    The call may contain arguments which need to be evaluated, but
11869    which are not useful to determine the result of the call.  In
11870    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11871    COMPOUND_EXPR will be an argument which must be evaluated.
11872    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11873    COMPOUND_EXPR in the chain will contain the tree for the simplified
11874    form of the builtin function call.  */
11875
11876 static tree
11877 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11878 {
11879   if (!validate_arg (dst, POINTER_TYPE)
11880       || !validate_arg (src, POINTER_TYPE)
11881       || !validate_arg (len, INTEGER_TYPE))
11882     return NULL_TREE;
11883   else
11884     {
11885       const char *p = c_getstr (src);
11886
11887       /* If the requested length is zero, or the src parameter string
11888          length is zero, return the dst parameter.  */
11889       if (integer_zerop (len) || (p && *p == '\0'))
11890         return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11891
11892       /* If the requested len is greater than or equal to the string
11893          length, call strcat.  */
11894       if (TREE_CODE (len) == INTEGER_CST && p
11895           && compare_tree_int (len, strlen (p)) >= 0)
11896         {
11897           tree fn = builtin_decl_implicit (BUILT_IN_STRCAT);
11898
11899           /* If the replacement _DECL isn't initialized, don't do the
11900              transformation.  */
11901           if (!fn)
11902             return NULL_TREE;
11903
11904           return build_call_expr_loc (loc, fn, 2, dst, src);
11905         }
11906       return NULL_TREE;
11907     }
11908 }
11909
11910 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11911    to the call.
11912
11913    Return NULL_TREE if no simplification was possible, otherwise return the
11914    simplified form of the call as a tree.
11915
11916    The simplified form may be a constant or other expression which
11917    computes the same value, but in a more efficient manner (including
11918    calls to other builtin functions).
11919
11920    The call may contain arguments which need to be evaluated, but
11921    which are not useful to determine the result of the call.  In
11922    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11923    COMPOUND_EXPR will be an argument which must be evaluated.
11924    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11925    COMPOUND_EXPR in the chain will contain the tree for the simplified
11926    form of the builtin function call.  */
11927
11928 static tree
11929 fold_builtin_strspn (location_t loc, tree s1, tree s2)
11930 {
11931   if (!validate_arg (s1, POINTER_TYPE)
11932       || !validate_arg (s2, POINTER_TYPE))
11933     return NULL_TREE;
11934   else
11935     {
11936       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11937
11938       /* If both arguments are constants, evaluate at compile-time.  */
11939       if (p1 && p2)
11940         {
11941           const size_t r = strspn (p1, p2);
11942           return build_int_cst (size_type_node, r);
11943         }
11944
11945       /* If either argument is "", return NULL_TREE.  */
11946       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11947         /* Evaluate and ignore both arguments in case either one has
11948            side-effects.  */
11949         return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11950                                   s1, s2);
11951       return NULL_TREE;
11952     }
11953 }
11954
11955 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11956    to the call.
11957
11958    Return NULL_TREE if no simplification was possible, otherwise return the
11959    simplified form of the call as a tree.
11960
11961    The simplified form may be a constant or other expression which
11962    computes the same value, but in a more efficient manner (including
11963    calls to other builtin functions).
11964
11965    The call may contain arguments which need to be evaluated, but
11966    which are not useful to determine the result of the call.  In
11967    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11968    COMPOUND_EXPR will be an argument which must be evaluated.
11969    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11970    COMPOUND_EXPR in the chain will contain the tree for the simplified
11971    form of the builtin function call.  */
11972
11973 static tree
11974 fold_builtin_strcspn (location_t loc, tree s1, tree s2)
11975 {
11976   if (!validate_arg (s1, POINTER_TYPE)
11977       || !validate_arg (s2, POINTER_TYPE))
11978     return NULL_TREE;
11979   else
11980     {
11981       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11982
11983       /* If both arguments are constants, evaluate at compile-time.  */
11984       if (p1 && p2)
11985         {
11986           const size_t r = strcspn (p1, p2);
11987           return build_int_cst (size_type_node, r);
11988         }
11989
11990       /* If the first argument is "", return NULL_TREE.  */
11991       if (p1 && *p1 == '\0')
11992         {
11993           /* Evaluate and ignore argument s2 in case it has
11994              side-effects.  */
11995           return omit_one_operand_loc (loc, size_type_node,
11996                                    size_zero_node, s2);
11997         }
11998
11999       /* If the second argument is "", return __builtin_strlen(s1).  */
12000       if (p2 && *p2 == '\0')
12001         {
12002           tree fn = builtin_decl_implicit (BUILT_IN_STRLEN);
12003
12004           /* If the replacement _DECL isn't initialized, don't do the
12005              transformation.  */
12006           if (!fn)
12007             return NULL_TREE;
12008
12009           return build_call_expr_loc (loc, fn, 1, s1);
12010         }
12011       return NULL_TREE;
12012     }
12013 }
12014
12015 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
12016    to the call.  IGNORE is true if the value returned
12017    by the builtin will be ignored.  UNLOCKED is true is true if this
12018    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
12019    the known length of the string.  Return NULL_TREE if no simplification
12020    was possible.  */
12021
12022 tree
12023 fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
12024                     bool ignore, bool unlocked, tree len)
12025 {
12026   /* If we're using an unlocked function, assume the other unlocked
12027      functions exist explicitly.  */
12028   tree const fn_fputc = (unlocked
12029                          ? builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED)
12030                          : builtin_decl_implicit (BUILT_IN_FPUTC));
12031   tree const fn_fwrite = (unlocked
12032                           ? builtin_decl_explicit (BUILT_IN_FWRITE_UNLOCKED)
12033                           : builtin_decl_implicit (BUILT_IN_FWRITE));
12034
12035   /* If the return value is used, don't do the transformation.  */
12036   if (!ignore)
12037     return NULL_TREE;
12038
12039   /* Verify the arguments in the original call.  */
12040   if (!validate_arg (arg0, POINTER_TYPE)
12041       || !validate_arg (arg1, POINTER_TYPE))
12042     return NULL_TREE;
12043
12044   if (! len)
12045     len = c_strlen (arg0, 0);
12046
12047   /* Get the length of the string passed to fputs.  If the length
12048      can't be determined, punt.  */
12049   if (!len
12050       || TREE_CODE (len) != INTEGER_CST)
12051     return NULL_TREE;
12052
12053   switch (compare_tree_int (len, 1))
12054     {
12055     case -1: /* length is 0, delete the call entirely .  */
12056       return omit_one_operand_loc (loc, integer_type_node,
12057                                integer_zero_node, arg1);;
12058
12059     case 0: /* length is 1, call fputc.  */
12060       {
12061         const char *p = c_getstr (arg0);
12062
12063         if (p != NULL)
12064           {
12065             if (fn_fputc)
12066               return build_call_expr_loc (loc, fn_fputc, 2,
12067                                           build_int_cst
12068                                             (integer_type_node, p[0]), arg1);
12069             else
12070               return NULL_TREE;
12071           }
12072       }
12073       /* FALLTHROUGH */
12074     case 1: /* length is greater than 1, call fwrite.  */
12075       {
12076         /* If optimizing for size keep fputs.  */
12077         if (optimize_function_for_size_p (cfun))
12078           return NULL_TREE;
12079         /* New argument list transforming fputs(string, stream) to
12080            fwrite(string, 1, len, stream).  */
12081         if (fn_fwrite)
12082           return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
12083                                   size_one_node, len, arg1);
12084         else
12085           return NULL_TREE;
12086       }
12087     default:
12088       gcc_unreachable ();
12089     }
12090   return NULL_TREE;
12091 }
12092
12093 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
12094    produced.  False otherwise.  This is done so that we don't output the error
12095    or warning twice or three times.  */
12096
12097 bool
12098 fold_builtin_next_arg (tree exp, bool va_start_p)
12099 {
12100   tree fntype = TREE_TYPE (current_function_decl);
12101   int nargs = call_expr_nargs (exp);
12102   tree arg;
12103   /* There is good chance the current input_location points inside the
12104      definition of the va_start macro (perhaps on the token for
12105      builtin) in a system header, so warnings will not be emitted.
12106      Use the location in real source code.  */
12107   source_location current_location =
12108     linemap_unwind_to_first_non_reserved_loc (line_table, input_location,
12109                                               NULL);
12110
12111   if (!stdarg_p (fntype))
12112     {
12113       error ("%<va_start%> used in function with fixed args");
12114       return true;
12115     }
12116
12117   if (va_start_p)
12118     {
12119       if (va_start_p && (nargs != 2))
12120         {
12121           error ("wrong number of arguments to function %<va_start%>");
12122           return true;
12123         }
12124       arg = CALL_EXPR_ARG (exp, 1);
12125     }
12126   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
12127      when we checked the arguments and if needed issued a warning.  */
12128   else
12129     {
12130       if (nargs == 0)
12131         {
12132           /* Evidently an out of date version of <stdarg.h>; can't validate
12133              va_start's second argument, but can still work as intended.  */
12134           warning_at (current_location,
12135                       OPT_Wvarargs,
12136                    "%<__builtin_next_arg%> called without an argument");
12137           return true;
12138         }
12139       else if (nargs > 1)
12140         {
12141           error ("wrong number of arguments to function %<__builtin_next_arg%>");
12142           return true;
12143         }
12144       arg = CALL_EXPR_ARG (exp, 0);
12145     }
12146
12147   if (TREE_CODE (arg) == SSA_NAME)
12148     arg = SSA_NAME_VAR (arg);
12149
12150   /* We destructively modify the call to be __builtin_va_start (ap, 0)
12151      or __builtin_next_arg (0) the first time we see it, after checking
12152      the arguments and if needed issuing a warning.  */
12153   if (!integer_zerop (arg))
12154     {
12155       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
12156
12157       /* Strip off all nops for the sake of the comparison.  This
12158          is not quite the same as STRIP_NOPS.  It does more.
12159          We must also strip off INDIRECT_EXPR for C++ reference
12160          parameters.  */
12161       while (CONVERT_EXPR_P (arg)
12162              || TREE_CODE (arg) == INDIRECT_REF)
12163         arg = TREE_OPERAND (arg, 0);
12164       if (arg != last_parm)
12165         {
12166           /* FIXME: Sometimes with the tree optimizers we can get the
12167              not the last argument even though the user used the last
12168              argument.  We just warn and set the arg to be the last
12169              argument so that we will get wrong-code because of
12170              it.  */
12171           warning_at (current_location,
12172                       OPT_Wvarargs,
12173                       "second parameter of %<va_start%> not last named argument");
12174         }
12175
12176       /* Undefined by C99 7.15.1.4p4 (va_start):
12177          "If the parameter parmN is declared with the register storage
12178          class, with a function or array type, or with a type that is
12179          not compatible with the type that results after application of
12180          the default argument promotions, the behavior is undefined."
12181       */
12182       else if (DECL_REGISTER (arg))
12183         {
12184           warning_at (current_location,
12185                       OPT_Wvarargs,
12186                       "undefined behaviour when second parameter of "
12187                       "%<va_start%> is declared with %<register%> storage");
12188         }
12189
12190       /* We want to verify the second parameter just once before the tree
12191          optimizers are run and then avoid keeping it in the tree,
12192          as otherwise we could warn even for correct code like:
12193          void foo (int i, ...)
12194          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
12195       if (va_start_p)
12196         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
12197       else
12198         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
12199     }
12200   return false;
12201 }
12202
12203
12204 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
12205    ORIG may be null if this is a 2-argument call.  We don't attempt to
12206    simplify calls with more than 3 arguments.
12207
12208    Return NULL_TREE if no simplification was possible, otherwise return the
12209    simplified form of the call as a tree.  If IGNORED is true, it means that
12210    the caller does not use the returned value of the function.  */
12211
12212 static tree
12213 fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
12214                       tree orig, int ignored)
12215 {
12216   tree call, retval;
12217   const char *fmt_str = NULL;
12218
12219   /* Verify the required arguments in the original call.  We deal with two
12220      types of sprintf() calls: 'sprintf (str, fmt)' and
12221      'sprintf (dest, "%s", orig)'.  */
12222   if (!validate_arg (dest, POINTER_TYPE)
12223       || !validate_arg (fmt, POINTER_TYPE))
12224     return NULL_TREE;
12225   if (orig && !validate_arg (orig, POINTER_TYPE))
12226     return NULL_TREE;
12227
12228   /* Check whether the format is a literal string constant.  */
12229   fmt_str = c_getstr (fmt);
12230   if (fmt_str == NULL)
12231     return NULL_TREE;
12232
12233   call = NULL_TREE;
12234   retval = NULL_TREE;
12235
12236   if (!init_target_chars ())
12237     return NULL_TREE;
12238
12239   /* If the format doesn't contain % args or %%, use strcpy.  */
12240   if (strchr (fmt_str, target_percent) == NULL)
12241     {
12242       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12243
12244       if (!fn)
12245         return NULL_TREE;
12246
12247       /* Don't optimize sprintf (buf, "abc", ptr++).  */
12248       if (orig)
12249         return NULL_TREE;
12250
12251       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
12252          'format' is known to contain no % formats.  */
12253       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12254       if (!ignored)
12255         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12256     }
12257
12258   /* If the format is "%s", use strcpy if the result isn't used.  */
12259   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12260     {
12261       tree fn;
12262       fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12263
12264       if (!fn)
12265         return NULL_TREE;
12266
12267       /* Don't crash on sprintf (str1, "%s").  */
12268       if (!orig)
12269         return NULL_TREE;
12270
12271       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
12272       if (!ignored)
12273         {
12274           retval = c_strlen (orig, 1);
12275           if (!retval || TREE_CODE (retval) != INTEGER_CST)
12276             return NULL_TREE;
12277         }
12278       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12279     }
12280
12281   if (call && retval)
12282     {
12283       retval = fold_convert_loc
12284         (loc, TREE_TYPE (TREE_TYPE (builtin_decl_implicit (BUILT_IN_SPRINTF))),
12285          retval);
12286       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12287     }
12288   else
12289     return call;
12290 }
12291
12292 /* Simplify a call to the snprintf builtin with arguments DEST, DESTSIZE,
12293    FMT, and ORIG.  ORIG may be null if this is a 3-argument call.  We don't
12294    attempt to simplify calls with more than 4 arguments.
12295
12296    Return NULL_TREE if no simplification was possible, otherwise return the
12297    simplified form of the call as a tree.  If IGNORED is true, it means that
12298    the caller does not use the returned value of the function.  */
12299
12300 static tree
12301 fold_builtin_snprintf (location_t loc, tree dest, tree destsize, tree fmt,
12302                        tree orig, int ignored)
12303 {
12304   tree call, retval;
12305   const char *fmt_str = NULL;
12306   unsigned HOST_WIDE_INT destlen;
12307
12308   /* Verify the required arguments in the original call.  We deal with two
12309      types of snprintf() calls: 'snprintf (str, cst, fmt)' and
12310      'snprintf (dest, cst, "%s", orig)'.  */
12311   if (!validate_arg (dest, POINTER_TYPE)
12312       || !validate_arg (destsize, INTEGER_TYPE)
12313       || !validate_arg (fmt, POINTER_TYPE))
12314     return NULL_TREE;
12315   if (orig && !validate_arg (orig, POINTER_TYPE))
12316     return NULL_TREE;
12317
12318   if (!host_integerp (destsize, 1))
12319     return NULL_TREE;
12320
12321   /* Check whether the format is a literal string constant.  */
12322   fmt_str = c_getstr (fmt);
12323   if (fmt_str == NULL)
12324     return NULL_TREE;
12325
12326   call = NULL_TREE;
12327   retval = NULL_TREE;
12328
12329   if (!init_target_chars ())
12330     return NULL_TREE;
12331
12332   destlen = tree_low_cst (destsize, 1);
12333
12334   /* If the format doesn't contain % args or %%, use strcpy.  */
12335   if (strchr (fmt_str, target_percent) == NULL)
12336     {
12337       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12338       size_t len = strlen (fmt_str);
12339
12340       /* Don't optimize snprintf (buf, 4, "abc", ptr++).  */
12341       if (orig)
12342         return NULL_TREE;
12343
12344       /* We could expand this as
12345          memcpy (str, fmt, cst - 1); str[cst - 1] = '\0';
12346          or to
12347          memcpy (str, fmt_with_nul_at_cstm1, cst);
12348          but in the former case that might increase code size
12349          and in the latter case grow .rodata section too much.
12350          So punt for now.  */
12351       if (len >= destlen)
12352         return NULL_TREE;
12353
12354       if (!fn)
12355         return NULL_TREE;
12356
12357       /* Convert snprintf (str, cst, fmt) into strcpy (str, fmt) when
12358          'format' is known to contain no % formats and
12359          strlen (fmt) < cst.  */
12360       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
12361
12362       if (!ignored)
12363         retval = build_int_cst (integer_type_node, strlen (fmt_str));
12364     }
12365
12366   /* If the format is "%s", use strcpy if the result isn't used.  */
12367   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
12368     {
12369       tree fn = builtin_decl_implicit (BUILT_IN_STRCPY);
12370       unsigned HOST_WIDE_INT origlen;
12371
12372       /* Don't crash on snprintf (str1, cst, "%s").  */
12373       if (!orig)
12374         return NULL_TREE;
12375
12376       retval = c_strlen (orig, 1);
12377       if (!retval || !host_integerp (retval, 1))  
12378         return NULL_TREE;
12379
12380       origlen = tree_low_cst (retval, 1);
12381       /* We could expand this as
12382          memcpy (str1, str2, cst - 1); str1[cst - 1] = '\0';
12383          or to
12384          memcpy (str1, str2_with_nul_at_cstm1, cst);
12385          but in the former case that might increase code size
12386          and in the latter case grow .rodata section too much.
12387          So punt for now.  */
12388       if (origlen >= destlen)
12389         return NULL_TREE;
12390
12391       /* Convert snprintf (str1, cst, "%s", str2) into
12392          strcpy (str1, str2) if strlen (str2) < cst.  */
12393       if (!fn)
12394         return NULL_TREE;
12395
12396       call = build_call_expr_loc (loc, fn, 2, dest, orig);
12397
12398       if (ignored)
12399         retval = NULL_TREE;
12400     }
12401
12402   if (call && retval)
12403     {
12404       tree fn = builtin_decl_explicit (BUILT_IN_SNPRINTF);
12405       retval = fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fn)), retval);
12406       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
12407     }
12408   else
12409     return call;
12410 }
12411
12412 /* Expand a call EXP to __builtin_object_size.  */
12413
12414 rtx
12415 expand_builtin_object_size (tree exp)
12416 {
12417   tree ost;
12418   int object_size_type;
12419   tree fndecl = get_callee_fndecl (exp);
12420
12421   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
12422     {
12423       error ("%Kfirst argument of %D must be a pointer, second integer constant",
12424              exp, fndecl);
12425       expand_builtin_trap ();
12426       return const0_rtx;
12427     }
12428
12429   ost = CALL_EXPR_ARG (exp, 1);
12430   STRIP_NOPS (ost);
12431
12432   if (TREE_CODE (ost) != INTEGER_CST
12433       || tree_int_cst_sgn (ost) < 0
12434       || compare_tree_int (ost, 3) > 0)
12435     {
12436       error ("%Klast argument of %D is not integer constant between 0 and 3",
12437              exp, fndecl);
12438       expand_builtin_trap ();
12439       return const0_rtx;
12440     }
12441
12442   object_size_type = tree_low_cst (ost, 0);
12443
12444   return object_size_type < 2 ? constm1_rtx : const0_rtx;
12445 }
12446
12447 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12448    FCODE is the BUILT_IN_* to use.
12449    Return NULL_RTX if we failed; the caller should emit a normal call,
12450    otherwise try to get the result in TARGET, if convenient (and in
12451    mode MODE if that's convenient).  */
12452
12453 static rtx
12454 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
12455                            enum built_in_function fcode)
12456 {
12457   tree dest, src, len, size;
12458
12459   if (!validate_arglist (exp,
12460                          POINTER_TYPE,
12461                          fcode == BUILT_IN_MEMSET_CHK
12462                          ? INTEGER_TYPE : POINTER_TYPE,
12463                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
12464     return NULL_RTX;
12465
12466   dest = CALL_EXPR_ARG (exp, 0);
12467   src = CALL_EXPR_ARG (exp, 1);
12468   len = CALL_EXPR_ARG (exp, 2);
12469   size = CALL_EXPR_ARG (exp, 3);
12470
12471   if (! host_integerp (size, 1))
12472     return NULL_RTX;
12473
12474   if (host_integerp (len, 1) || integer_all_onesp (size))
12475     {
12476       tree fn;
12477
12478       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
12479         {
12480           warning_at (tree_nonartificial_location (exp),
12481                       0, "%Kcall to %D will always overflow destination buffer",
12482                       exp, get_callee_fndecl (exp));
12483           return NULL_RTX;
12484         }
12485
12486       fn = NULL_TREE;
12487       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12488          mem{cpy,pcpy,move,set} is available.  */
12489       switch (fcode)
12490         {
12491         case BUILT_IN_MEMCPY_CHK:
12492           fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12493           break;
12494         case BUILT_IN_MEMPCPY_CHK:
12495           fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12496           break;
12497         case BUILT_IN_MEMMOVE_CHK:
12498           fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12499           break;
12500         case BUILT_IN_MEMSET_CHK:
12501           fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12502           break;
12503         default:
12504           break;
12505         }
12506
12507       if (! fn)
12508         return NULL_RTX;
12509
12510       fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 3, dest, src, len);
12511       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12512       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12513       return expand_expr (fn, target, mode, EXPAND_NORMAL);
12514     }
12515   else if (fcode == BUILT_IN_MEMSET_CHK)
12516     return NULL_RTX;
12517   else
12518     {
12519       unsigned int dest_align = get_pointer_alignment (dest);
12520
12521       /* If DEST is not a pointer type, call the normal function.  */
12522       if (dest_align == 0)
12523         return NULL_RTX;
12524
12525       /* If SRC and DEST are the same (and not volatile), do nothing.  */
12526       if (operand_equal_p (src, dest, 0))
12527         {
12528           tree expr;
12529
12530           if (fcode != BUILT_IN_MEMPCPY_CHK)
12531             {
12532               /* Evaluate and ignore LEN in case it has side-effects.  */
12533               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12534               return expand_expr (dest, target, mode, EXPAND_NORMAL);
12535             }
12536
12537           expr = fold_build_pointer_plus (dest, len);
12538           return expand_expr (expr, target, mode, EXPAND_NORMAL);
12539         }
12540
12541       /* __memmove_chk special case.  */
12542       if (fcode == BUILT_IN_MEMMOVE_CHK)
12543         {
12544           unsigned int src_align = get_pointer_alignment (src);
12545
12546           if (src_align == 0)
12547             return NULL_RTX;
12548
12549           /* If src is categorized for a readonly section we can use
12550              normal __memcpy_chk.  */
12551           if (readonly_data_expr (src))
12552             {
12553               tree fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12554               if (!fn)
12555                 return NULL_RTX;
12556               fn = build_call_nofold_loc (EXPR_LOCATION (exp), fn, 4,
12557                                           dest, src, len, size);
12558               gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12559               CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12560               return expand_expr (fn, target, mode, EXPAND_NORMAL);
12561             }
12562         }
12563       return NULL_RTX;
12564     }
12565 }
12566
12567 /* Emit warning if a buffer overflow is detected at compile time.  */
12568
12569 static void
12570 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12571 {
12572   int is_strlen = 0;
12573   tree len, size;
12574   location_t loc = tree_nonartificial_location (exp);
12575
12576   switch (fcode)
12577     {
12578     case BUILT_IN_STRCPY_CHK:
12579     case BUILT_IN_STPCPY_CHK:
12580     /* For __strcat_chk the warning will be emitted only if overflowing
12581        by at least strlen (dest) + 1 bytes.  */
12582     case BUILT_IN_STRCAT_CHK:
12583       len = CALL_EXPR_ARG (exp, 1);
12584       size = CALL_EXPR_ARG (exp, 2);
12585       is_strlen = 1;
12586       break;
12587     case BUILT_IN_STRNCAT_CHK:
12588     case BUILT_IN_STRNCPY_CHK:
12589     case BUILT_IN_STPNCPY_CHK:
12590       len = CALL_EXPR_ARG (exp, 2);
12591       size = CALL_EXPR_ARG (exp, 3);
12592       break;
12593     case BUILT_IN_SNPRINTF_CHK:
12594     case BUILT_IN_VSNPRINTF_CHK:
12595       len = CALL_EXPR_ARG (exp, 1);
12596       size = CALL_EXPR_ARG (exp, 3);
12597       break;
12598     default:
12599       gcc_unreachable ();
12600     }
12601
12602   if (!len || !size)
12603     return;
12604
12605   if (! host_integerp (size, 1) || integer_all_onesp (size))
12606     return;
12607
12608   if (is_strlen)
12609     {
12610       len = c_strlen (len, 1);
12611       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12612         return;
12613     }
12614   else if (fcode == BUILT_IN_STRNCAT_CHK)
12615     {
12616       tree src = CALL_EXPR_ARG (exp, 1);
12617       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12618         return;
12619       src = c_strlen (src, 1);
12620       if (! src || ! host_integerp (src, 1))
12621         {
12622           warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12623                       exp, get_callee_fndecl (exp));
12624           return;
12625         }
12626       else if (tree_int_cst_lt (src, size))
12627         return;
12628     }
12629   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12630     return;
12631
12632   warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12633               exp, get_callee_fndecl (exp));
12634 }
12635
12636 /* Emit warning if a buffer overflow is detected at compile time
12637    in __sprintf_chk/__vsprintf_chk calls.  */
12638
12639 static void
12640 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12641 {
12642   tree size, len, fmt;
12643   const char *fmt_str;
12644   int nargs = call_expr_nargs (exp);
12645
12646   /* Verify the required arguments in the original call.  */
12647
12648   if (nargs < 4)
12649     return;
12650   size = CALL_EXPR_ARG (exp, 2);
12651   fmt = CALL_EXPR_ARG (exp, 3);
12652
12653   if (! host_integerp (size, 1) || integer_all_onesp (size))
12654     return;
12655
12656   /* Check whether the format is a literal string constant.  */
12657   fmt_str = c_getstr (fmt);
12658   if (fmt_str == NULL)
12659     return;
12660
12661   if (!init_target_chars ())
12662     return;
12663
12664   /* If the format doesn't contain % args or %%, we know its size.  */
12665   if (strchr (fmt_str, target_percent) == 0)
12666     len = build_int_cstu (size_type_node, strlen (fmt_str));
12667   /* If the format is "%s" and first ... argument is a string literal,
12668      we know it too.  */
12669   else if (fcode == BUILT_IN_SPRINTF_CHK
12670            && strcmp (fmt_str, target_percent_s) == 0)
12671     {
12672       tree arg;
12673
12674       if (nargs < 5)
12675         return;
12676       arg = CALL_EXPR_ARG (exp, 4);
12677       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12678         return;
12679
12680       len = c_strlen (arg, 1);
12681       if (!len || ! host_integerp (len, 1))
12682         return;
12683     }
12684   else
12685     return;
12686
12687   if (! tree_int_cst_lt (len, size))
12688     warning_at (tree_nonartificial_location (exp),
12689                 0, "%Kcall to %D will always overflow destination buffer",
12690                 exp, get_callee_fndecl (exp));
12691 }
12692
12693 /* Emit warning if a free is called with address of a variable.  */
12694
12695 static void
12696 maybe_emit_free_warning (tree exp)
12697 {
12698   tree arg = CALL_EXPR_ARG (exp, 0);
12699
12700   STRIP_NOPS (arg);
12701   if (TREE_CODE (arg) != ADDR_EXPR)
12702     return;
12703
12704   arg = get_base_address (TREE_OPERAND (arg, 0));
12705   if (arg == NULL || INDIRECT_REF_P (arg) || TREE_CODE (arg) == MEM_REF)
12706     return;
12707
12708   if (SSA_VAR_P (arg))
12709     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12710                 "%Kattempt to free a non-heap object %qD", exp, arg);
12711   else
12712     warning_at (tree_nonartificial_location (exp), OPT_Wfree_nonheap_object,
12713                 "%Kattempt to free a non-heap object", exp);
12714 }
12715
12716 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12717    if possible.  */
12718
12719 tree
12720 fold_builtin_object_size (tree ptr, tree ost)
12721 {
12722   unsigned HOST_WIDE_INT bytes;
12723   int object_size_type;
12724
12725   if (!validate_arg (ptr, POINTER_TYPE)
12726       || !validate_arg (ost, INTEGER_TYPE))
12727     return NULL_TREE;
12728
12729   STRIP_NOPS (ost);
12730
12731   if (TREE_CODE (ost) != INTEGER_CST
12732       || tree_int_cst_sgn (ost) < 0
12733       || compare_tree_int (ost, 3) > 0)
12734     return NULL_TREE;
12735
12736   object_size_type = tree_low_cst (ost, 0);
12737
12738   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12739      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12740      and (size_t) 0 for types 2 and 3.  */
12741   if (TREE_SIDE_EFFECTS (ptr))
12742     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12743
12744   if (TREE_CODE (ptr) == ADDR_EXPR)
12745     {
12746       bytes = compute_builtin_object_size (ptr, object_size_type);
12747       if (double_int_fits_to_tree_p (size_type_node,
12748                                      double_int::from_uhwi (bytes)))
12749         return build_int_cstu (size_type_node, bytes);
12750     }
12751   else if (TREE_CODE (ptr) == SSA_NAME)
12752     {
12753       /* If object size is not known yet, delay folding until
12754        later.  Maybe subsequent passes will help determining
12755        it.  */
12756       bytes = compute_builtin_object_size (ptr, object_size_type);
12757       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2 ? -1 : 0)
12758           && double_int_fits_to_tree_p (size_type_node,
12759                                         double_int::from_uhwi (bytes)))
12760         return build_int_cstu (size_type_node, bytes);
12761     }
12762
12763   return NULL_TREE;
12764 }
12765
12766 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12767    DEST, SRC, LEN, and SIZE are the arguments to the call.
12768    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12769    code of the builtin.  If MAXLEN is not NULL, it is maximum length
12770    passed as third argument.  */
12771
12772 tree
12773 fold_builtin_memory_chk (location_t loc, tree fndecl,
12774                          tree dest, tree src, tree len, tree size,
12775                          tree maxlen, bool ignore,
12776                          enum built_in_function fcode)
12777 {
12778   tree fn;
12779
12780   if (!validate_arg (dest, POINTER_TYPE)
12781       || !validate_arg (src,
12782                         (fcode == BUILT_IN_MEMSET_CHK
12783                          ? INTEGER_TYPE : POINTER_TYPE))
12784       || !validate_arg (len, INTEGER_TYPE)
12785       || !validate_arg (size, INTEGER_TYPE))
12786     return NULL_TREE;
12787
12788   /* If SRC and DEST are the same (and not volatile), return DEST
12789      (resp. DEST+LEN for __mempcpy_chk).  */
12790   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12791     {
12792       if (fcode != BUILT_IN_MEMPCPY_CHK)
12793         return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12794                                  dest, len);
12795       else
12796         {
12797           tree temp = fold_build_pointer_plus_loc (loc, dest, len);
12798           return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12799         }
12800     }
12801
12802   if (! host_integerp (size, 1))
12803     return NULL_TREE;
12804
12805   if (! integer_all_onesp (size))
12806     {
12807       if (! host_integerp (len, 1))
12808         {
12809           /* If LEN is not constant, try MAXLEN too.
12810              For MAXLEN only allow optimizing into non-_ocs function
12811              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12812           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12813             {
12814               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12815                 {
12816                   /* (void) __mempcpy_chk () can be optimized into
12817                      (void) __memcpy_chk ().  */
12818                   fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12819                   if (!fn)
12820                     return NULL_TREE;
12821
12822                   return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12823                 }
12824               return NULL_TREE;
12825             }
12826         }
12827       else
12828         maxlen = len;
12829
12830       if (tree_int_cst_lt (size, maxlen))
12831         return NULL_TREE;
12832     }
12833
12834   fn = NULL_TREE;
12835   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12836      mem{cpy,pcpy,move,set} is available.  */
12837   switch (fcode)
12838     {
12839     case BUILT_IN_MEMCPY_CHK:
12840       fn = builtin_decl_explicit (BUILT_IN_MEMCPY);
12841       break;
12842     case BUILT_IN_MEMPCPY_CHK:
12843       fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);
12844       break;
12845     case BUILT_IN_MEMMOVE_CHK:
12846       fn = builtin_decl_explicit (BUILT_IN_MEMMOVE);
12847       break;
12848     case BUILT_IN_MEMSET_CHK:
12849       fn = builtin_decl_explicit (BUILT_IN_MEMSET);
12850       break;
12851     default:
12852       break;
12853     }
12854
12855   if (!fn)
12856     return NULL_TREE;
12857
12858   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12859 }
12860
12861 /* Fold a call to the __st[rp]cpy_chk builtin.
12862    DEST, SRC, and SIZE are the arguments to the call.
12863    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12864    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12865    strings passed as second argument.  */
12866
12867 tree
12868 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12869                          tree src, tree size,
12870                          tree maxlen, bool ignore,
12871                          enum built_in_function fcode)
12872 {
12873   tree len, fn;
12874
12875   if (!validate_arg (dest, POINTER_TYPE)
12876       || !validate_arg (src, POINTER_TYPE)
12877       || !validate_arg (size, INTEGER_TYPE))
12878     return NULL_TREE;
12879
12880   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12881   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12882     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12883
12884   if (! host_integerp (size, 1))
12885     return NULL_TREE;
12886
12887   if (! integer_all_onesp (size))
12888     {
12889       len = c_strlen (src, 1);
12890       if (! len || ! host_integerp (len, 1))
12891         {
12892           /* If LEN is not constant, try MAXLEN too.
12893              For MAXLEN only allow optimizing into non-_ocs function
12894              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12895           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12896             {
12897               if (fcode == BUILT_IN_STPCPY_CHK)
12898                 {
12899                   if (! ignore)
12900                     return NULL_TREE;
12901
12902                   /* If return value of __stpcpy_chk is ignored,
12903                      optimize into __strcpy_chk.  */
12904                   fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
12905                   if (!fn)
12906                     return NULL_TREE;
12907
12908                   return build_call_expr_loc (loc, fn, 3, dest, src, size);
12909                 }
12910
12911               if (! len || TREE_SIDE_EFFECTS (len))
12912                 return NULL_TREE;
12913
12914               /* If c_strlen returned something, but not a constant,
12915                  transform __strcpy_chk into __memcpy_chk.  */
12916               fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
12917               if (!fn)
12918                 return NULL_TREE;
12919
12920               len = fold_convert_loc (loc, size_type_node, len);
12921               len = size_binop_loc (loc, PLUS_EXPR, len,
12922                                     build_int_cst (size_type_node, 1));
12923               return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12924                                        build_call_expr_loc (loc, fn, 4,
12925                                                         dest, src, len, size));
12926             }
12927         }
12928       else
12929         maxlen = len;
12930
12931       if (! tree_int_cst_lt (maxlen, size))
12932         return NULL_TREE;
12933     }
12934
12935   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12936   fn = builtin_decl_explicit (fcode == BUILT_IN_STPCPY_CHK
12937                               ? BUILT_IN_STPCPY : BUILT_IN_STRCPY);
12938   if (!fn)
12939     return NULL_TREE;
12940
12941   return build_call_expr_loc (loc, fn, 2, dest, src);
12942 }
12943
12944 /* Fold a call to the __st{r,p}ncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12945    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12946    length passed as third argument. IGNORE is true if return value can be
12947    ignored. FCODE is the BUILT_IN_* code of the builtin. */
12948
12949 tree
12950 fold_builtin_stxncpy_chk (location_t loc, tree dest, tree src,
12951                           tree len, tree size, tree maxlen, bool ignore,
12952                           enum built_in_function fcode)
12953 {
12954   tree fn;
12955
12956   if (!validate_arg (dest, POINTER_TYPE)
12957       || !validate_arg (src, POINTER_TYPE)
12958       || !validate_arg (len, INTEGER_TYPE)
12959       || !validate_arg (size, INTEGER_TYPE))
12960     return NULL_TREE;
12961
12962   if (fcode == BUILT_IN_STPNCPY_CHK && ignore)
12963     {
12964        /* If return value of __stpncpy_chk is ignored,
12965           optimize into __strncpy_chk.  */
12966        fn = builtin_decl_explicit (BUILT_IN_STRNCPY_CHK);
12967        if (fn)
12968          return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12969     }
12970
12971   if (! host_integerp (size, 1))
12972     return NULL_TREE;
12973
12974   if (! integer_all_onesp (size))
12975     {
12976       if (! host_integerp (len, 1))
12977         {
12978           /* If LEN is not constant, try MAXLEN too.
12979              For MAXLEN only allow optimizing into non-_ocs function
12980              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12981           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12982             return NULL_TREE;
12983         }
12984       else
12985         maxlen = len;
12986
12987       if (tree_int_cst_lt (size, maxlen))
12988         return NULL_TREE;
12989     }
12990
12991   /* If __builtin_st{r,p}ncpy_chk is used, assume st{r,p}ncpy is available.  */
12992   fn = builtin_decl_explicit (fcode == BUILT_IN_STPNCPY_CHK
12993                               ? BUILT_IN_STPNCPY : BUILT_IN_STRNCPY);
12994   if (!fn)
12995     return NULL_TREE;
12996
12997   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12998 }
12999
13000 /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
13001    are the arguments to the call.  */
13002
13003 static tree
13004 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
13005                          tree src, tree size)
13006 {
13007   tree fn;
13008   const char *p;
13009
13010   if (!validate_arg (dest, POINTER_TYPE)
13011       || !validate_arg (src, POINTER_TYPE)
13012       || !validate_arg (size, INTEGER_TYPE))
13013     return NULL_TREE;
13014
13015   p = c_getstr (src);
13016   /* If the SRC parameter is "", return DEST.  */
13017   if (p && *p == '\0')
13018     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
13019
13020   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
13021     return NULL_TREE;
13022
13023   /* If __builtin_strcat_chk is used, assume strcat is available.  */
13024   fn = builtin_decl_explicit (BUILT_IN_STRCAT);
13025   if (!fn)
13026     return NULL_TREE;
13027
13028   return build_call_expr_loc (loc, fn, 2, dest, src);
13029 }
13030
13031 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
13032    LEN, and SIZE.  */
13033
13034 static tree
13035 fold_builtin_strncat_chk (location_t loc, tree fndecl,
13036                           tree dest, tree src, tree len, tree size)
13037 {
13038   tree fn;
13039   const char *p;
13040
13041   if (!validate_arg (dest, POINTER_TYPE)
13042       || !validate_arg (src, POINTER_TYPE)
13043       || !validate_arg (size, INTEGER_TYPE)
13044       || !validate_arg (size, INTEGER_TYPE))
13045     return NULL_TREE;
13046
13047   p = c_getstr (src);
13048   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
13049   if (p && *p == '\0')
13050     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
13051   else if (integer_zerop (len))
13052     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
13053
13054   if (! host_integerp (size, 1))
13055     return NULL_TREE;
13056
13057   if (! integer_all_onesp (size))
13058     {
13059       tree src_len = c_strlen (src, 1);
13060       if (src_len
13061           && host_integerp (src_len, 1)
13062           && host_integerp (len, 1)
13063           && ! tree_int_cst_lt (len, src_len))
13064         {
13065           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
13066           fn = builtin_decl_explicit (BUILT_IN_STRCAT_CHK);
13067           if (!fn)
13068             return NULL_TREE;
13069
13070           return build_call_expr_loc (loc, fn, 3, dest, src, size);
13071         }
13072       return NULL_TREE;
13073     }
13074
13075   /* If __builtin_strncat_chk is used, assume strncat is available.  */
13076   fn = builtin_decl_explicit (BUILT_IN_STRNCAT);
13077   if (!fn)
13078     return NULL_TREE;
13079
13080   return build_call_expr_loc (loc, fn, 3, dest, src, len);
13081 }
13082
13083 /* Fold a call EXP to __{,v}sprintf_chk having NARGS passed as ARGS.
13084    Return NULL_TREE if a normal call should be emitted rather than
13085    expanding the function inline.  FCODE is either BUILT_IN_SPRINTF_CHK
13086    or BUILT_IN_VSPRINTF_CHK.  */
13087
13088 static tree
13089 fold_builtin_sprintf_chk_1 (location_t loc, int nargs, tree *args,
13090                             enum built_in_function fcode)
13091 {
13092   tree dest, size, len, fn, fmt, flag;
13093   const char *fmt_str;
13094
13095   /* Verify the required arguments in the original call.  */
13096   if (nargs < 4)
13097     return NULL_TREE;
13098   dest = args[0];
13099   if (!validate_arg (dest, POINTER_TYPE))
13100     return NULL_TREE;
13101   flag = args[1];
13102   if (!validate_arg (flag, INTEGER_TYPE))
13103     return NULL_TREE;
13104   size = args[2];
13105   if (!validate_arg (size, INTEGER_TYPE))
13106     return NULL_TREE;
13107   fmt = args[3];
13108   if (!validate_arg (fmt, POINTER_TYPE))
13109     return NULL_TREE;
13110
13111   if (! host_integerp (size, 1))
13112     return NULL_TREE;
13113
13114   len = NULL_TREE;
13115
13116   if (!init_target_chars ())
13117     return NULL_TREE;
13118
13119   /* Check whether the format is a literal string constant.  */
13120   fmt_str = c_getstr (fmt);
13121   if (fmt_str != NULL)
13122     {
13123       /* If the format doesn't contain % args or %%, we know the size.  */
13124       if (strchr (fmt_str, target_percent) == 0)
13125         {
13126           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13127             len = build_int_cstu (size_type_node, strlen (fmt_str));
13128         }
13129       /* If the format is "%s" and first ... argument is a string literal,
13130          we know the size too.  */
13131       else if (fcode == BUILT_IN_SPRINTF_CHK
13132                && strcmp (fmt_str, target_percent_s) == 0)
13133         {
13134           tree arg;
13135
13136           if (nargs == 5)
13137             {
13138               arg = args[4];
13139               if (validate_arg (arg, POINTER_TYPE))
13140                 {
13141                   len = c_strlen (arg, 1);
13142                   if (! len || ! host_integerp (len, 1))
13143                     len = NULL_TREE;
13144                 }
13145             }
13146         }
13147     }
13148
13149   if (! integer_all_onesp (size))
13150     {
13151       if (! len || ! tree_int_cst_lt (len, size))
13152         return NULL_TREE;
13153     }
13154
13155   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13156      or if format doesn't contain % chars or is "%s".  */
13157   if (! integer_zerop (flag))
13158     {
13159       if (fmt_str == NULL)
13160         return NULL_TREE;
13161       if (strchr (fmt_str, target_percent) != NULL
13162           && strcmp (fmt_str, target_percent_s))
13163         return NULL_TREE;
13164     }
13165
13166   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13167   fn = builtin_decl_explicit (fcode == BUILT_IN_VSPRINTF_CHK
13168                               ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF);
13169   if (!fn)
13170     return NULL_TREE;
13171
13172   return rewrite_call_expr_array (loc, nargs, args, 4, fn, 2, dest, fmt);
13173 }
13174
13175 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
13176    a normal call should be emitted rather than expanding the function
13177    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13178
13179 static tree
13180 fold_builtin_sprintf_chk (location_t loc, tree exp,
13181                           enum built_in_function fcode)
13182 {
13183   return fold_builtin_sprintf_chk_1 (loc, call_expr_nargs (exp),
13184                                      CALL_EXPR_ARGP (exp), fcode);
13185 }
13186
13187 /* Fold a call EXP to {,v}snprintf having NARGS passed as ARGS.  Return
13188    NULL_TREE if a normal call should be emitted rather than expanding
13189    the function inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13190    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13191    passed as second argument.  */
13192
13193 static tree
13194 fold_builtin_snprintf_chk_1 (location_t loc, int nargs, tree *args,
13195                              tree maxlen, enum built_in_function fcode)
13196 {
13197   tree dest, size, len, fn, fmt, flag;
13198   const char *fmt_str;
13199
13200   /* Verify the required arguments in the original call.  */
13201   if (nargs < 5)
13202     return NULL_TREE;
13203   dest = args[0];
13204   if (!validate_arg (dest, POINTER_TYPE))
13205     return NULL_TREE;
13206   len = args[1];
13207   if (!validate_arg (len, INTEGER_TYPE))
13208     return NULL_TREE;
13209   flag = args[2];
13210   if (!validate_arg (flag, INTEGER_TYPE))
13211     return NULL_TREE;
13212   size = args[3];
13213   if (!validate_arg (size, INTEGER_TYPE))
13214     return NULL_TREE;
13215   fmt = args[4];
13216   if (!validate_arg (fmt, POINTER_TYPE))
13217     return NULL_TREE;
13218
13219   if (! host_integerp (size, 1))
13220     return NULL_TREE;
13221
13222   if (! integer_all_onesp (size))
13223     {
13224       if (! host_integerp (len, 1))
13225         {
13226           /* If LEN is not constant, try MAXLEN too.
13227              For MAXLEN only allow optimizing into non-_ocs function
13228              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13229           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13230             return NULL_TREE;
13231         }
13232       else
13233         maxlen = len;
13234
13235       if (tree_int_cst_lt (size, maxlen))
13236         return NULL_TREE;
13237     }
13238
13239   if (!init_target_chars ())
13240     return NULL_TREE;
13241
13242   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13243      or if format doesn't contain % chars or is "%s".  */
13244   if (! integer_zerop (flag))
13245     {
13246       fmt_str = c_getstr (fmt);
13247       if (fmt_str == NULL)
13248         return NULL_TREE;
13249       if (strchr (fmt_str, target_percent) != NULL
13250           && strcmp (fmt_str, target_percent_s))
13251         return NULL_TREE;
13252     }
13253
13254   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13255      available.  */
13256   fn = builtin_decl_explicit (fcode == BUILT_IN_VSNPRINTF_CHK
13257                               ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF);
13258   if (!fn)
13259     return NULL_TREE;
13260
13261   return rewrite_call_expr_array (loc, nargs, args, 5, fn, 3, dest, len, fmt);
13262 }
13263
13264 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
13265    a normal call should be emitted rather than expanding the function
13266    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13267    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13268    passed as second argument.  */
13269
13270 tree
13271 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
13272                            enum built_in_function fcode)
13273 {
13274   return fold_builtin_snprintf_chk_1 (loc, call_expr_nargs (exp),
13275                                       CALL_EXPR_ARGP (exp), maxlen, fcode);
13276 }
13277
13278 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
13279    FMT and ARG are the arguments to the call; we don't fold cases with
13280    more than 2 arguments, and ARG may be null if this is a 1-argument case.
13281
13282    Return NULL_TREE if no simplification was possible, otherwise return the
13283    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13284    code of the function to be simplified.  */
13285
13286 static tree
13287 fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
13288                      tree arg, bool ignore,
13289                      enum built_in_function fcode)
13290 {
13291   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
13292   const char *fmt_str = NULL;
13293
13294   /* If the return value is used, don't do the transformation.  */
13295   if (! ignore)
13296     return NULL_TREE;
13297
13298   /* Verify the required arguments in the original call.  */
13299   if (!validate_arg (fmt, POINTER_TYPE))
13300     return NULL_TREE;
13301
13302   /* Check whether the format is a literal string constant.  */
13303   fmt_str = c_getstr (fmt);
13304   if (fmt_str == NULL)
13305     return NULL_TREE;
13306
13307   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
13308     {
13309       /* If we're using an unlocked function, assume the other
13310          unlocked functions exist explicitly.  */
13311       fn_putchar = builtin_decl_explicit (BUILT_IN_PUTCHAR_UNLOCKED);
13312       fn_puts = builtin_decl_explicit (BUILT_IN_PUTS_UNLOCKED);
13313     }
13314   else
13315     {
13316       fn_putchar = builtin_decl_implicit (BUILT_IN_PUTCHAR);
13317       fn_puts = builtin_decl_implicit (BUILT_IN_PUTS);
13318     }
13319
13320   if (!init_target_chars ())
13321     return NULL_TREE;
13322
13323   if (strcmp (fmt_str, target_percent_s) == 0
13324       || strchr (fmt_str, target_percent) == NULL)
13325     {
13326       const char *str;
13327
13328       if (strcmp (fmt_str, target_percent_s) == 0)
13329         {
13330           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13331             return NULL_TREE;
13332
13333           if (!arg || !validate_arg (arg, POINTER_TYPE))
13334             return NULL_TREE;
13335
13336           str = c_getstr (arg);
13337           if (str == NULL)
13338             return NULL_TREE;
13339         }
13340       else
13341         {
13342           /* The format specifier doesn't contain any '%' characters.  */
13343           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
13344               && arg)
13345             return NULL_TREE;
13346           str = fmt_str;
13347         }
13348
13349       /* If the string was "", printf does nothing.  */
13350       if (str[0] == '\0')
13351         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13352
13353       /* If the string has length of 1, call putchar.  */
13354       if (str[1] == '\0')
13355         {
13356           /* Given printf("c"), (where c is any one character,)
13357              convert "c"[0] to an int and pass that to the replacement
13358              function.  */
13359           newarg = build_int_cst (integer_type_node, str[0]);
13360           if (fn_putchar)
13361             call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
13362         }
13363       else
13364         {
13365           /* If the string was "string\n", call puts("string").  */
13366           size_t len = strlen (str);
13367           if ((unsigned char)str[len - 1] == target_newline
13368               && (size_t) (int) len == len
13369               && (int) len > 0)
13370             {
13371               char *newstr;
13372               tree offset_node, string_cst;
13373
13374               /* Create a NUL-terminated string that's one char shorter
13375                  than the original, stripping off the trailing '\n'.  */
13376               newarg = build_string_literal (len, str);
13377               string_cst = string_constant (newarg, &offset_node);
13378               gcc_checking_assert (string_cst
13379                                    && (TREE_STRING_LENGTH (string_cst)
13380                                        == (int) len)
13381                                    && integer_zerop (offset_node)
13382                                    && (unsigned char)
13383                                       TREE_STRING_POINTER (string_cst)[len - 1]
13384                                       == target_newline);
13385               /* build_string_literal creates a new STRING_CST,
13386                  modify it in place to avoid double copying.  */
13387               newstr = CONST_CAST (char *, TREE_STRING_POINTER (string_cst));
13388               newstr[len - 1] = '\0';
13389               if (fn_puts)
13390                 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
13391             }
13392           else
13393             /* We'd like to arrange to call fputs(string,stdout) here,
13394                but we need stdout and don't have a way to get it yet.  */
13395             return NULL_TREE;
13396         }
13397     }
13398
13399   /* The other optimizations can be done only on the non-va_list variants.  */
13400   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
13401     return NULL_TREE;
13402
13403   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
13404   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
13405     {
13406       if (!arg || !validate_arg (arg, POINTER_TYPE))
13407         return NULL_TREE;
13408       if (fn_puts)
13409         call = build_call_expr_loc (loc, fn_puts, 1, arg);
13410     }
13411
13412   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
13413   else if (strcmp (fmt_str, target_percent_c) == 0)
13414     {
13415       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13416         return NULL_TREE;
13417       if (fn_putchar)
13418         call = build_call_expr_loc (loc, fn_putchar, 1, arg);
13419     }
13420
13421   if (!call)
13422     return NULL_TREE;
13423
13424   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13425 }
13426
13427 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
13428    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
13429    more than 3 arguments, and ARG may be null in the 2-argument case.
13430
13431    Return NULL_TREE if no simplification was possible, otherwise return the
13432    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
13433    code of the function to be simplified.  */
13434
13435 static tree
13436 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
13437                       tree fmt, tree arg, bool ignore,
13438                       enum built_in_function fcode)
13439 {
13440   tree fn_fputc, fn_fputs, call = NULL_TREE;
13441   const char *fmt_str = NULL;
13442
13443   /* If the return value is used, don't do the transformation.  */
13444   if (! ignore)
13445     return NULL_TREE;
13446
13447   /* Verify the required arguments in the original call.  */
13448   if (!validate_arg (fp, POINTER_TYPE))
13449     return NULL_TREE;
13450   if (!validate_arg (fmt, POINTER_TYPE))
13451     return NULL_TREE;
13452
13453   /* Check whether the format is a literal string constant.  */
13454   fmt_str = c_getstr (fmt);
13455   if (fmt_str == NULL)
13456     return NULL_TREE;
13457
13458   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
13459     {
13460       /* If we're using an unlocked function, assume the other
13461          unlocked functions exist explicitly.  */
13462       fn_fputc = builtin_decl_explicit (BUILT_IN_FPUTC_UNLOCKED);
13463       fn_fputs = builtin_decl_explicit (BUILT_IN_FPUTS_UNLOCKED);
13464     }
13465   else
13466     {
13467       fn_fputc = builtin_decl_implicit (BUILT_IN_FPUTC);
13468       fn_fputs = builtin_decl_implicit (BUILT_IN_FPUTS);
13469     }
13470
13471   if (!init_target_chars ())
13472     return NULL_TREE;
13473
13474   /* If the format doesn't contain % args or %%, use strcpy.  */
13475   if (strchr (fmt_str, target_percent) == NULL)
13476     {
13477       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
13478           && arg)
13479         return NULL_TREE;
13480
13481       /* If the format specifier was "", fprintf does nothing.  */
13482       if (fmt_str[0] == '\0')
13483         {
13484           /* If FP has side-effects, just wait until gimplification is
13485              done.  */
13486           if (TREE_SIDE_EFFECTS (fp))
13487             return NULL_TREE;
13488
13489           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
13490         }
13491
13492       /* When "string" doesn't contain %, replace all cases of
13493          fprintf (fp, string) with fputs (string, fp).  The fputs
13494          builtin will take care of special cases like length == 1.  */
13495       if (fn_fputs)
13496         call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
13497     }
13498
13499   /* The other optimizations can be done only on the non-va_list variants.  */
13500   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
13501     return NULL_TREE;
13502
13503   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
13504   else if (strcmp (fmt_str, target_percent_s) == 0)
13505     {
13506       if (!arg || !validate_arg (arg, POINTER_TYPE))
13507         return NULL_TREE;
13508       if (fn_fputs)
13509         call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
13510     }
13511
13512   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
13513   else if (strcmp (fmt_str, target_percent_c) == 0)
13514     {
13515       if (!arg || !validate_arg (arg, INTEGER_TYPE))
13516         return NULL_TREE;
13517       if (fn_fputc)
13518         call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
13519     }
13520
13521   if (!call)
13522     return NULL_TREE;
13523   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
13524 }
13525
13526 /* Initialize format string characters in the target charset.  */
13527
13528 static bool
13529 init_target_chars (void)
13530 {
13531   static bool init;
13532   if (!init)
13533     {
13534       target_newline = lang_hooks.to_target_charset ('\n');
13535       target_percent = lang_hooks.to_target_charset ('%');
13536       target_c = lang_hooks.to_target_charset ('c');
13537       target_s = lang_hooks.to_target_charset ('s');
13538       if (target_newline == 0 || target_percent == 0 || target_c == 0
13539           || target_s == 0)
13540         return false;
13541
13542       target_percent_c[0] = target_percent;
13543       target_percent_c[1] = target_c;
13544       target_percent_c[2] = '\0';
13545
13546       target_percent_s[0] = target_percent;
13547       target_percent_s[1] = target_s;
13548       target_percent_s[2] = '\0';
13549
13550       target_percent_s_newline[0] = target_percent;
13551       target_percent_s_newline[1] = target_s;
13552       target_percent_s_newline[2] = target_newline;
13553       target_percent_s_newline[3] = '\0';
13554
13555       init = true;
13556     }
13557   return true;
13558 }
13559
13560 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13561    and no overflow/underflow occurred.  INEXACT is true if M was not
13562    exactly calculated.  TYPE is the tree type for the result.  This
13563    function assumes that you cleared the MPFR flags and then
13564    calculated M to see if anything subsequently set a flag prior to
13565    entering this function.  Return NULL_TREE if any checks fail.  */
13566
13567 static tree
13568 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13569 {
13570   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13571      overflow/underflow occurred.  If -frounding-math, proceed iff the
13572      result of calling FUNC was exact.  */
13573   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13574       && (!flag_rounding_math || !inexact))
13575     {
13576       REAL_VALUE_TYPE rr;
13577
13578       real_from_mpfr (&rr, m, type, GMP_RNDN);
13579       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13580          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13581          but the mpft_t is not, then we underflowed in the
13582          conversion.  */
13583       if (real_isfinite (&rr)
13584           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13585         {
13586           REAL_VALUE_TYPE rmode;
13587
13588           real_convert (&rmode, TYPE_MODE (type), &rr);
13589           /* Proceed iff the specified mode can hold the value.  */
13590           if (real_identical (&rmode, &rr))
13591             return build_real (type, rmode);
13592         }
13593     }
13594   return NULL_TREE;
13595 }
13596
13597 /* Helper function for do_mpc_arg*().  Ensure M is a normal complex
13598    number and no overflow/underflow occurred.  INEXACT is true if M
13599    was not exactly calculated.  TYPE is the tree type for the result.
13600    This function assumes that you cleared the MPFR flags and then
13601    calculated M to see if anything subsequently set a flag prior to
13602    entering this function.  Return NULL_TREE if any checks fail, if
13603    FORCE_CONVERT is true, then bypass the checks.  */
13604
13605 static tree
13606 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13607 {
13608   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13609      overflow/underflow occurred.  If -frounding-math, proceed iff the
13610      result of calling FUNC was exact.  */
13611   if (force_convert
13612       || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13613           && !mpfr_overflow_p () && !mpfr_underflow_p ()
13614           && (!flag_rounding_math || !inexact)))
13615     {
13616       REAL_VALUE_TYPE re, im;
13617
13618       real_from_mpfr (&re, mpc_realref (m), TREE_TYPE (type), GMP_RNDN);
13619       real_from_mpfr (&im, mpc_imagref (m), TREE_TYPE (type), GMP_RNDN);
13620       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13621          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13622          but the mpft_t is not, then we underflowed in the
13623          conversion.  */
13624       if (force_convert
13625           || (real_isfinite (&re) && real_isfinite (&im)
13626               && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13627               && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13628         {
13629           REAL_VALUE_TYPE re_mode, im_mode;
13630
13631           real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13632           real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13633           /* Proceed iff the specified mode can hold the value.  */
13634           if (force_convert
13635               || (real_identical (&re_mode, &re)
13636                   && real_identical (&im_mode, &im)))
13637             return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13638                                   build_real (TREE_TYPE (type), im_mode));
13639         }
13640     }
13641   return NULL_TREE;
13642 }
13643
13644 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13645    FUNC on it and return the resulting value as a tree with type TYPE.
13646    If MIN and/or MAX are not NULL, then the supplied ARG must be
13647    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13648    acceptable values, otherwise they are not.  The mpfr precision is
13649    set to the precision of TYPE.  We assume that function FUNC returns
13650    zero if the result could be calculated exactly within the requested
13651    precision.  */
13652
13653 static tree
13654 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13655               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13656               bool inclusive)
13657 {
13658   tree result = NULL_TREE;
13659
13660   STRIP_NOPS (arg);
13661
13662   /* To proceed, MPFR must exactly represent the target floating point
13663      format, which only happens when the target base equals two.  */
13664   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13665       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13666     {
13667       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13668
13669       if (real_isfinite (ra)
13670           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13671           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13672         {
13673           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13674           const int prec = fmt->p;
13675           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13676           int inexact;
13677           mpfr_t m;
13678
13679           mpfr_init2 (m, prec);
13680           mpfr_from_real (m, ra, GMP_RNDN);
13681           mpfr_clear_flags ();
13682           inexact = func (m, m, rnd);
13683           result = do_mpfr_ckconv (m, type, inexact);
13684           mpfr_clear (m);
13685         }
13686     }
13687
13688   return result;
13689 }
13690
13691 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13692    FUNC on it and return the resulting value as a tree with type TYPE.
13693    The mpfr precision is set to the precision of TYPE.  We assume that
13694    function FUNC returns zero if the result could be calculated
13695    exactly within the requested precision.  */
13696
13697 static tree
13698 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13699               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13700 {
13701   tree result = NULL_TREE;
13702
13703   STRIP_NOPS (arg1);
13704   STRIP_NOPS (arg2);
13705
13706   /* To proceed, MPFR must exactly represent the target floating point
13707      format, which only happens when the target base equals two.  */
13708   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13709       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13710       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13711     {
13712       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13713       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13714
13715       if (real_isfinite (ra1) && real_isfinite (ra2))
13716         {
13717           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13718           const int prec = fmt->p;
13719           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13720           int inexact;
13721           mpfr_t m1, m2;
13722
13723           mpfr_inits2 (prec, m1, m2, NULL);
13724           mpfr_from_real (m1, ra1, GMP_RNDN);
13725           mpfr_from_real (m2, ra2, GMP_RNDN);
13726           mpfr_clear_flags ();
13727           inexact = func (m1, m1, m2, rnd);
13728           result = do_mpfr_ckconv (m1, type, inexact);
13729           mpfr_clears (m1, m2, NULL);
13730         }
13731     }
13732
13733   return result;
13734 }
13735
13736 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13737    FUNC on it and return the resulting value as a tree with type TYPE.
13738    The mpfr precision is set to the precision of TYPE.  We assume that
13739    function FUNC returns zero if the result could be calculated
13740    exactly within the requested precision.  */
13741
13742 static tree
13743 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13744               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13745 {
13746   tree result = NULL_TREE;
13747
13748   STRIP_NOPS (arg1);
13749   STRIP_NOPS (arg2);
13750   STRIP_NOPS (arg3);
13751
13752   /* To proceed, MPFR must exactly represent the target floating point
13753      format, which only happens when the target base equals two.  */
13754   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13755       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13756       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13757       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13758     {
13759       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13760       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13761       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13762
13763       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13764         {
13765           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13766           const int prec = fmt->p;
13767           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13768           int inexact;
13769           mpfr_t m1, m2, m3;
13770
13771           mpfr_inits2 (prec, m1, m2, m3, NULL);
13772           mpfr_from_real (m1, ra1, GMP_RNDN);
13773           mpfr_from_real (m2, ra2, GMP_RNDN);
13774           mpfr_from_real (m3, ra3, GMP_RNDN);
13775           mpfr_clear_flags ();
13776           inexact = func (m1, m1, m2, m3, rnd);
13777           result = do_mpfr_ckconv (m1, type, inexact);
13778           mpfr_clears (m1, m2, m3, NULL);
13779         }
13780     }
13781
13782   return result;
13783 }
13784
13785 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13786    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13787    If ARG_SINP and ARG_COSP are NULL then the result is returned
13788    as a complex value.
13789    The type is taken from the type of ARG and is used for setting the
13790    precision of the calculation and results.  */
13791
13792 static tree
13793 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13794 {
13795   tree const type = TREE_TYPE (arg);
13796   tree result = NULL_TREE;
13797
13798   STRIP_NOPS (arg);
13799
13800   /* To proceed, MPFR must exactly represent the target floating point
13801      format, which only happens when the target base equals two.  */
13802   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13803       && TREE_CODE (arg) == REAL_CST
13804       && !TREE_OVERFLOW (arg))
13805     {
13806       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13807
13808       if (real_isfinite (ra))
13809         {
13810           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13811           const int prec = fmt->p;
13812           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13813           tree result_s, result_c;
13814           int inexact;
13815           mpfr_t m, ms, mc;
13816
13817           mpfr_inits2 (prec, m, ms, mc, NULL);
13818           mpfr_from_real (m, ra, GMP_RNDN);
13819           mpfr_clear_flags ();
13820           inexact = mpfr_sin_cos (ms, mc, m, rnd);
13821           result_s = do_mpfr_ckconv (ms, type, inexact);
13822           result_c = do_mpfr_ckconv (mc, type, inexact);
13823           mpfr_clears (m, ms, mc, NULL);
13824           if (result_s && result_c)
13825             {
13826               /* If we are to return in a complex value do so.  */
13827               if (!arg_sinp && !arg_cosp)
13828                 return build_complex (build_complex_type (type),
13829                                       result_c, result_s);
13830
13831               /* Dereference the sin/cos pointer arguments.  */
13832               arg_sinp = build_fold_indirect_ref (arg_sinp);
13833               arg_cosp = build_fold_indirect_ref (arg_cosp);
13834               /* Proceed if valid pointer type were passed in.  */
13835               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13836                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13837                 {
13838                   /* Set the values. */
13839                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13840                                           result_s);
13841                   TREE_SIDE_EFFECTS (result_s) = 1;
13842                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13843                                           result_c);
13844                   TREE_SIDE_EFFECTS (result_c) = 1;
13845                   /* Combine the assignments into a compound expr.  */
13846                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13847                                                     result_s, result_c));
13848                 }
13849             }
13850         }
13851     }
13852   return result;
13853 }
13854
13855 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13856    two-argument mpfr order N Bessel function FUNC on them and return
13857    the resulting value as a tree with type TYPE.  The mpfr precision
13858    is set to the precision of TYPE.  We assume that function FUNC
13859    returns zero if the result could be calculated exactly within the
13860    requested precision.  */
13861 static tree
13862 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13863                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13864                   const REAL_VALUE_TYPE *min, bool inclusive)
13865 {
13866   tree result = NULL_TREE;
13867
13868   STRIP_NOPS (arg1);
13869   STRIP_NOPS (arg2);
13870
13871   /* To proceed, MPFR must exactly represent the target floating point
13872      format, which only happens when the target base equals two.  */
13873   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13874       && host_integerp (arg1, 0)
13875       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13876     {
13877       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13878       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13879
13880       if (n == (long)n
13881           && real_isfinite (ra)
13882           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13883         {
13884           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13885           const int prec = fmt->p;
13886           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13887           int inexact;
13888           mpfr_t m;
13889
13890           mpfr_init2 (m, prec);
13891           mpfr_from_real (m, ra, GMP_RNDN);
13892           mpfr_clear_flags ();
13893           inexact = func (m, n, m, rnd);
13894           result = do_mpfr_ckconv (m, type, inexact);
13895           mpfr_clear (m);
13896         }
13897     }
13898
13899   return result;
13900 }
13901
13902 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13903    the pointer *(ARG_QUO) and return the result.  The type is taken
13904    from the type of ARG0 and is used for setting the precision of the
13905    calculation and results.  */
13906
13907 static tree
13908 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13909 {
13910   tree const type = TREE_TYPE (arg0);
13911   tree result = NULL_TREE;
13912
13913   STRIP_NOPS (arg0);
13914   STRIP_NOPS (arg1);
13915
13916   /* To proceed, MPFR must exactly represent the target floating point
13917      format, which only happens when the target base equals two.  */
13918   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13919       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13920       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13921     {
13922       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13923       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13924
13925       if (real_isfinite (ra0) && real_isfinite (ra1))
13926         {
13927           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13928           const int prec = fmt->p;
13929           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13930           tree result_rem;
13931           long integer_quo;
13932           mpfr_t m0, m1;
13933
13934           mpfr_inits2 (prec, m0, m1, NULL);
13935           mpfr_from_real (m0, ra0, GMP_RNDN);
13936           mpfr_from_real (m1, ra1, GMP_RNDN);
13937           mpfr_clear_flags ();
13938           mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13939           /* Remquo is independent of the rounding mode, so pass
13940              inexact=0 to do_mpfr_ckconv().  */
13941           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13942           mpfr_clears (m0, m1, NULL);
13943           if (result_rem)
13944             {
13945               /* MPFR calculates quo in the host's long so it may
13946                  return more bits in quo than the target int can hold
13947                  if sizeof(host long) > sizeof(target int).  This can
13948                  happen even for native compilers in LP64 mode.  In
13949                  these cases, modulo the quo value with the largest
13950                  number that the target int can hold while leaving one
13951                  bit for the sign.  */
13952               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13953                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13954
13955               /* Dereference the quo pointer argument.  */
13956               arg_quo = build_fold_indirect_ref (arg_quo);
13957               /* Proceed iff a valid pointer type was passed in.  */
13958               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13959                 {
13960                   /* Set the value. */
13961                   tree result_quo
13962                     = fold_build2 (MODIFY_EXPR, TREE_TYPE (arg_quo), arg_quo,
13963                                    build_int_cst (TREE_TYPE (arg_quo),
13964                                                   integer_quo));
13965                   TREE_SIDE_EFFECTS (result_quo) = 1;
13966                   /* Combine the quo assignment with the rem.  */
13967                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13968                                                     result_quo, result_rem));
13969                 }
13970             }
13971         }
13972     }
13973   return result;
13974 }
13975
13976 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13977    resulting value as a tree with type TYPE.  The mpfr precision is
13978    set to the precision of TYPE.  We assume that this mpfr function
13979    returns zero if the result could be calculated exactly within the
13980    requested precision.  In addition, the integer pointer represented
13981    by ARG_SG will be dereferenced and set to the appropriate signgam
13982    (-1,1) value.  */
13983
13984 static tree
13985 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13986 {
13987   tree result = NULL_TREE;
13988
13989   STRIP_NOPS (arg);
13990
13991   /* To proceed, MPFR must exactly represent the target floating point
13992      format, which only happens when the target base equals two.  Also
13993      verify ARG is a constant and that ARG_SG is an int pointer.  */
13994   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13995       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13996       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13997       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13998     {
13999       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
14000
14001       /* In addition to NaN and Inf, the argument cannot be zero or a
14002          negative integer.  */
14003       if (real_isfinite (ra)
14004           && ra->cl != rvc_zero
14005           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
14006         {
14007           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
14008           const int prec = fmt->p;
14009           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
14010           int inexact, sg;
14011           mpfr_t m;
14012           tree result_lg;
14013
14014           mpfr_init2 (m, prec);
14015           mpfr_from_real (m, ra, GMP_RNDN);
14016           mpfr_clear_flags ();
14017           inexact = mpfr_lgamma (m, &sg, m, rnd);
14018           result_lg = do_mpfr_ckconv (m, type, inexact);
14019           mpfr_clear (m);
14020           if (result_lg)
14021             {
14022               tree result_sg;
14023
14024               /* Dereference the arg_sg pointer argument.  */
14025               arg_sg = build_fold_indirect_ref (arg_sg);
14026               /* Assign the signgam value into *arg_sg. */
14027               result_sg = fold_build2 (MODIFY_EXPR,
14028                                        TREE_TYPE (arg_sg), arg_sg,
14029                                        build_int_cst (TREE_TYPE (arg_sg), sg));
14030               TREE_SIDE_EFFECTS (result_sg) = 1;
14031               /* Combine the signgam assignment with the lgamma result.  */
14032               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
14033                                                 result_sg, result_lg));
14034             }
14035         }
14036     }
14037
14038   return result;
14039 }
14040
14041 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc
14042    function FUNC on it and return the resulting value as a tree with
14043    type TYPE.  The mpfr precision is set to the precision of TYPE.  We
14044    assume that function FUNC returns zero if the result could be
14045    calculated exactly within the requested precision.  */
14046
14047 static tree
14048 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
14049 {
14050   tree result = NULL_TREE;
14051
14052   STRIP_NOPS (arg);
14053
14054   /* To proceed, MPFR must exactly represent the target floating point
14055      format, which only happens when the target base equals two.  */
14056   if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
14057       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
14058       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
14059     {
14060       const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
14061       const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
14062
14063       if (real_isfinite (re) && real_isfinite (im))
14064         {
14065           const struct real_format *const fmt =
14066             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14067           const int prec = fmt->p;
14068           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14069           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14070           int inexact;
14071           mpc_t m;
14072
14073           mpc_init2 (m, prec);
14074           mpfr_from_real (mpc_realref(m), re, rnd);
14075           mpfr_from_real (mpc_imagref(m), im, rnd);
14076           mpfr_clear_flags ();
14077           inexact = func (m, m, crnd);
14078           result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
14079           mpc_clear (m);
14080         }
14081     }
14082
14083   return result;
14084 }
14085
14086 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
14087    mpc function FUNC on it and return the resulting value as a tree
14088    with type TYPE.  The mpfr precision is set to the precision of
14089    TYPE.  We assume that function FUNC returns zero if the result
14090    could be calculated exactly within the requested precision.  If
14091    DO_NONFINITE is true, then fold expressions containing Inf or NaN
14092    in the arguments and/or results.  */
14093
14094 tree
14095 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
14096              int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
14097 {
14098   tree result = NULL_TREE;
14099
14100   STRIP_NOPS (arg0);
14101   STRIP_NOPS (arg1);
14102
14103   /* To proceed, MPFR must exactly represent the target floating point
14104      format, which only happens when the target base equals two.  */
14105   if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
14106       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
14107       && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
14108       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
14109       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
14110     {
14111       const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
14112       const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
14113       const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
14114       const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
14115
14116       if (do_nonfinite
14117           || (real_isfinite (re0) && real_isfinite (im0)
14118               && real_isfinite (re1) && real_isfinite (im1)))
14119         {
14120           const struct real_format *const fmt =
14121             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
14122           const int prec = fmt->p;
14123           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
14124           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
14125           int inexact;
14126           mpc_t m0, m1;
14127
14128           mpc_init2 (m0, prec);
14129           mpc_init2 (m1, prec);
14130           mpfr_from_real (mpc_realref(m0), re0, rnd);
14131           mpfr_from_real (mpc_imagref(m0), im0, rnd);
14132           mpfr_from_real (mpc_realref(m1), re1, rnd);
14133           mpfr_from_real (mpc_imagref(m1), im1, rnd);
14134           mpfr_clear_flags ();
14135           inexact = func (m0, m0, m1, crnd);
14136           result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
14137           mpc_clear (m0);
14138           mpc_clear (m1);
14139         }
14140     }
14141
14142   return result;
14143 }
14144
14145 /* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
14146    a normal call should be emitted rather than expanding the function
14147    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
14148
14149 static tree
14150 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
14151 {
14152   int nargs = gimple_call_num_args (stmt);
14153
14154   return fold_builtin_sprintf_chk_1 (gimple_location (stmt), nargs,
14155                                      (nargs > 0
14156                                       ? gimple_call_arg_ptr (stmt, 0)
14157                                       : &error_mark_node), fcode);
14158 }
14159
14160 /* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
14161    a normal call should be emitted rather than expanding the function
14162    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
14163    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
14164    passed as second argument.  */
14165
14166 tree
14167 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
14168                                   enum built_in_function fcode)
14169 {
14170   int nargs = gimple_call_num_args (stmt);
14171
14172   return fold_builtin_snprintf_chk_1 (gimple_location (stmt), nargs,
14173                                       (nargs > 0
14174                                        ? gimple_call_arg_ptr (stmt, 0)
14175                                        : &error_mark_node), maxlen, fcode);
14176 }
14177
14178 /* Builtins with folding operations that operate on "..." arguments
14179    need special handling; we need to store the arguments in a convenient
14180    data structure before attempting any folding.  Fortunately there are
14181    only a few builtins that fall into this category.  FNDECL is the
14182    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
14183    result of the function call is ignored.  */
14184
14185 static tree
14186 gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
14187                              bool ignore ATTRIBUTE_UNUSED)
14188 {
14189   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
14190   tree ret = NULL_TREE;
14191
14192   switch (fcode)
14193     {
14194     case BUILT_IN_SPRINTF_CHK:
14195     case BUILT_IN_VSPRINTF_CHK:
14196       ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
14197       break;
14198
14199     case BUILT_IN_SNPRINTF_CHK:
14200     case BUILT_IN_VSNPRINTF_CHK:
14201       ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
14202
14203     default:
14204       break;
14205     }
14206   if (ret)
14207     {
14208       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
14209       TREE_NO_WARNING (ret) = 1;
14210       return ret;
14211     }
14212   return NULL_TREE;
14213 }
14214
14215 /* A wrapper function for builtin folding that prevents warnings for
14216    "statement without effect" and the like, caused by removing the
14217    call node earlier than the warning is generated.  */
14218
14219 tree
14220 fold_call_stmt (gimple stmt, bool ignore)
14221 {
14222   tree ret = NULL_TREE;
14223   tree fndecl = gimple_call_fndecl (stmt);
14224   location_t loc = gimple_location (stmt);
14225   if (fndecl
14226       && TREE_CODE (fndecl) == FUNCTION_DECL
14227       && DECL_BUILT_IN (fndecl)
14228       && !gimple_call_va_arg_pack_p (stmt))
14229     {
14230       int nargs = gimple_call_num_args (stmt);
14231       tree *args = (nargs > 0
14232                     ? gimple_call_arg_ptr (stmt, 0)
14233                     : &error_mark_node);
14234
14235       if (avoid_folding_inline_builtin (fndecl))
14236         return NULL_TREE;
14237       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
14238         {
14239           return targetm.fold_builtin (fndecl, nargs, args, ignore);
14240         }
14241       else
14242         {
14243           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
14244             ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
14245           if (!ret)
14246             ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
14247           if (ret)
14248             {
14249               /* Propagate location information from original call to
14250                  expansion of builtin.  Otherwise things like
14251                  maybe_emit_chk_warning, that operate on the expansion
14252                  of a builtin, will use the wrong location information.  */
14253               if (gimple_has_location (stmt))
14254                 {
14255                   tree realret = ret;
14256                   if (TREE_CODE (ret) == NOP_EXPR)
14257                     realret = TREE_OPERAND (ret, 0);
14258                   if (CAN_HAVE_LOCATION_P (realret)
14259                       && !EXPR_HAS_LOCATION (realret))
14260                     SET_EXPR_LOCATION (realret, loc);
14261                   return realret;
14262                 }
14263               return ret;
14264             }
14265         }
14266     }
14267   return NULL_TREE;
14268 }
14269
14270 /* Look up the function in builtin_decl that corresponds to DECL
14271    and set ASMSPEC as its user assembler name.  DECL must be a
14272    function decl that declares a builtin.  */
14273
14274 void
14275 set_builtin_user_assembler_name (tree decl, const char *asmspec)
14276 {
14277   tree builtin;
14278   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
14279               && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
14280               && asmspec != 0);
14281
14282   builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
14283   set_user_assembler_name (builtin, asmspec);
14284   switch (DECL_FUNCTION_CODE (decl))
14285     {
14286     case BUILT_IN_MEMCPY:
14287       init_block_move_fn (asmspec);
14288       memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
14289       break;
14290     case BUILT_IN_MEMSET:
14291       init_block_clear_fn (asmspec);
14292       memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
14293       break;
14294     case BUILT_IN_MEMMOVE:
14295       memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
14296       break;
14297     case BUILT_IN_MEMCMP:
14298       memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
14299       break;
14300     case BUILT_IN_ABORT:
14301       abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
14302       break;
14303     case BUILT_IN_FFS:
14304       if (INT_TYPE_SIZE < BITS_PER_WORD)
14305         {
14306           set_user_assembler_libfunc ("ffs", asmspec);
14307           set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
14308                                                        MODE_INT, 0), "ffs");
14309         }
14310       break;
14311     default:
14312       break;
14313     }
14314 }
14315
14316 /* Return true if DECL is a builtin that expands to a constant or similarly
14317    simple code.  */
14318 bool
14319 is_simple_builtin (tree decl)
14320 {
14321   if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14322     switch (DECL_FUNCTION_CODE (decl))
14323       {
14324         /* Builtins that expand to constants.  */
14325       case BUILT_IN_CONSTANT_P:
14326       case BUILT_IN_EXPECT:
14327       case BUILT_IN_OBJECT_SIZE:
14328       case BUILT_IN_UNREACHABLE:
14329         /* Simple register moves or loads from stack.  */
14330       case BUILT_IN_ASSUME_ALIGNED:
14331       case BUILT_IN_RETURN_ADDRESS:
14332       case BUILT_IN_EXTRACT_RETURN_ADDR:
14333       case BUILT_IN_FROB_RETURN_ADDR:
14334       case BUILT_IN_RETURN:
14335       case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
14336       case BUILT_IN_FRAME_ADDRESS:
14337       case BUILT_IN_VA_END:
14338       case BUILT_IN_STACK_SAVE:
14339       case BUILT_IN_STACK_RESTORE:
14340         /* Exception state returns or moves registers around.  */
14341       case BUILT_IN_EH_FILTER:
14342       case BUILT_IN_EH_POINTER:
14343       case BUILT_IN_EH_COPY_VALUES:
14344         return true;
14345
14346       default:
14347         return false;
14348       }
14349
14350   return false;
14351 }
14352
14353 /* Return true if DECL is a builtin that is not expensive, i.e., they are
14354    most probably expanded inline into reasonably simple code.  This is a
14355    superset of is_simple_builtin.  */
14356 bool
14357 is_inexpensive_builtin (tree decl)
14358 {
14359   if (!decl)
14360     return false;
14361   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
14362     return true;
14363   else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
14364     switch (DECL_FUNCTION_CODE (decl))
14365       {
14366       case BUILT_IN_ABS:
14367       case BUILT_IN_ALLOCA:
14368       case BUILT_IN_ALLOCA_WITH_ALIGN:
14369       case BUILT_IN_BSWAP16:
14370       case BUILT_IN_BSWAP32:
14371       case BUILT_IN_BSWAP64:
14372       case BUILT_IN_CLZ:
14373       case BUILT_IN_CLZIMAX:
14374       case BUILT_IN_CLZL:
14375       case BUILT_IN_CLZLL:
14376       case BUILT_IN_CTZ:
14377       case BUILT_IN_CTZIMAX:
14378       case BUILT_IN_CTZL:
14379       case BUILT_IN_CTZLL:
14380       case BUILT_IN_FFS:
14381       case BUILT_IN_FFSIMAX:
14382       case BUILT_IN_FFSL:
14383       case BUILT_IN_FFSLL:
14384       case BUILT_IN_IMAXABS:
14385       case BUILT_IN_FINITE:
14386       case BUILT_IN_FINITEF:
14387       case BUILT_IN_FINITEL:
14388       case BUILT_IN_FINITED32:
14389       case BUILT_IN_FINITED64:
14390       case BUILT_IN_FINITED128:
14391       case BUILT_IN_FPCLASSIFY:
14392       case BUILT_IN_ISFINITE:
14393       case BUILT_IN_ISINF_SIGN:
14394       case BUILT_IN_ISINF:
14395       case BUILT_IN_ISINFF:
14396       case BUILT_IN_ISINFL:
14397       case BUILT_IN_ISINFD32:
14398       case BUILT_IN_ISINFD64:
14399       case BUILT_IN_ISINFD128:
14400       case BUILT_IN_ISNAN:
14401       case BUILT_IN_ISNANF:
14402       case BUILT_IN_ISNANL:
14403       case BUILT_IN_ISNAND32:
14404       case BUILT_IN_ISNAND64:
14405       case BUILT_IN_ISNAND128:
14406       case BUILT_IN_ISNORMAL:
14407       case BUILT_IN_ISGREATER:
14408       case BUILT_IN_ISGREATEREQUAL:
14409       case BUILT_IN_ISLESS:
14410       case BUILT_IN_ISLESSEQUAL:
14411       case BUILT_IN_ISLESSGREATER:
14412       case BUILT_IN_ISUNORDERED:
14413       case BUILT_IN_VA_ARG_PACK:
14414       case BUILT_IN_VA_ARG_PACK_LEN:
14415       case BUILT_IN_VA_COPY:
14416       case BUILT_IN_TRAP:
14417       case BUILT_IN_SAVEREGS:
14418       case BUILT_IN_POPCOUNTL:
14419       case BUILT_IN_POPCOUNTLL:
14420       case BUILT_IN_POPCOUNTIMAX:
14421       case BUILT_IN_POPCOUNT:
14422       case BUILT_IN_PARITYL:
14423       case BUILT_IN_PARITYLL:
14424       case BUILT_IN_PARITYIMAX:
14425       case BUILT_IN_PARITY:
14426       case BUILT_IN_LABS:
14427       case BUILT_IN_LLABS:
14428       case BUILT_IN_PREFETCH:
14429         return true;
14430
14431       default:
14432         return is_simple_builtin (decl);
14433       }
14434
14435   return false;
14436 }