OSDN Git Service

30bcdf817509070df9695a012a844d937bb98158
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4    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 "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-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 "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #include "tree-mudflap.h"
50 #include "tree-flow.h"
51 #include "value-prof.h"
52 #include "diagnostic.h"
53
54 #ifndef PAD_VARARGS_DOWN
55 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
56 #endif
57
58 /* Define the names of the builtin function types and codes.  */
59 const char *const built_in_class_names[4]
60   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
61
62 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
63 const char * built_in_names[(int) END_BUILTINS] =
64 {
65 #include "builtins.def"
66 };
67 #undef DEF_BUILTIN
68
69 /* Setup an array of _DECL trees, make sure each element is
70    initialized to NULL_TREE.  */
71 tree built_in_decls[(int) END_BUILTINS];
72 /* Declarations used when constructing the builtin implicitly in the compiler.
73    It may be NULL_TREE when this is invalid (for instance runtime is not
74    required to implement the function call in all cases).  */
75 tree implicit_built_in_decls[(int) END_BUILTINS];
76
77 static const char *c_getstr (tree);
78 static rtx c_readstr (const char *, enum machine_mode);
79 static int target_char_cast (tree, char *);
80 static rtx get_memory_rtx (tree, tree);
81 static int apply_args_size (void);
82 static int apply_result_size (void);
83 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
84 static rtx result_vector (int, rtx);
85 #endif
86 static void expand_builtin_update_setjmp_buf (rtx);
87 static void expand_builtin_prefetch (tree);
88 static rtx expand_builtin_apply_args (void);
89 static rtx expand_builtin_apply_args_1 (void);
90 static rtx expand_builtin_apply (rtx, rtx, rtx);
91 static void expand_builtin_return (rtx);
92 static enum type_class type_to_class (tree);
93 static rtx expand_builtin_classify_type (tree);
94 static void expand_errno_check (tree, rtx);
95 static rtx expand_builtin_mathfn (tree, rtx, rtx);
96 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
97 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
98 static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
99 static rtx expand_builtin_sincos (tree);
100 static rtx expand_builtin_cexpi (tree, rtx, rtx);
101 static rtx expand_builtin_int_roundingfn (tree, rtx, rtx);
102 static rtx expand_builtin_int_roundingfn_2 (tree, rtx, rtx);
103 static rtx expand_builtin_args_info (tree);
104 static rtx expand_builtin_next_arg (void);
105 static rtx expand_builtin_va_start (tree);
106 static rtx expand_builtin_va_end (tree);
107 static rtx expand_builtin_va_copy (tree);
108 static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
109 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
110 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
111 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
112 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
113 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
114 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx, 
120                                         enum machine_mode, int);
121 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
122 static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx, 
123                                         enum machine_mode, int);
124 static rtx expand_builtin_bcopy (tree, int);
125 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
127 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
128 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
129 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
130 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
131 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
132 static rtx expand_builtin_bzero (tree);
133 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
134 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
136 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
137 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
138 static rtx expand_builtin_alloca (tree, rtx);
139 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
140 static rtx expand_builtin_frame_address (tree, tree);
141 static rtx expand_builtin_fputs (tree, rtx, bool);
142 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
143 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
144 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
145 static tree stabilize_va_list (tree, int);
146 static rtx expand_builtin_expect (tree, rtx);
147 static tree fold_builtin_constant_p (tree);
148 static tree fold_builtin_expect (tree, tree);
149 static tree fold_builtin_classify_type (tree);
150 static tree fold_builtin_strlen (tree);
151 static tree fold_builtin_inf (tree, int);
152 static tree fold_builtin_nan (tree, tree, int);
153 static tree rewrite_call_expr (tree, int, tree, int, ...);
154 static bool validate_arg (const_tree, enum tree_code code);
155 static bool integer_valued_real_p (tree);
156 static tree fold_trunc_transparent_mathfn (tree, tree);
157 static bool readonly_data_expr (tree);
158 static rtx expand_builtin_fabs (tree, rtx, rtx);
159 static rtx expand_builtin_signbit (tree, rtx);
160 static tree fold_builtin_sqrt (tree, tree);
161 static tree fold_builtin_cbrt (tree, tree);
162 static tree fold_builtin_pow (tree, tree, tree, tree);
163 static tree fold_builtin_powi (tree, tree, tree, tree);
164 static tree fold_builtin_cos (tree, tree, tree);
165 static tree fold_builtin_cosh (tree, tree, tree);
166 static tree fold_builtin_tan (tree, tree);
167 static tree fold_builtin_trunc (tree, tree);
168 static tree fold_builtin_floor (tree, tree);
169 static tree fold_builtin_ceil (tree, tree);
170 static tree fold_builtin_round (tree, tree);
171 static tree fold_builtin_int_roundingfn (tree, tree);
172 static tree fold_builtin_bitop (tree, tree);
173 static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
174 static tree fold_builtin_strchr (tree, tree, tree);
175 static tree fold_builtin_memchr (tree, tree, tree, tree);
176 static tree fold_builtin_memcmp (tree, tree, tree);
177 static tree fold_builtin_strcmp (tree, tree);
178 static tree fold_builtin_strncmp (tree, tree, tree);
179 static tree fold_builtin_signbit (tree, tree);
180 static tree fold_builtin_copysign (tree, tree, tree, tree);
181 static tree fold_builtin_isascii (tree);
182 static tree fold_builtin_toascii (tree);
183 static tree fold_builtin_isdigit (tree);
184 static tree fold_builtin_fabs (tree, tree);
185 static tree fold_builtin_abs (tree, tree);
186 static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
187                                         enum tree_code);
188 static tree fold_builtin_n (tree, tree *, int, bool);
189 static tree fold_builtin_0 (tree, bool);
190 static tree fold_builtin_1 (tree, tree, bool);
191 static tree fold_builtin_2 (tree, tree, tree, bool);
192 static tree fold_builtin_3 (tree, tree, tree, tree, bool);
193 static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
194 static tree fold_builtin_varargs (tree, tree, bool);
195
196 static tree fold_builtin_strpbrk (tree, tree, tree);
197 static tree fold_builtin_strstr (tree, tree, tree);
198 static tree fold_builtin_strrchr (tree, tree, tree);
199 static tree fold_builtin_strcat (tree, tree);
200 static tree fold_builtin_strncat (tree, tree, tree);
201 static tree fold_builtin_strspn (tree, tree);
202 static tree fold_builtin_strcspn (tree, tree);
203 static tree fold_builtin_sprintf (tree, tree, tree, int);
204
205 static rtx expand_builtin_object_size (tree);
206 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
207                                       enum built_in_function);
208 static void maybe_emit_chk_warning (tree, enum built_in_function);
209 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
210 static tree fold_builtin_object_size (tree, tree);
211 static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
212 static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
213 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
214 static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
215 static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
216                                   enum built_in_function);
217 static bool init_target_chars (void);
218
219 static unsigned HOST_WIDE_INT target_newline;
220 static unsigned HOST_WIDE_INT target_percent;
221 static unsigned HOST_WIDE_INT target_c;
222 static unsigned HOST_WIDE_INT target_s;
223 static char target_percent_c[3];
224 static char target_percent_s[3];
225 static char target_percent_s_newline[4];
226 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
227                           const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
228 static tree do_mpfr_arg2 (tree, tree, tree,
229                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
230 static tree do_mpfr_arg3 (tree, tree, tree, tree,
231                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
232 static tree do_mpfr_sincos (tree, tree, tree);
233 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
234 static tree do_mpfr_bessel_n (tree, tree, tree,
235                               int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
236                               const REAL_VALUE_TYPE *, bool);
237 static tree do_mpfr_remquo (tree, tree, tree);
238 static tree do_mpfr_lgamma_r (tree, tree, tree);
239 #endif
240
241 /* Return true if NODE should be considered for inline expansion regardless
242    of the optimization level.  This means whenever a function is invoked with
243    its "internal" name, which normally contains the prefix "__builtin".  */
244
245 static bool called_as_built_in (tree node)
246 {
247   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
248   if (strncmp (name, "__builtin_", 10) == 0)
249     return true;
250   if (strncmp (name, "__sync_", 7) == 0)
251     return true;
252   return false;
253 }
254
255 /* Return the alignment in bits of EXP, a pointer valued expression.
256    But don't return more than MAX_ALIGN no matter what.
257    The alignment returned is, by default, the alignment of the thing that
258    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
259
260    Otherwise, look at the expression to see if we can do better, i.e., if the
261    expression is actually pointing at an object whose alignment is tighter.  */
262
263 int
264 get_pointer_alignment (tree exp, unsigned int max_align)
265 {
266   unsigned int align, inner;
267
268   /* We rely on TER to compute accurate alignment information.  */
269   if (!(optimize && flag_tree_ter))
270     return 0;
271
272   if (!POINTER_TYPE_P (TREE_TYPE (exp)))
273     return 0;
274
275   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
276   align = MIN (align, max_align);
277
278   while (1)
279     {
280       switch (TREE_CODE (exp))
281         {
282         CASE_CONVERT:
283           exp = TREE_OPERAND (exp, 0);
284           if (! POINTER_TYPE_P (TREE_TYPE (exp)))
285             return align;
286
287           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
288           align = MIN (inner, max_align);
289           break;
290
291         case POINTER_PLUS_EXPR:
292           /* If sum of pointer + int, restrict our maximum alignment to that
293              imposed by the integer.  If not, we can't do any better than
294              ALIGN.  */
295           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
296             return align;
297
298           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
299                   & (max_align / BITS_PER_UNIT - 1))
300                  != 0)
301             max_align >>= 1;
302
303           exp = TREE_OPERAND (exp, 0);
304           break;
305
306         case ADDR_EXPR:
307           /* See what we are pointing at and look at its alignment.  */
308           exp = TREE_OPERAND (exp, 0);
309           inner = max_align;
310           if (handled_component_p (exp))
311             {
312               HOST_WIDE_INT bitsize, bitpos;
313               tree offset;
314               enum machine_mode mode; 
315               int unsignedp, volatilep;
316
317               exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
318                                          &mode, &unsignedp, &volatilep, true);
319               if (bitpos)
320                 inner = MIN (inner, (unsigned) (bitpos & -bitpos));
321               if (offset && TREE_CODE (offset) == PLUS_EXPR
322                   && host_integerp (TREE_OPERAND (offset, 1), 1))
323                 {
324                   /* Any overflow in calculating offset_bits won't change
325                      the alignment.  */
326                   unsigned offset_bits
327                     = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
328                        * BITS_PER_UNIT);
329
330                   if (offset_bits)
331                     inner = MIN (inner, (offset_bits & -offset_bits));
332                   offset = TREE_OPERAND (offset, 0);
333                 }
334               if (offset && TREE_CODE (offset) == MULT_EXPR
335                   && host_integerp (TREE_OPERAND (offset, 1), 1))
336                 {
337                   /* Any overflow in calculating offset_factor won't change
338                      the alignment.  */
339                   unsigned offset_factor
340                     = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
341                        * BITS_PER_UNIT);
342
343                   if (offset_factor)
344                     inner = MIN (inner, (offset_factor & -offset_factor));
345                 }
346               else if (offset)
347                 inner = MIN (inner, BITS_PER_UNIT);
348             }
349           if (DECL_P (exp))
350             align = MIN (inner, DECL_ALIGN (exp));
351 #ifdef CONSTANT_ALIGNMENT
352           else if (CONSTANT_CLASS_P (exp))
353             align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
354 #endif
355           else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
356                    || TREE_CODE (exp) == INDIRECT_REF)
357             align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
358           else
359             align = MIN (align, inner);
360           return MIN (align, max_align);
361
362         default:
363           return align;
364         }
365     }
366 }
367
368 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
369    way, because it could contain a zero byte in the middle.
370    TREE_STRING_LENGTH is the size of the character array, not the string.
371
372    ONLY_VALUE should be nonzero if the result is not going to be emitted
373    into the instruction stream and zero if it is going to be expanded.
374    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
375    is returned, otherwise NULL, since
376    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
377    evaluate the side-effects.
378
379    The value returned is of type `ssizetype'.
380
381    Unfortunately, string_constant can't access the values of const char
382    arrays with initializers, so neither can we do so here.  */
383
384 tree
385 c_strlen (tree src, int only_value)
386 {
387   tree offset_node;
388   HOST_WIDE_INT offset;
389   int max;
390   const char *ptr;
391
392   STRIP_NOPS (src);
393   if (TREE_CODE (src) == COND_EXPR
394       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
395     {
396       tree len1, len2;
397
398       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
399       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
400       if (tree_int_cst_equal (len1, len2))
401         return len1;
402     }
403
404   if (TREE_CODE (src) == COMPOUND_EXPR
405       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
406     return c_strlen (TREE_OPERAND (src, 1), only_value);
407
408   src = string_constant (src, &offset_node);
409   if (src == 0)
410     return NULL_TREE;
411
412   max = TREE_STRING_LENGTH (src) - 1;
413   ptr = TREE_STRING_POINTER (src);
414
415   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
416     {
417       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
418          compute the offset to the following null if we don't know where to
419          start searching for it.  */
420       int i;
421
422       for (i = 0; i < max; i++)
423         if (ptr[i] == 0)
424           return NULL_TREE;
425
426       /* We don't know the starting offset, but we do know that the string
427          has no internal zero bytes.  We can assume that the offset falls
428          within the bounds of the string; otherwise, the programmer deserves
429          what he gets.  Subtract the offset from the length of the string,
430          and return that.  This would perhaps not be valid if we were dealing
431          with named arrays in addition to literal string constants.  */
432
433       return size_diffop (size_int (max), offset_node);
434     }
435
436   /* We have a known offset into the string.  Start searching there for
437      a null character if we can represent it as a single HOST_WIDE_INT.  */
438   if (offset_node == 0)
439     offset = 0;
440   else if (! host_integerp (offset_node, 0))
441     offset = -1;
442   else
443     offset = tree_low_cst (offset_node, 0);
444
445   /* If the offset is known to be out of bounds, warn, and call strlen at
446      runtime.  */
447   if (offset < 0 || offset > max)
448     {
449      /* Suppress multiple warnings for propagated constant strings.  */
450       if (! TREE_NO_WARNING (src))
451         {
452           warning (0, "offset outside bounds of constant string");
453           TREE_NO_WARNING (src) = 1;
454         }
455       return NULL_TREE;
456     }
457
458   /* Use strlen to search for the first zero byte.  Since any strings
459      constructed with build_string will have nulls appended, we win even
460      if we get handed something like (char[4])"abcd".
461
462      Since OFFSET is our starting index into the string, no further
463      calculation is needed.  */
464   return ssize_int (strlen (ptr + offset));
465 }
466
467 /* Return a char pointer for a C string if it is a string constant
468    or sum of string constant and integer constant.  */
469
470 static const char *
471 c_getstr (tree src)
472 {
473   tree offset_node;
474
475   src = string_constant (src, &offset_node);
476   if (src == 0)
477     return 0;
478
479   if (offset_node == 0)
480     return TREE_STRING_POINTER (src);
481   else if (!host_integerp (offset_node, 1)
482            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
483     return 0;
484
485   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
486 }
487
488 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
489    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
490
491 static rtx
492 c_readstr (const char *str, enum machine_mode mode)
493 {
494   HOST_WIDE_INT c[2];
495   HOST_WIDE_INT ch;
496   unsigned int i, j;
497
498   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
499
500   c[0] = 0;
501   c[1] = 0;
502   ch = 1;
503   for (i = 0; i < GET_MODE_SIZE (mode); i++)
504     {
505       j = i;
506       if (WORDS_BIG_ENDIAN)
507         j = GET_MODE_SIZE (mode) - i - 1;
508       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
509           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
510         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
511       j *= BITS_PER_UNIT;
512       gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
513
514       if (ch)
515         ch = (unsigned char) str[i];
516       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
517     }
518   return immed_double_const (c[0], c[1], mode);
519 }
520
521 /* Cast a target constant CST to target CHAR and if that value fits into
522    host char type, return zero and put that value into variable pointed to by
523    P.  */
524
525 static int
526 target_char_cast (tree cst, char *p)
527 {
528   unsigned HOST_WIDE_INT val, hostval;
529
530   if (!host_integerp (cst, 1)
531       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
532     return 1;
533
534   val = tree_low_cst (cst, 1);
535   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
536     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
537
538   hostval = val;
539   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
540     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
541
542   if (val != hostval)
543     return 1;
544
545   *p = hostval;
546   return 0;
547 }
548
549 /* Similar to save_expr, but assumes that arbitrary code is not executed
550    in between the multiple evaluations.  In particular, we assume that a
551    non-addressable local variable will not be modified.  */
552
553 static tree
554 builtin_save_expr (tree exp)
555 {
556   if (TREE_ADDRESSABLE (exp) == 0
557       && (TREE_CODE (exp) == PARM_DECL
558           || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
559     return exp;
560
561   return save_expr (exp);
562 }
563
564 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
565    times to get the address of either a higher stack frame, or a return
566    address located within it (depending on FNDECL_CODE).  */
567
568 static rtx
569 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
570 {
571   int i;
572
573 #ifdef INITIAL_FRAME_ADDRESS_RTX
574   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
575 #else
576   rtx tem;
577
578   /* For a zero count with __builtin_return_address, we don't care what
579      frame address we return, because target-specific definitions will
580      override us.  Therefore frame pointer elimination is OK, and using
581      the soft frame pointer is OK.
582
583      For a nonzero count, or a zero count with __builtin_frame_address,
584      we require a stable offset from the current frame pointer to the
585      previous one, so we must use the hard frame pointer, and
586      we must disable frame pointer elimination.  */
587   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
588     tem = frame_pointer_rtx;
589   else
590     {
591       tem = hard_frame_pointer_rtx;
592
593       /* Tell reload not to eliminate the frame pointer.  */
594       crtl->accesses_prior_frames = 1;
595     }
596 #endif
597
598   /* Some machines need special handling before we can access
599      arbitrary frames.  For example, on the SPARC, we must first flush
600      all register windows to the stack.  */
601 #ifdef SETUP_FRAME_ADDRESSES
602   if (count > 0)
603     SETUP_FRAME_ADDRESSES ();
604 #endif
605
606   /* On the SPARC, the return address is not in the frame, it is in a
607      register.  There is no way to access it off of the current frame
608      pointer, but it can be accessed off the previous frame pointer by
609      reading the value from the register window save area.  */
610 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
611   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
612     count--;
613 #endif
614
615   /* Scan back COUNT frames to the specified frame.  */
616   for (i = 0; i < count; i++)
617     {
618       /* Assume the dynamic chain pointer is in the word that the
619          frame address points to, unless otherwise specified.  */
620 #ifdef DYNAMIC_CHAIN_ADDRESS
621       tem = DYNAMIC_CHAIN_ADDRESS (tem);
622 #endif
623       tem = memory_address (Pmode, tem);
624       tem = gen_frame_mem (Pmode, tem);
625       tem = copy_to_reg (tem);
626     }
627
628   /* For __builtin_frame_address, return what we've got.  But, on
629      the SPARC for example, we may have to add a bias.  */
630   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
631 #ifdef FRAME_ADDR_RTX
632     return FRAME_ADDR_RTX (tem);
633 #else
634     return tem;
635 #endif
636
637   /* For __builtin_return_address, get the return address from that frame.  */
638 #ifdef RETURN_ADDR_RTX
639   tem = RETURN_ADDR_RTX (count, tem);
640 #else
641   tem = memory_address (Pmode,
642                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
643   tem = gen_frame_mem (Pmode, tem);
644 #endif
645   return tem;
646 }
647
648 /* Alias set used for setjmp buffer.  */
649 static alias_set_type setjmp_alias_set = -1;
650
651 /* Construct the leading half of a __builtin_setjmp call.  Control will
652    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
653    exception handling code.  */
654
655 void
656 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
657 {
658   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
659   rtx stack_save;
660   rtx mem;
661
662   if (setjmp_alias_set == -1)
663     setjmp_alias_set = new_alias_set ();
664
665   buf_addr = convert_memory_address (Pmode, buf_addr);
666
667   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
668
669   /* We store the frame pointer and the address of receiver_label in
670      the buffer and use the rest of it for the stack save area, which
671      is machine-dependent.  */
672
673   mem = gen_rtx_MEM (Pmode, buf_addr);
674   set_mem_alias_set (mem, setjmp_alias_set);
675   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
676
677   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
678   set_mem_alias_set (mem, setjmp_alias_set);
679
680   emit_move_insn (validize_mem (mem),
681                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
682
683   stack_save = gen_rtx_MEM (sa_mode,
684                             plus_constant (buf_addr,
685                                            2 * GET_MODE_SIZE (Pmode)));
686   set_mem_alias_set (stack_save, setjmp_alias_set);
687   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
688
689   /* If there is further processing to do, do it.  */
690 #ifdef HAVE_builtin_setjmp_setup
691   if (HAVE_builtin_setjmp_setup)
692     emit_insn (gen_builtin_setjmp_setup (buf_addr));
693 #endif
694
695   /* Tell optimize_save_area_alloca that extra work is going to
696      need to go on during alloca.  */
697   cfun->calls_setjmp = 1;
698
699   /* We have a nonlocal label.   */
700   cfun->has_nonlocal_label = 1;
701 }
702
703 /* Construct the trailing part of a __builtin_setjmp call.  This is
704    also called directly by the SJLJ exception handling code.  */
705
706 void
707 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
708 {
709   /* Clobber the FP when we get here, so we have to make sure it's
710      marked as used by this function.  */
711   emit_use (hard_frame_pointer_rtx);
712
713   /* Mark the static chain as clobbered here so life information
714      doesn't get messed up for it.  */
715   emit_clobber (static_chain_rtx);
716
717   /* Now put in the code to restore the frame pointer, and argument
718      pointer, if needed.  */
719 #ifdef HAVE_nonlocal_goto
720   if (! HAVE_nonlocal_goto)
721 #endif
722     {
723       emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
724       /* This might change the hard frame pointer in ways that aren't
725          apparent to early optimization passes, so force a clobber.  */
726       emit_clobber (hard_frame_pointer_rtx);
727     }
728
729 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
730   if (fixed_regs[ARG_POINTER_REGNUM])
731     {
732 #ifdef ELIMINABLE_REGS
733       size_t i;
734       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
735
736       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
737         if (elim_regs[i].from == ARG_POINTER_REGNUM
738             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
739           break;
740
741       if (i == ARRAY_SIZE (elim_regs))
742 #endif
743         {
744           /* Now restore our arg pointer from the address at which it
745              was saved in our stack frame.  */
746           emit_move_insn (virtual_incoming_args_rtx,
747                           copy_to_reg (get_arg_pointer_save_area ()));
748         }
749     }
750 #endif
751
752 #ifdef HAVE_builtin_setjmp_receiver
753   if (HAVE_builtin_setjmp_receiver)
754     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
755   else
756 #endif
757 #ifdef HAVE_nonlocal_goto_receiver
758     if (HAVE_nonlocal_goto_receiver)
759       emit_insn (gen_nonlocal_goto_receiver ());
760     else
761 #endif
762       { /* Nothing */ }
763
764   /* We must not allow the code we just generated to be reordered by
765      scheduling.  Specifically, the update of the frame pointer must
766      happen immediately, not later.  */
767   emit_insn (gen_blockage ());
768 }
769
770 /* __builtin_longjmp is passed a pointer to an array of five words (not
771    all will be used on all machines).  It operates similarly to the C
772    library function of the same name, but is more efficient.  Much of
773    the code below is copied from the handling of non-local gotos.  */
774
775 static void
776 expand_builtin_longjmp (rtx buf_addr, rtx value)
777 {
778   rtx fp, lab, stack, insn, last;
779   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
780
781   if (setjmp_alias_set == -1)
782     setjmp_alias_set = new_alias_set ();
783
784   buf_addr = convert_memory_address (Pmode, buf_addr);
785
786   buf_addr = force_reg (Pmode, buf_addr);
787
788   /* We used to store value in static_chain_rtx, but that fails if pointers
789      are smaller than integers.  We instead require that the user must pass
790      a second argument of 1, because that is what builtin_setjmp will
791      return.  This also makes EH slightly more efficient, since we are no
792      longer copying around a value that we don't care about.  */
793   gcc_assert (value == const1_rtx);
794
795   last = get_last_insn ();
796 #ifdef HAVE_builtin_longjmp
797   if (HAVE_builtin_longjmp)
798     emit_insn (gen_builtin_longjmp (buf_addr));
799   else
800 #endif
801     {
802       fp = gen_rtx_MEM (Pmode, buf_addr);
803       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
804                                                GET_MODE_SIZE (Pmode)));
805
806       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
807                                                    2 * GET_MODE_SIZE (Pmode)));
808       set_mem_alias_set (fp, setjmp_alias_set);
809       set_mem_alias_set (lab, setjmp_alias_set);
810       set_mem_alias_set (stack, setjmp_alias_set);
811
812       /* Pick up FP, label, and SP from the block and jump.  This code is
813          from expand_goto in stmt.c; see there for detailed comments.  */
814 #ifdef HAVE_nonlocal_goto
815       if (HAVE_nonlocal_goto)
816         /* We have to pass a value to the nonlocal_goto pattern that will
817            get copied into the static_chain pointer, but it does not matter
818            what that value is, because builtin_setjmp does not use it.  */
819         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
820       else
821 #endif
822         {
823           lab = copy_to_reg (lab);
824
825           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
826           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
827
828           emit_move_insn (hard_frame_pointer_rtx, fp);
829           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
830
831           emit_use (hard_frame_pointer_rtx);
832           emit_use (stack_pointer_rtx);
833           emit_indirect_jump (lab);
834         }
835     }
836
837   /* Search backwards and mark the jump insn as a non-local goto.
838      Note that this precludes the use of __builtin_longjmp to a
839      __builtin_setjmp target in the same function.  However, we've
840      already cautioned the user that these functions are for
841      internal exception handling use only.  */
842   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
843     {
844       gcc_assert (insn != last);
845
846       if (JUMP_P (insn))
847         {
848           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
849           break;
850         }
851       else if (CALL_P (insn))
852         break;
853     }
854 }
855
856 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
857    and the address of the save area.  */
858
859 static rtx
860 expand_builtin_nonlocal_goto (tree exp)
861 {
862   tree t_label, t_save_area;
863   rtx r_label, r_save_area, r_fp, r_sp, insn;
864
865   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
866     return NULL_RTX;
867
868   t_label = CALL_EXPR_ARG (exp, 0);
869   t_save_area = CALL_EXPR_ARG (exp, 1);
870
871   r_label = expand_normal (t_label);
872   r_label = convert_memory_address (Pmode, r_label);
873   r_save_area = expand_normal (t_save_area);
874   r_save_area = convert_memory_address (Pmode, r_save_area);
875   /* Copy the address of the save location to a register just in case it was based
876     on the frame pointer.   */
877   r_save_area = copy_to_reg (r_save_area);
878   r_fp = gen_rtx_MEM (Pmode, r_save_area);
879   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
880                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
881
882   crtl->has_nonlocal_goto = 1;
883
884 #ifdef HAVE_nonlocal_goto
885   /* ??? We no longer need to pass the static chain value, afaik.  */
886   if (HAVE_nonlocal_goto)
887     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
888   else
889 #endif
890     {
891       r_label = copy_to_reg (r_label);
892
893       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
894       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
895
896       /* Restore frame pointer for containing function.
897          This sets the actual hard register used for the frame pointer
898          to the location of the function's incoming static chain info.
899          The non-local goto handler will then adjust it to contain the
900          proper value and reload the argument pointer, if needed.  */
901       emit_move_insn (hard_frame_pointer_rtx, r_fp);
902       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
903
904       /* USE of hard_frame_pointer_rtx added for consistency;
905          not clear if really needed.  */
906       emit_use (hard_frame_pointer_rtx);
907       emit_use (stack_pointer_rtx);
908
909       /* If the architecture is using a GP register, we must
910          conservatively assume that the target function makes use of it.
911          The prologue of functions with nonlocal gotos must therefore
912          initialize the GP register to the appropriate value, and we
913          must then make sure that this value is live at the point
914          of the jump.  (Note that this doesn't necessarily apply
915          to targets with a nonlocal_goto pattern; they are free
916          to implement it in their own way.  Note also that this is
917          a no-op if the GP register is a global invariant.)  */
918       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
919           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
920         emit_use (pic_offset_table_rtx);
921
922       emit_indirect_jump (r_label);
923     }
924
925   /* Search backwards to the jump insn and mark it as a
926      non-local goto.  */
927   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
928     {
929       if (JUMP_P (insn))
930         {
931           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
932           break;
933         }
934       else if (CALL_P (insn))
935         break;
936     }
937
938   return const0_rtx;
939 }
940
941 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
942    (not all will be used on all machines) that was passed to __builtin_setjmp.
943    It updates the stack pointer in that block to correspond to the current
944    stack pointer.  */
945
946 static void
947 expand_builtin_update_setjmp_buf (rtx buf_addr)
948 {
949   enum machine_mode sa_mode = Pmode;
950   rtx stack_save;
951
952
953 #ifdef HAVE_save_stack_nonlocal
954   if (HAVE_save_stack_nonlocal)
955     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
956 #endif
957 #ifdef STACK_SAVEAREA_MODE
958   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
959 #endif
960
961   stack_save
962     = gen_rtx_MEM (sa_mode,
963                    memory_address
964                    (sa_mode,
965                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
966
967 #ifdef HAVE_setjmp
968   if (HAVE_setjmp)
969     emit_insn (gen_setjmp ());
970 #endif
971
972   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
973 }
974
975 /* Expand a call to __builtin_prefetch.  For a target that does not support
976    data prefetch, evaluate the memory address argument in case it has side
977    effects.  */
978
979 static void
980 expand_builtin_prefetch (tree exp)
981 {
982   tree arg0, arg1, arg2;
983   int nargs;
984   rtx op0, op1, op2;
985
986   if (!validate_arglist (exp, POINTER_TYPE, 0))
987     return;
988
989   arg0 = CALL_EXPR_ARG (exp, 0);
990
991   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
992      zero (read) and argument 2 (locality) defaults to 3 (high degree of
993      locality).  */
994   nargs = call_expr_nargs (exp);
995   if (nargs > 1)
996     arg1 = CALL_EXPR_ARG (exp, 1);
997   else
998     arg1 = integer_zero_node;
999   if (nargs > 2)
1000     arg2 = CALL_EXPR_ARG (exp, 2);
1001   else
1002     arg2 = build_int_cst (NULL_TREE, 3);
1003
1004   /* Argument 0 is an address.  */
1005   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1006
1007   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1008   if (TREE_CODE (arg1) != INTEGER_CST)
1009     {
1010       error ("second argument to %<__builtin_prefetch%> must be a constant");
1011       arg1 = integer_zero_node;
1012     }
1013   op1 = expand_normal (arg1);
1014   /* Argument 1 must be either zero or one.  */
1015   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1016     {
1017       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1018                " using zero");
1019       op1 = const0_rtx;
1020     }
1021
1022   /* Argument 2 (locality) must be a compile-time constant int.  */
1023   if (TREE_CODE (arg2) != INTEGER_CST)
1024     {
1025       error ("third argument to %<__builtin_prefetch%> must be a constant");
1026       arg2 = integer_zero_node;
1027     }
1028   op2 = expand_normal (arg2);
1029   /* Argument 2 must be 0, 1, 2, or 3.  */
1030   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1031     {
1032       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1033       op2 = const0_rtx;
1034     }
1035
1036 #ifdef HAVE_prefetch
1037   if (HAVE_prefetch)
1038     {
1039       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1040              (op0,
1041               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1042           || (GET_MODE (op0) != Pmode))
1043         {
1044           op0 = convert_memory_address (Pmode, op0);
1045           op0 = force_reg (Pmode, op0);
1046         }
1047       emit_insn (gen_prefetch (op0, op1, op2));
1048     }
1049 #endif
1050
1051   /* Don't do anything with direct references to volatile memory, but
1052      generate code to handle other side effects.  */
1053   if (!MEM_P (op0) && side_effects_p (op0))
1054     emit_insn (op0);
1055 }
1056
1057 /* Get a MEM rtx for expression EXP which is the address of an operand
1058    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1059    the maximum length of the block of memory that might be accessed or
1060    NULL if unknown.  */
1061
1062 static rtx
1063 get_memory_rtx (tree exp, tree len)
1064 {
1065   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1066   rtx mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1067
1068   /* Get an expression we can use to find the attributes to assign to MEM.
1069      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1070      we can.  First remove any nops.  */
1071   while (CONVERT_EXPR_P (exp)
1072          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1073     exp = TREE_OPERAND (exp, 0);
1074
1075   if (TREE_CODE (exp) == ADDR_EXPR)
1076     exp = TREE_OPERAND (exp, 0);
1077   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1078     exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1079   else
1080     exp = NULL;
1081
1082   /* Honor attributes derived from exp, except for the alias set
1083      (as builtin stringops may alias with anything) and the size
1084      (as stringops may access multiple array elements).  */
1085   if (exp)
1086     {
1087       set_mem_attributes (mem, exp, 0);
1088
1089       /* Allow the string and memory builtins to overflow from one
1090          field into another, see http://gcc.gnu.org/PR23561.
1091          Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1092          memory accessed by the string or memory builtin will fit
1093          within the field.  */
1094       if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1095         {
1096           tree mem_expr = MEM_EXPR (mem);
1097           HOST_WIDE_INT offset = -1, length = -1;
1098           tree inner = exp;
1099
1100           while (TREE_CODE (inner) == ARRAY_REF
1101                  || CONVERT_EXPR_P (inner)
1102                  || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1103                  || TREE_CODE (inner) == SAVE_EXPR)
1104             inner = TREE_OPERAND (inner, 0);
1105
1106           gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1107
1108           if (MEM_OFFSET (mem)
1109               && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1110             offset = INTVAL (MEM_OFFSET (mem));
1111
1112           if (offset >= 0 && len && host_integerp (len, 0))
1113             length = tree_low_cst (len, 0);
1114
1115           while (TREE_CODE (inner) == COMPONENT_REF)
1116             {
1117               tree field = TREE_OPERAND (inner, 1);
1118               gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1119               gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1120
1121               /* Bitfields are generally not byte-addressable.  */
1122               gcc_assert (!DECL_BIT_FIELD (field)
1123                           || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1124                                % BITS_PER_UNIT) == 0
1125                               && host_integerp (DECL_SIZE (field), 0)
1126                               && (TREE_INT_CST_LOW (DECL_SIZE (field))
1127                                   % BITS_PER_UNIT) == 0));
1128
1129               /* If we can prove that the memory starting at XEXP (mem, 0) and
1130                  ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1131                  can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
1132                  fields without DECL_SIZE_UNIT like flexible array members.  */
1133               if (length >= 0
1134                   && DECL_SIZE_UNIT (field)
1135                   && host_integerp (DECL_SIZE_UNIT (field), 0))
1136                 {
1137                   HOST_WIDE_INT size
1138                     = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
1139                   if (offset <= size
1140                       && length <= size
1141                       && offset + length <= size)
1142                     break;
1143                 }
1144
1145               if (offset >= 0
1146                   && host_integerp (DECL_FIELD_OFFSET (field), 0))
1147                 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
1148                           + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1149                             / BITS_PER_UNIT;
1150               else
1151                 {
1152                   offset = -1;
1153                   length = -1;
1154                 }
1155
1156               mem_expr = TREE_OPERAND (mem_expr, 0);
1157               inner = TREE_OPERAND (inner, 0);
1158             }
1159
1160           if (mem_expr == NULL)
1161             offset = -1;
1162           if (mem_expr != MEM_EXPR (mem))
1163             {
1164               set_mem_expr (mem, mem_expr);
1165               set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1166             }
1167         }
1168       set_mem_alias_set (mem, 0);
1169       set_mem_size (mem, NULL_RTX);
1170     }
1171
1172   return mem;
1173 }
1174 \f
1175 /* Built-in functions to perform an untyped call and return.  */
1176
1177 /* For each register that may be used for calling a function, this
1178    gives a mode used to copy the register's value.  VOIDmode indicates
1179    the register is not used for calling a function.  If the machine
1180    has register windows, this gives only the outbound registers.
1181    INCOMING_REGNO gives the corresponding inbound register.  */
1182 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1183
1184 /* For each register that may be used for returning values, this gives
1185    a mode used to copy the register's value.  VOIDmode indicates the
1186    register is not used for returning values.  If the machine has
1187    register windows, this gives only the outbound registers.
1188    INCOMING_REGNO gives the corresponding inbound register.  */
1189 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1190
1191 /* For each register that may be used for calling a function, this
1192    gives the offset of that register into the block returned by
1193    __builtin_apply_args.  0 indicates that the register is not
1194    used for calling a function.  */
1195 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1196
1197 /* Return the size required for the block returned by __builtin_apply_args,
1198    and initialize apply_args_mode.  */
1199
1200 static int
1201 apply_args_size (void)
1202 {
1203   static int size = -1;
1204   int align;
1205   unsigned int regno;
1206   enum machine_mode mode;
1207
1208   /* The values computed by this function never change.  */
1209   if (size < 0)
1210     {
1211       /* The first value is the incoming arg-pointer.  */
1212       size = GET_MODE_SIZE (Pmode);
1213
1214       /* The second value is the structure value address unless this is
1215          passed as an "invisible" first argument.  */
1216       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1217         size += GET_MODE_SIZE (Pmode);
1218
1219       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1220         if (FUNCTION_ARG_REGNO_P (regno))
1221           {
1222             mode = reg_raw_mode[regno];
1223
1224             gcc_assert (mode != VOIDmode);
1225
1226             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1227             if (size % align != 0)
1228               size = CEIL (size, align) * align;
1229             apply_args_reg_offset[regno] = size;
1230             size += GET_MODE_SIZE (mode);
1231             apply_args_mode[regno] = mode;
1232           }
1233         else
1234           {
1235             apply_args_mode[regno] = VOIDmode;
1236             apply_args_reg_offset[regno] = 0;
1237           }
1238     }
1239   return size;
1240 }
1241
1242 /* Return the size required for the block returned by __builtin_apply,
1243    and initialize apply_result_mode.  */
1244
1245 static int
1246 apply_result_size (void)
1247 {
1248   static int size = -1;
1249   int align, regno;
1250   enum machine_mode mode;
1251
1252   /* The values computed by this function never change.  */
1253   if (size < 0)
1254     {
1255       size = 0;
1256
1257       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1258         if (FUNCTION_VALUE_REGNO_P (regno))
1259           {
1260             mode = reg_raw_mode[regno];
1261
1262             gcc_assert (mode != VOIDmode);
1263
1264             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1265             if (size % align != 0)
1266               size = CEIL (size, align) * align;
1267             size += GET_MODE_SIZE (mode);
1268             apply_result_mode[regno] = mode;
1269           }
1270         else
1271           apply_result_mode[regno] = VOIDmode;
1272
1273       /* Allow targets that use untyped_call and untyped_return to override
1274          the size so that machine-specific information can be stored here.  */
1275 #ifdef APPLY_RESULT_SIZE
1276       size = APPLY_RESULT_SIZE;
1277 #endif
1278     }
1279   return size;
1280 }
1281
1282 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1283 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1284    the result block is used to save the values; otherwise it is used to
1285    restore the values.  */
1286
1287 static rtx
1288 result_vector (int savep, rtx result)
1289 {
1290   int regno, size, align, nelts;
1291   enum machine_mode mode;
1292   rtx reg, mem;
1293   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1294
1295   size = nelts = 0;
1296   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1297     if ((mode = apply_result_mode[regno]) != VOIDmode)
1298       {
1299         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1300         if (size % align != 0)
1301           size = CEIL (size, align) * align;
1302         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1303         mem = adjust_address (result, mode, size);
1304         savevec[nelts++] = (savep
1305                             ? gen_rtx_SET (VOIDmode, mem, reg)
1306                             : gen_rtx_SET (VOIDmode, reg, mem));
1307         size += GET_MODE_SIZE (mode);
1308       }
1309   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1310 }
1311 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1312
1313 /* Save the state required to perform an untyped call with the same
1314    arguments as were passed to the current function.  */
1315
1316 static rtx
1317 expand_builtin_apply_args_1 (void)
1318 {
1319   rtx registers, tem;
1320   int size, align, regno;
1321   enum machine_mode mode;
1322   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1323
1324   /* Create a block where the arg-pointer, structure value address,
1325      and argument registers can be saved.  */
1326   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1327
1328   /* Walk past the arg-pointer and structure value address.  */
1329   size = GET_MODE_SIZE (Pmode);
1330   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1331     size += GET_MODE_SIZE (Pmode);
1332
1333   /* Save each register used in calling a function to the block.  */
1334   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1335     if ((mode = apply_args_mode[regno]) != VOIDmode)
1336       {
1337         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1338         if (size % align != 0)
1339           size = CEIL (size, align) * align;
1340
1341         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1342
1343         emit_move_insn (adjust_address (registers, mode, size), tem);
1344         size += GET_MODE_SIZE (mode);
1345       }
1346
1347   /* Save the arg pointer to the block.  */
1348   tem = copy_to_reg (virtual_incoming_args_rtx);
1349 #ifdef STACK_GROWS_DOWNWARD
1350   /* We need the pointer as the caller actually passed them to us, not
1351      as we might have pretended they were passed.  Make sure it's a valid
1352      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1353   tem
1354     = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
1355                      NULL_RTX);
1356 #endif
1357   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1358
1359   size = GET_MODE_SIZE (Pmode);
1360
1361   /* Save the structure value address unless this is passed as an
1362      "invisible" first argument.  */
1363   if (struct_incoming_value)
1364     {
1365       emit_move_insn (adjust_address (registers, Pmode, size),
1366                       copy_to_reg (struct_incoming_value));
1367       size += GET_MODE_SIZE (Pmode);
1368     }
1369
1370   /* Return the address of the block.  */
1371   return copy_addr_to_reg (XEXP (registers, 0));
1372 }
1373
1374 /* __builtin_apply_args returns block of memory allocated on
1375    the stack into which is stored the arg pointer, structure
1376    value address, static chain, and all the registers that might
1377    possibly be used in performing a function call.  The code is
1378    moved to the start of the function so the incoming values are
1379    saved.  */
1380
1381 static rtx
1382 expand_builtin_apply_args (void)
1383 {
1384   /* Don't do __builtin_apply_args more than once in a function.
1385      Save the result of the first call and reuse it.  */
1386   if (apply_args_value != 0)
1387     return apply_args_value;
1388   {
1389     /* When this function is called, it means that registers must be
1390        saved on entry to this function.  So we migrate the
1391        call to the first insn of this function.  */
1392     rtx temp;
1393     rtx seq;
1394
1395     start_sequence ();
1396     temp = expand_builtin_apply_args_1 ();
1397     seq = get_insns ();
1398     end_sequence ();
1399
1400     apply_args_value = temp;
1401
1402     /* Put the insns after the NOTE that starts the function.
1403        If this is inside a start_sequence, make the outer-level insn
1404        chain current, so the code is placed at the start of the
1405        function.  */
1406     push_topmost_sequence ();
1407     emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1408     pop_topmost_sequence ();
1409     return temp;
1410   }
1411 }
1412
1413 /* Perform an untyped call and save the state required to perform an
1414    untyped return of whatever value was returned by the given function.  */
1415
1416 static rtx
1417 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1418 {
1419   int size, align, regno;
1420   enum machine_mode mode;
1421   rtx incoming_args, result, reg, dest, src, call_insn;
1422   rtx old_stack_level = 0;
1423   rtx call_fusage = 0;
1424   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1425
1426   arguments = convert_memory_address (Pmode, arguments);
1427
1428   /* Create a block where the return registers can be saved.  */
1429   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1430
1431   /* Fetch the arg pointer from the ARGUMENTS block.  */
1432   incoming_args = gen_reg_rtx (Pmode);
1433   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1434 #ifndef STACK_GROWS_DOWNWARD
1435   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1436                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1437 #endif
1438
1439   /* Push a new argument block and copy the arguments.  Do not allow
1440      the (potential) memcpy call below to interfere with our stack
1441      manipulations.  */
1442   do_pending_stack_adjust ();
1443   NO_DEFER_POP;
1444
1445   /* Save the stack with nonlocal if available.  */
1446 #ifdef HAVE_save_stack_nonlocal
1447   if (HAVE_save_stack_nonlocal)
1448     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1449   else
1450 #endif
1451     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1452
1453   /* Allocate a block of memory onto the stack and copy the memory
1454      arguments to the outgoing arguments address.  */
1455   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1456   dest = virtual_outgoing_args_rtx;
1457 #ifndef STACK_GROWS_DOWNWARD
1458   if (GET_CODE (argsize) == CONST_INT)
1459     dest = plus_constant (dest, -INTVAL (argsize));
1460   else
1461     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1462 #endif
1463   dest = gen_rtx_MEM (BLKmode, dest);
1464   set_mem_align (dest, PARM_BOUNDARY);
1465   src = gen_rtx_MEM (BLKmode, incoming_args);
1466   set_mem_align (src, PARM_BOUNDARY);
1467   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1468
1469   /* Refer to the argument block.  */
1470   apply_args_size ();
1471   arguments = gen_rtx_MEM (BLKmode, arguments);
1472   set_mem_align (arguments, PARM_BOUNDARY);
1473
1474   /* Walk past the arg-pointer and structure value address.  */
1475   size = GET_MODE_SIZE (Pmode);
1476   if (struct_value)
1477     size += GET_MODE_SIZE (Pmode);
1478
1479   /* Restore each of the registers previously saved.  Make USE insns
1480      for each of these registers for use in making the call.  */
1481   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1482     if ((mode = apply_args_mode[regno]) != VOIDmode)
1483       {
1484         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1485         if (size % align != 0)
1486           size = CEIL (size, align) * align;
1487         reg = gen_rtx_REG (mode, regno);
1488         emit_move_insn (reg, adjust_address (arguments, mode, size));
1489         use_reg (&call_fusage, reg);
1490         size += GET_MODE_SIZE (mode);
1491       }
1492
1493   /* Restore the structure value address unless this is passed as an
1494      "invisible" first argument.  */
1495   size = GET_MODE_SIZE (Pmode);
1496   if (struct_value)
1497     {
1498       rtx value = gen_reg_rtx (Pmode);
1499       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1500       emit_move_insn (struct_value, value);
1501       if (REG_P (struct_value))
1502         use_reg (&call_fusage, struct_value);
1503       size += GET_MODE_SIZE (Pmode);
1504     }
1505
1506   /* All arguments and registers used for the call are set up by now!  */
1507   function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1508
1509   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1510      and we don't want to load it into a register as an optimization,
1511      because prepare_call_address already did it if it should be done.  */
1512   if (GET_CODE (function) != SYMBOL_REF)
1513     function = memory_address (FUNCTION_MODE, function);
1514
1515   /* Generate the actual call instruction and save the return value.  */
1516 #ifdef HAVE_untyped_call
1517   if (HAVE_untyped_call)
1518     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1519                                       result, result_vector (1, result)));
1520   else
1521 #endif
1522 #ifdef HAVE_call_value
1523   if (HAVE_call_value)
1524     {
1525       rtx valreg = 0;
1526
1527       /* Locate the unique return register.  It is not possible to
1528          express a call that sets more than one return register using
1529          call_value; use untyped_call for that.  In fact, untyped_call
1530          only needs to save the return registers in the given block.  */
1531       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1532         if ((mode = apply_result_mode[regno]) != VOIDmode)
1533           {
1534             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1535
1536             valreg = gen_rtx_REG (mode, regno);
1537           }
1538
1539       emit_call_insn (GEN_CALL_VALUE (valreg,
1540                                       gen_rtx_MEM (FUNCTION_MODE, function),
1541                                       const0_rtx, NULL_RTX, const0_rtx));
1542
1543       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1544     }
1545   else
1546 #endif
1547     gcc_unreachable ();
1548
1549   /* Find the CALL insn we just emitted, and attach the register usage
1550      information.  */
1551   call_insn = last_call_insn ();
1552   add_function_usage_to (call_insn, call_fusage);
1553
1554   /* Restore the stack.  */
1555 #ifdef HAVE_save_stack_nonlocal
1556   if (HAVE_save_stack_nonlocal)
1557     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1558   else
1559 #endif
1560     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1561
1562   OK_DEFER_POP;
1563
1564   /* Return the address of the result block.  */
1565   result = copy_addr_to_reg (XEXP (result, 0));
1566   return convert_memory_address (ptr_mode, result);
1567 }
1568
1569 /* Perform an untyped return.  */
1570
1571 static void
1572 expand_builtin_return (rtx result)
1573 {
1574   int size, align, regno;
1575   enum machine_mode mode;
1576   rtx reg;
1577   rtx call_fusage = 0;
1578
1579   result = convert_memory_address (Pmode, result);
1580
1581   apply_result_size ();
1582   result = gen_rtx_MEM (BLKmode, result);
1583
1584 #ifdef HAVE_untyped_return
1585   if (HAVE_untyped_return)
1586     {
1587       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1588       emit_barrier ();
1589       return;
1590     }
1591 #endif
1592
1593   /* Restore the return value and note that each value is used.  */
1594   size = 0;
1595   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1596     if ((mode = apply_result_mode[regno]) != VOIDmode)
1597       {
1598         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1599         if (size % align != 0)
1600           size = CEIL (size, align) * align;
1601         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1602         emit_move_insn (reg, adjust_address (result, mode, size));
1603
1604         push_to_sequence (call_fusage);
1605         emit_use (reg);
1606         call_fusage = get_insns ();
1607         end_sequence ();
1608         size += GET_MODE_SIZE (mode);
1609       }
1610
1611   /* Put the USE insns before the return.  */
1612   emit_insn (call_fusage);
1613
1614   /* Return whatever values was restored by jumping directly to the end
1615      of the function.  */
1616   expand_naked_return ();
1617 }
1618
1619 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1620
1621 static enum type_class
1622 type_to_class (tree type)
1623 {
1624   switch (TREE_CODE (type))
1625     {
1626     case VOID_TYPE:        return void_type_class;
1627     case INTEGER_TYPE:     return integer_type_class;
1628     case ENUMERAL_TYPE:    return enumeral_type_class;
1629     case BOOLEAN_TYPE:     return boolean_type_class;
1630     case POINTER_TYPE:     return pointer_type_class;
1631     case REFERENCE_TYPE:   return reference_type_class;
1632     case OFFSET_TYPE:      return offset_type_class;
1633     case REAL_TYPE:        return real_type_class;
1634     case COMPLEX_TYPE:     return complex_type_class;
1635     case FUNCTION_TYPE:    return function_type_class;
1636     case METHOD_TYPE:      return method_type_class;
1637     case RECORD_TYPE:      return record_type_class;
1638     case UNION_TYPE:
1639     case QUAL_UNION_TYPE:  return union_type_class;
1640     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1641                                    ? string_type_class : array_type_class);
1642     case LANG_TYPE:        return lang_type_class;
1643     default:               return no_type_class;
1644     }
1645 }
1646
1647 /* Expand a call EXP to __builtin_classify_type.  */
1648
1649 static rtx
1650 expand_builtin_classify_type (tree exp)
1651 {
1652   if (call_expr_nargs (exp))
1653     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1654   return GEN_INT (no_type_class);
1655 }
1656
1657 /* This helper macro, meant to be used in mathfn_built_in below,
1658    determines which among a set of three builtin math functions is
1659    appropriate for a given type mode.  The `F' and `L' cases are
1660    automatically generated from the `double' case.  */
1661 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1662   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1663   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1664   fcodel = BUILT_IN_MATHFN##L ; break;
1665 /* Similar to above, but appends _R after any F/L suffix.  */
1666 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1667   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1668   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1669   fcodel = BUILT_IN_MATHFN##L_R ; break;
1670
1671 /* Return mathematic function equivalent to FN but operating directly
1672    on TYPE, if available.  If IMPLICIT is true find the function in
1673    implicit_built_in_decls[], otherwise use built_in_decls[].  If we
1674    can't do the conversion, return zero.  */
1675
1676 static tree
1677 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
1678 {
1679   tree const *const fn_arr
1680     = implicit ? implicit_built_in_decls : built_in_decls;
1681   enum built_in_function fcode, fcodef, fcodel;
1682
1683   switch (fn)
1684     {
1685       CASE_MATHFN (BUILT_IN_ACOS)
1686       CASE_MATHFN (BUILT_IN_ACOSH)
1687       CASE_MATHFN (BUILT_IN_ASIN)
1688       CASE_MATHFN (BUILT_IN_ASINH)
1689       CASE_MATHFN (BUILT_IN_ATAN)
1690       CASE_MATHFN (BUILT_IN_ATAN2)
1691       CASE_MATHFN (BUILT_IN_ATANH)
1692       CASE_MATHFN (BUILT_IN_CBRT)
1693       CASE_MATHFN (BUILT_IN_CEIL)
1694       CASE_MATHFN (BUILT_IN_CEXPI)
1695       CASE_MATHFN (BUILT_IN_COPYSIGN)
1696       CASE_MATHFN (BUILT_IN_COS)
1697       CASE_MATHFN (BUILT_IN_COSH)
1698       CASE_MATHFN (BUILT_IN_DREM)
1699       CASE_MATHFN (BUILT_IN_ERF)
1700       CASE_MATHFN (BUILT_IN_ERFC)
1701       CASE_MATHFN (BUILT_IN_EXP)
1702       CASE_MATHFN (BUILT_IN_EXP10)
1703       CASE_MATHFN (BUILT_IN_EXP2)
1704       CASE_MATHFN (BUILT_IN_EXPM1)
1705       CASE_MATHFN (BUILT_IN_FABS)
1706       CASE_MATHFN (BUILT_IN_FDIM)
1707       CASE_MATHFN (BUILT_IN_FLOOR)
1708       CASE_MATHFN (BUILT_IN_FMA)
1709       CASE_MATHFN (BUILT_IN_FMAX)
1710       CASE_MATHFN (BUILT_IN_FMIN)
1711       CASE_MATHFN (BUILT_IN_FMOD)
1712       CASE_MATHFN (BUILT_IN_FREXP)
1713       CASE_MATHFN (BUILT_IN_GAMMA)
1714       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1715       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1716       CASE_MATHFN (BUILT_IN_HYPOT)
1717       CASE_MATHFN (BUILT_IN_ILOGB)
1718       CASE_MATHFN (BUILT_IN_INF)
1719       CASE_MATHFN (BUILT_IN_ISINF)
1720       CASE_MATHFN (BUILT_IN_J0)
1721       CASE_MATHFN (BUILT_IN_J1)
1722       CASE_MATHFN (BUILT_IN_JN)
1723       CASE_MATHFN (BUILT_IN_LCEIL)
1724       CASE_MATHFN (BUILT_IN_LDEXP)
1725       CASE_MATHFN (BUILT_IN_LFLOOR)
1726       CASE_MATHFN (BUILT_IN_LGAMMA)
1727       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1728       CASE_MATHFN (BUILT_IN_LLCEIL)
1729       CASE_MATHFN (BUILT_IN_LLFLOOR)
1730       CASE_MATHFN (BUILT_IN_LLRINT)
1731       CASE_MATHFN (BUILT_IN_LLROUND)
1732       CASE_MATHFN (BUILT_IN_LOG)
1733       CASE_MATHFN (BUILT_IN_LOG10)
1734       CASE_MATHFN (BUILT_IN_LOG1P)
1735       CASE_MATHFN (BUILT_IN_LOG2)
1736       CASE_MATHFN (BUILT_IN_LOGB)
1737       CASE_MATHFN (BUILT_IN_LRINT)
1738       CASE_MATHFN (BUILT_IN_LROUND)
1739       CASE_MATHFN (BUILT_IN_MODF)
1740       CASE_MATHFN (BUILT_IN_NAN)
1741       CASE_MATHFN (BUILT_IN_NANS)
1742       CASE_MATHFN (BUILT_IN_NEARBYINT)
1743       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1744       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1745       CASE_MATHFN (BUILT_IN_POW)
1746       CASE_MATHFN (BUILT_IN_POWI)
1747       CASE_MATHFN (BUILT_IN_POW10)
1748       CASE_MATHFN (BUILT_IN_REMAINDER)
1749       CASE_MATHFN (BUILT_IN_REMQUO)
1750       CASE_MATHFN (BUILT_IN_RINT)
1751       CASE_MATHFN (BUILT_IN_ROUND)
1752       CASE_MATHFN (BUILT_IN_SCALB)
1753       CASE_MATHFN (BUILT_IN_SCALBLN)
1754       CASE_MATHFN (BUILT_IN_SCALBN)
1755       CASE_MATHFN (BUILT_IN_SIGNBIT)
1756       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1757       CASE_MATHFN (BUILT_IN_SIN)
1758       CASE_MATHFN (BUILT_IN_SINCOS)
1759       CASE_MATHFN (BUILT_IN_SINH)
1760       CASE_MATHFN (BUILT_IN_SQRT)
1761       CASE_MATHFN (BUILT_IN_TAN)
1762       CASE_MATHFN (BUILT_IN_TANH)
1763       CASE_MATHFN (BUILT_IN_TGAMMA)
1764       CASE_MATHFN (BUILT_IN_TRUNC)
1765       CASE_MATHFN (BUILT_IN_Y0)
1766       CASE_MATHFN (BUILT_IN_Y1)
1767       CASE_MATHFN (BUILT_IN_YN)
1768
1769       default:
1770         return NULL_TREE;
1771       }
1772
1773   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1774     return fn_arr[fcode];
1775   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1776     return fn_arr[fcodef];
1777   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1778     return fn_arr[fcodel];
1779   else
1780     return NULL_TREE;
1781 }
1782
1783 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1784
1785 tree
1786 mathfn_built_in (tree type, enum built_in_function fn)
1787 {
1788   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1789 }
1790
1791 /* If errno must be maintained, expand the RTL to check if the result,
1792    TARGET, of a built-in function call, EXP, is NaN, and if so set
1793    errno to EDOM.  */
1794
1795 static void
1796 expand_errno_check (tree exp, rtx target)
1797 {
1798   rtx lab = gen_label_rtx ();
1799
1800   /* Test the result; if it is NaN, set errno=EDOM because
1801      the argument was not in the domain.  */
1802   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1803                            0, lab);
1804
1805 #ifdef TARGET_EDOM
1806   /* If this built-in doesn't throw an exception, set errno directly.  */
1807   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1808     {
1809 #ifdef GEN_ERRNO_RTX
1810       rtx errno_rtx = GEN_ERRNO_RTX;
1811 #else
1812       rtx errno_rtx
1813           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1814 #endif
1815       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1816       emit_label (lab);
1817       return;
1818     }
1819 #endif
1820
1821   /* Make sure the library call isn't expanded as a tail call.  */
1822   CALL_EXPR_TAILCALL (exp) = 0;
1823
1824   /* We can't set errno=EDOM directly; let the library call do it.
1825      Pop the arguments right away in case the call gets deleted.  */
1826   NO_DEFER_POP;
1827   expand_call (exp, target, 0);
1828   OK_DEFER_POP;
1829   emit_label (lab);
1830 }
1831
1832 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1833    Return NULL_RTX if a normal call should be emitted rather than expanding
1834    the function in-line.  EXP is the expression that is a call to the builtin
1835    function; if convenient, the result should be placed in TARGET.
1836    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1837
1838 static rtx
1839 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1840 {
1841   optab builtin_optab;
1842   rtx op0, insns, before_call;
1843   tree fndecl = get_callee_fndecl (exp);
1844   enum machine_mode mode;
1845   bool errno_set = false;
1846   tree arg;
1847
1848   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1849     return NULL_RTX;
1850
1851   arg = CALL_EXPR_ARG (exp, 0);
1852
1853   switch (DECL_FUNCTION_CODE (fndecl))
1854     {
1855     CASE_FLT_FN (BUILT_IN_SQRT):
1856       errno_set = ! tree_expr_nonnegative_p (arg);
1857       builtin_optab = sqrt_optab;
1858       break;
1859     CASE_FLT_FN (BUILT_IN_EXP):
1860       errno_set = true; builtin_optab = exp_optab; break;
1861     CASE_FLT_FN (BUILT_IN_EXP10):
1862     CASE_FLT_FN (BUILT_IN_POW10):
1863       errno_set = true; builtin_optab = exp10_optab; break;
1864     CASE_FLT_FN (BUILT_IN_EXP2):
1865       errno_set = true; builtin_optab = exp2_optab; break;
1866     CASE_FLT_FN (BUILT_IN_EXPM1):
1867       errno_set = true; builtin_optab = expm1_optab; break;
1868     CASE_FLT_FN (BUILT_IN_LOGB):
1869       errno_set = true; builtin_optab = logb_optab; break;
1870     CASE_FLT_FN (BUILT_IN_LOG):
1871       errno_set = true; builtin_optab = log_optab; break;
1872     CASE_FLT_FN (BUILT_IN_LOG10):
1873       errno_set = true; builtin_optab = log10_optab; break;
1874     CASE_FLT_FN (BUILT_IN_LOG2):
1875       errno_set = true; builtin_optab = log2_optab; break;
1876     CASE_FLT_FN (BUILT_IN_LOG1P):
1877       errno_set = true; builtin_optab = log1p_optab; break;
1878     CASE_FLT_FN (BUILT_IN_ASIN):
1879       builtin_optab = asin_optab; break;
1880     CASE_FLT_FN (BUILT_IN_ACOS):
1881       builtin_optab = acos_optab; break;
1882     CASE_FLT_FN (BUILT_IN_TAN):
1883       builtin_optab = tan_optab; break;
1884     CASE_FLT_FN (BUILT_IN_ATAN):
1885       builtin_optab = atan_optab; break;
1886     CASE_FLT_FN (BUILT_IN_FLOOR):
1887       builtin_optab = floor_optab; break;
1888     CASE_FLT_FN (BUILT_IN_CEIL):
1889       builtin_optab = ceil_optab; break;
1890     CASE_FLT_FN (BUILT_IN_TRUNC):
1891       builtin_optab = btrunc_optab; break;
1892     CASE_FLT_FN (BUILT_IN_ROUND):
1893       builtin_optab = round_optab; break;
1894     CASE_FLT_FN (BUILT_IN_NEARBYINT):
1895       builtin_optab = nearbyint_optab;
1896       if (flag_trapping_math)
1897         break;
1898       /* Else fallthrough and expand as rint.  */
1899     CASE_FLT_FN (BUILT_IN_RINT):
1900       builtin_optab = rint_optab; break;
1901     default:
1902       gcc_unreachable ();
1903     }
1904
1905   /* Make a suitable register to place result in.  */
1906   mode = TYPE_MODE (TREE_TYPE (exp));
1907
1908   if (! flag_errno_math || ! HONOR_NANS (mode))
1909     errno_set = false;
1910
1911   /* Before working hard, check whether the instruction is available.  */
1912   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
1913     {
1914       target = gen_reg_rtx (mode);
1915
1916       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1917          need to expand the argument again.  This way, we will not perform
1918          side-effects more the once.  */
1919       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
1920
1921       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
1922
1923       start_sequence ();
1924
1925       /* Compute into TARGET.
1926          Set TARGET to wherever the result comes back.  */
1927       target = expand_unop (mode, builtin_optab, op0, target, 0);
1928
1929       if (target != 0)
1930         {
1931           if (errno_set)
1932             expand_errno_check (exp, target);
1933
1934           /* Output the entire sequence.  */
1935           insns = get_insns ();
1936           end_sequence ();
1937           emit_insn (insns);
1938           return target;
1939         }
1940
1941       /* If we were unable to expand via the builtin, stop the sequence
1942          (without outputting the insns) and call to the library function
1943          with the stabilized argument list.  */
1944       end_sequence ();
1945     }
1946
1947   before_call = get_last_insn ();
1948
1949   return expand_call (exp, target, target == const0_rtx);
1950 }
1951
1952 /* Expand a call to the builtin binary math functions (pow and atan2).
1953    Return NULL_RTX if a normal call should be emitted rather than expanding the
1954    function in-line.  EXP is the expression that is a call to the builtin
1955    function; if convenient, the result should be placed in TARGET.
1956    SUBTARGET may be used as the target for computing one of EXP's
1957    operands.  */
1958
1959 static rtx
1960 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1961 {
1962   optab builtin_optab;
1963   rtx op0, op1, insns;
1964   int op1_type = REAL_TYPE;
1965   tree fndecl = get_callee_fndecl (exp);
1966   tree arg0, arg1;
1967   enum machine_mode mode;
1968   bool errno_set = true;
1969
1970   switch (DECL_FUNCTION_CODE (fndecl))
1971     {
1972     CASE_FLT_FN (BUILT_IN_SCALBN):
1973     CASE_FLT_FN (BUILT_IN_SCALBLN):
1974     CASE_FLT_FN (BUILT_IN_LDEXP):
1975       op1_type = INTEGER_TYPE;
1976     default:
1977       break;
1978     }
1979
1980   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
1981     return NULL_RTX;
1982
1983   arg0 = CALL_EXPR_ARG (exp, 0);
1984   arg1 = CALL_EXPR_ARG (exp, 1);
1985
1986   switch (DECL_FUNCTION_CODE (fndecl))
1987     {
1988     CASE_FLT_FN (BUILT_IN_POW):
1989       builtin_optab = pow_optab; break;
1990     CASE_FLT_FN (BUILT_IN_ATAN2):
1991       builtin_optab = atan2_optab; break;
1992     CASE_FLT_FN (BUILT_IN_SCALB):
1993       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
1994         return 0;
1995       builtin_optab = scalb_optab; break;
1996     CASE_FLT_FN (BUILT_IN_SCALBN):
1997     CASE_FLT_FN (BUILT_IN_SCALBLN):
1998       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
1999         return 0;
2000     /* Fall through... */
2001     CASE_FLT_FN (BUILT_IN_LDEXP):
2002       builtin_optab = ldexp_optab; break;
2003     CASE_FLT_FN (BUILT_IN_FMOD):
2004       builtin_optab = fmod_optab; break;
2005     CASE_FLT_FN (BUILT_IN_REMAINDER):
2006     CASE_FLT_FN (BUILT_IN_DREM):
2007       builtin_optab = remainder_optab; break;
2008     default:
2009       gcc_unreachable ();
2010     }
2011
2012   /* Make a suitable register to place result in.  */
2013   mode = TYPE_MODE (TREE_TYPE (exp));
2014
2015   /* Before working hard, check whether the instruction is available.  */
2016   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2017     return NULL_RTX;
2018
2019   target = gen_reg_rtx (mode);
2020
2021   if (! flag_errno_math || ! HONOR_NANS (mode))
2022     errno_set = false;
2023
2024   /* Always stabilize the argument list.  */
2025   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2026   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2027
2028   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2029   op1 = expand_normal (arg1);
2030
2031   start_sequence ();
2032
2033   /* Compute into TARGET.
2034      Set TARGET to wherever the result comes back.  */
2035   target = expand_binop (mode, builtin_optab, op0, op1,
2036                          target, 0, OPTAB_DIRECT);
2037
2038   /* If we were unable to expand via the builtin, stop the sequence
2039      (without outputting the insns) and call to the library function
2040      with the stabilized argument list.  */
2041   if (target == 0)
2042     {
2043       end_sequence ();
2044       return expand_call (exp, target, target == const0_rtx);
2045     }
2046
2047   if (errno_set)
2048     expand_errno_check (exp, target);
2049
2050   /* Output the entire sequence.  */
2051   insns = get_insns ();
2052   end_sequence ();
2053   emit_insn (insns);
2054
2055   return target;
2056 }
2057
2058 /* Expand a call to the builtin sin and cos math functions.
2059    Return NULL_RTX if a normal call should be emitted rather than expanding the
2060    function in-line.  EXP is the expression that is a call to the builtin
2061    function; if convenient, the result should be placed in TARGET.
2062    SUBTARGET may be used as the target for computing one of EXP's
2063    operands.  */
2064
2065 static rtx
2066 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2067 {
2068   optab builtin_optab;
2069   rtx op0, insns;
2070   tree fndecl = get_callee_fndecl (exp);
2071   enum machine_mode mode;
2072   tree arg;
2073
2074   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2075     return NULL_RTX;
2076
2077   arg = CALL_EXPR_ARG (exp, 0);
2078
2079   switch (DECL_FUNCTION_CODE (fndecl))
2080     {
2081     CASE_FLT_FN (BUILT_IN_SIN):
2082     CASE_FLT_FN (BUILT_IN_COS):
2083       builtin_optab = sincos_optab; break;
2084     default:
2085       gcc_unreachable ();
2086     }
2087
2088   /* Make a suitable register to place result in.  */
2089   mode = TYPE_MODE (TREE_TYPE (exp));
2090
2091   /* Check if sincos insn is available, otherwise fallback
2092      to sin or cos insn.  */
2093   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2094     switch (DECL_FUNCTION_CODE (fndecl))
2095       {
2096       CASE_FLT_FN (BUILT_IN_SIN):
2097         builtin_optab = sin_optab; break;
2098       CASE_FLT_FN (BUILT_IN_COS):
2099         builtin_optab = cos_optab; break;
2100       default:
2101         gcc_unreachable ();
2102       }
2103
2104   /* Before working hard, check whether the instruction is available.  */
2105   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
2106     {
2107       target = gen_reg_rtx (mode);
2108
2109       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2110          need to expand the argument again.  This way, we will not perform
2111          side-effects more the once.  */
2112       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2113
2114       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2115
2116       start_sequence ();
2117
2118       /* Compute into TARGET.
2119          Set TARGET to wherever the result comes back.  */
2120       if (builtin_optab == sincos_optab)
2121         {
2122           int result;
2123
2124           switch (DECL_FUNCTION_CODE (fndecl))
2125             {
2126             CASE_FLT_FN (BUILT_IN_SIN):
2127               result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2128               break;
2129             CASE_FLT_FN (BUILT_IN_COS):
2130               result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2131               break;
2132             default:
2133               gcc_unreachable ();
2134             }
2135           gcc_assert (result);
2136         }
2137       else
2138         {
2139           target = expand_unop (mode, builtin_optab, op0, target, 0);
2140         }
2141
2142       if (target != 0)
2143         {
2144           /* Output the entire sequence.  */
2145           insns = get_insns ();
2146           end_sequence ();
2147           emit_insn (insns);
2148           return target;
2149         }
2150
2151       /* If we were unable to expand via the builtin, stop the sequence
2152          (without outputting the insns) and call to the library function
2153          with the stabilized argument list.  */
2154       end_sequence ();
2155     }
2156
2157   target = expand_call (exp, target, target == const0_rtx);
2158
2159   return target;
2160 }
2161
2162 /* Expand a call to one of the builtin math functions that operate on
2163    floating point argument and output an integer result (ilogb, isinf,
2164    isnan, etc).
2165    Return 0 if a normal call should be emitted rather than expanding the
2166    function in-line.  EXP is the expression that is a call to the builtin
2167    function; if convenient, the result should be placed in TARGET.
2168    SUBTARGET may be used as the target for computing one of EXP's operands.  */
2169
2170 static rtx
2171 expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2172 {
2173   optab builtin_optab = 0;
2174   enum insn_code icode = CODE_FOR_nothing;
2175   rtx op0;
2176   tree fndecl = get_callee_fndecl (exp);
2177   enum machine_mode mode;
2178   bool errno_set = false;
2179   tree arg;
2180
2181   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2182     return NULL_RTX;
2183
2184   arg = CALL_EXPR_ARG (exp, 0);
2185
2186   switch (DECL_FUNCTION_CODE (fndecl))
2187     {
2188     CASE_FLT_FN (BUILT_IN_ILOGB):
2189       errno_set = true; builtin_optab = ilogb_optab; break;
2190     CASE_FLT_FN (BUILT_IN_ISINF):
2191       builtin_optab = isinf_optab; break;
2192     case BUILT_IN_ISNORMAL:
2193     case BUILT_IN_ISFINITE:
2194     CASE_FLT_FN (BUILT_IN_FINITE):
2195       /* These builtins have no optabs (yet).  */
2196       break;
2197     default:
2198       gcc_unreachable ();
2199     }
2200
2201   /* There's no easy way to detect the case we need to set EDOM.  */
2202   if (flag_errno_math && errno_set)
2203     return NULL_RTX;
2204
2205   /* Optab mode depends on the mode of the input argument.  */
2206   mode = TYPE_MODE (TREE_TYPE (arg));
2207
2208   if (builtin_optab)
2209     icode = optab_handler (builtin_optab, mode)->insn_code;
2210  
2211   /* Before working hard, check whether the instruction is available.  */
2212   if (icode != CODE_FOR_nothing)
2213     {
2214       /* Make a suitable register to place result in.  */
2215       if (!target
2216           || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2217          target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2218
2219       gcc_assert (insn_data[icode].operand[0].predicate
2220                   (target, GET_MODE (target)));
2221
2222       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2223          need to expand the argument again.  This way, we will not perform
2224          side-effects more the once.  */
2225       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2226
2227       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2228
2229       if (mode != GET_MODE (op0))
2230         op0 = convert_to_mode (mode, op0, 0);
2231
2232       /* Compute into TARGET.
2233          Set TARGET to wherever the result comes back.  */
2234       emit_unop_insn (icode, target, op0, UNKNOWN);
2235       return target;
2236     }
2237
2238   /* If there is no optab, try generic code.  */
2239   switch (DECL_FUNCTION_CODE (fndecl))
2240     {
2241       tree result;
2242
2243     CASE_FLT_FN (BUILT_IN_ISINF):
2244       {
2245         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
2246         tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2247         tree const type = TREE_TYPE (arg);
2248         REAL_VALUE_TYPE r;
2249         char buf[128];
2250
2251         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2252         real_from_string (&r, buf);
2253         result = build_call_expr (isgr_fn, 2,
2254                                   fold_build1 (ABS_EXPR, type, arg),
2255                                   build_real (type, r));
2256         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2257       }
2258     CASE_FLT_FN (BUILT_IN_FINITE):
2259     case BUILT_IN_ISFINITE:
2260       {
2261         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
2262         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2263         tree const type = TREE_TYPE (arg);
2264         REAL_VALUE_TYPE r;
2265         char buf[128];
2266
2267         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2268         real_from_string (&r, buf);
2269         result = build_call_expr (isle_fn, 2,
2270                                   fold_build1 (ABS_EXPR, type, arg),
2271                                   build_real (type, r));
2272         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2273       }
2274     case BUILT_IN_ISNORMAL:
2275       {
2276         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2277            islessequal(fabs(x),DBL_MAX).  */
2278         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2279         tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2280         tree const type = TREE_TYPE (arg);
2281         REAL_VALUE_TYPE rmax, rmin;
2282         char buf[128];
2283
2284         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2285         real_from_string (&rmax, buf);
2286         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2287         real_from_string (&rmin, buf);
2288         arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2289         result = build_call_expr (isle_fn, 2, arg,
2290                                   build_real (type, rmax));
2291         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2292                               build_call_expr (isge_fn, 2, arg,
2293                                                build_real (type, rmin)));
2294         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2295       }
2296     default:
2297       break;
2298     }
2299
2300   target = expand_call (exp, target, target == const0_rtx);
2301
2302   return target;
2303 }
2304
2305 /* Expand a call to the builtin sincos math function.
2306    Return NULL_RTX if a normal call should be emitted rather than expanding the
2307    function in-line.  EXP is the expression that is a call to the builtin
2308    function.  */
2309
2310 static rtx
2311 expand_builtin_sincos (tree exp)
2312 {
2313   rtx op0, op1, op2, target1, target2;
2314   enum machine_mode mode;
2315   tree arg, sinp, cosp;
2316   int result;
2317
2318   if (!validate_arglist (exp, REAL_TYPE,
2319                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2320     return NULL_RTX;
2321
2322   arg = CALL_EXPR_ARG (exp, 0);
2323   sinp = CALL_EXPR_ARG (exp, 1);
2324   cosp = CALL_EXPR_ARG (exp, 2);
2325
2326   /* Make a suitable register to place result in.  */
2327   mode = TYPE_MODE (TREE_TYPE (arg));
2328
2329   /* Check if sincos insn is available, otherwise emit the call.  */
2330   if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
2331     return NULL_RTX;
2332
2333   target1 = gen_reg_rtx (mode);
2334   target2 = gen_reg_rtx (mode);
2335
2336   op0 = expand_normal (arg);
2337   op1 = expand_normal (build_fold_indirect_ref (sinp));
2338   op2 = expand_normal (build_fold_indirect_ref (cosp));
2339
2340   /* Compute into target1 and target2.
2341      Set TARGET to wherever the result comes back.  */
2342   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2343   gcc_assert (result);
2344
2345   /* Move target1 and target2 to the memory locations indicated
2346      by op1 and op2.  */
2347   emit_move_insn (op1, target1);
2348   emit_move_insn (op2, target2);
2349
2350   return const0_rtx;
2351 }
2352
2353 /* Expand a call to the internal cexpi builtin to the sincos math function.
2354    EXP is the expression that is a call to the builtin function; if convenient,
2355    the result should be placed in TARGET.  SUBTARGET may be used as the target
2356    for computing one of EXP's operands.  */
2357
2358 static rtx
2359 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2360 {
2361   tree fndecl = get_callee_fndecl (exp);
2362   tree arg, type;
2363   enum machine_mode mode;
2364   rtx op0, op1, op2;
2365
2366   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2367     return NULL_RTX;
2368
2369   arg = CALL_EXPR_ARG (exp, 0);
2370   type = TREE_TYPE (arg);
2371   mode = TYPE_MODE (TREE_TYPE (arg));
2372
2373   /* Try expanding via a sincos optab, fall back to emitting a libcall
2374      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2375      is only generated from sincos, cexp or if we have either of them.  */
2376   if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
2377     {
2378       op1 = gen_reg_rtx (mode);
2379       op2 = gen_reg_rtx (mode);
2380
2381       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2382
2383       /* Compute into op1 and op2.  */
2384       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2385     }
2386   else if (TARGET_HAS_SINCOS)
2387     {
2388       tree call, fn = NULL_TREE;
2389       tree top1, top2;
2390       rtx op1a, op2a;
2391
2392       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2393         fn = built_in_decls[BUILT_IN_SINCOSF];
2394       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2395         fn = built_in_decls[BUILT_IN_SINCOS];
2396       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2397         fn = built_in_decls[BUILT_IN_SINCOSL];
2398       else
2399         gcc_unreachable ();
2400  
2401       op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2402       op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2403       op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2404       op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2405       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2406       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2407
2408       /* Make sure not to fold the sincos call again.  */
2409       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2410       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2411                                       call, 3, arg, top1, top2));
2412     }
2413   else
2414     {
2415       tree call, fn = NULL_TREE, narg;
2416       tree ctype = build_complex_type (type);
2417
2418       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2419         fn = built_in_decls[BUILT_IN_CEXPF];
2420       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2421         fn = built_in_decls[BUILT_IN_CEXP];
2422       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2423         fn = built_in_decls[BUILT_IN_CEXPL];
2424       else
2425         gcc_unreachable ();
2426
2427       /* If we don't have a decl for cexp create one.  This is the
2428          friendliest fallback if the user calls __builtin_cexpi
2429          without full target C99 function support.  */
2430       if (fn == NULL_TREE)
2431         {
2432           tree fntype;
2433           const char *name = NULL;
2434
2435           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2436             name = "cexpf";
2437           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2438             name = "cexp";
2439           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2440             name = "cexpl";
2441
2442           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2443           fn = build_fn_decl (name, fntype);
2444         }
2445
2446       narg = fold_build2 (COMPLEX_EXPR, ctype,
2447                           build_real (type, dconst0), arg);
2448
2449       /* Make sure not to fold the cexp call again.  */
2450       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2451       return expand_expr (build_call_nary (ctype, call, 1, narg), 
2452                           target, VOIDmode, EXPAND_NORMAL);
2453     }
2454
2455   /* Now build the proper return type.  */
2456   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2457                               make_tree (TREE_TYPE (arg), op2),
2458                               make_tree (TREE_TYPE (arg), op1)),
2459                       target, VOIDmode, EXPAND_NORMAL);
2460 }
2461
2462 /* Expand a call to one of the builtin rounding functions gcc defines
2463    as an extension (lfloor and lceil).  As these are gcc extensions we
2464    do not need to worry about setting errno to EDOM.
2465    If expanding via optab fails, lower expression to (int)(floor(x)).
2466    EXP is the expression that is a call to the builtin function;
2467    if convenient, the result should be placed in TARGET.  SUBTARGET may
2468    be used as the target for computing one of EXP's operands.  */
2469
2470 static rtx
2471 expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
2472 {
2473   convert_optab builtin_optab;
2474   rtx op0, insns, tmp;
2475   tree fndecl = get_callee_fndecl (exp);
2476   enum built_in_function fallback_fn;
2477   tree fallback_fndecl;
2478   enum machine_mode mode;
2479   tree arg;
2480
2481   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2482     gcc_unreachable ();
2483
2484   arg = CALL_EXPR_ARG (exp, 0);
2485
2486   switch (DECL_FUNCTION_CODE (fndecl))
2487     {
2488     CASE_FLT_FN (BUILT_IN_LCEIL):
2489     CASE_FLT_FN (BUILT_IN_LLCEIL):
2490       builtin_optab = lceil_optab;
2491       fallback_fn = BUILT_IN_CEIL;
2492       break;
2493
2494     CASE_FLT_FN (BUILT_IN_LFLOOR):
2495     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2496       builtin_optab = lfloor_optab;
2497       fallback_fn = BUILT_IN_FLOOR;
2498       break;
2499
2500     default:
2501       gcc_unreachable ();
2502     }
2503
2504   /* Make a suitable register to place result in.  */
2505   mode = TYPE_MODE (TREE_TYPE (exp));
2506
2507   target = gen_reg_rtx (mode);
2508
2509   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2510      need to expand the argument again.  This way, we will not perform
2511      side-effects more the once.  */
2512   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2513
2514   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2515
2516   start_sequence ();
2517
2518   /* Compute into TARGET.  */
2519   if (expand_sfix_optab (target, op0, builtin_optab))
2520     {
2521       /* Output the entire sequence.  */
2522       insns = get_insns ();
2523       end_sequence ();
2524       emit_insn (insns);
2525       return target;
2526     }
2527
2528   /* If we were unable to expand via the builtin, stop the sequence
2529      (without outputting the insns).  */
2530   end_sequence ();
2531
2532   /* Fall back to floating point rounding optab.  */
2533   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2534
2535   /* For non-C99 targets we may end up without a fallback fndecl here
2536      if the user called __builtin_lfloor directly.  In this case emit
2537      a call to the floor/ceil variants nevertheless.  This should result
2538      in the best user experience for not full C99 targets.  */
2539   if (fallback_fndecl == NULL_TREE)
2540     {
2541       tree fntype;
2542       const char *name = NULL;
2543
2544       switch (DECL_FUNCTION_CODE (fndecl))
2545         {
2546         case BUILT_IN_LCEIL:
2547         case BUILT_IN_LLCEIL:
2548           name = "ceil";
2549           break;
2550         case BUILT_IN_LCEILF:
2551         case BUILT_IN_LLCEILF:
2552           name = "ceilf";
2553           break;
2554         case BUILT_IN_LCEILL:
2555         case BUILT_IN_LLCEILL:
2556           name = "ceill";
2557           break;
2558         case BUILT_IN_LFLOOR:
2559         case BUILT_IN_LLFLOOR:
2560           name = "floor";
2561           break;
2562         case BUILT_IN_LFLOORF:
2563         case BUILT_IN_LLFLOORF:
2564           name = "floorf";
2565           break;
2566         case BUILT_IN_LFLOORL:
2567         case BUILT_IN_LLFLOORL:
2568           name = "floorl";
2569           break;
2570         default:
2571           gcc_unreachable ();
2572         }
2573
2574       fntype = build_function_type_list (TREE_TYPE (arg),
2575                                          TREE_TYPE (arg), NULL_TREE);
2576       fallback_fndecl = build_fn_decl (name, fntype);
2577     }
2578
2579   exp = build_call_expr (fallback_fndecl, 1, arg);
2580
2581   tmp = expand_normal (exp);
2582
2583   /* Truncate the result of floating point optab to integer
2584      via expand_fix ().  */
2585   target = gen_reg_rtx (mode);
2586   expand_fix (target, tmp, 0);
2587
2588   return target;
2589 }
2590
2591 /* Expand a call to one of the builtin math functions doing integer
2592    conversion (lrint).
2593    Return 0 if a normal call should be emitted rather than expanding the
2594    function in-line.  EXP is the expression that is a call to the builtin
2595    function; if convenient, the result should be placed in TARGET.
2596    SUBTARGET may be used as the target for computing one of EXP's operands.  */
2597
2598 static rtx
2599 expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
2600 {
2601   convert_optab builtin_optab;
2602   rtx op0, insns;
2603   tree fndecl = get_callee_fndecl (exp);
2604   tree arg;
2605   enum machine_mode mode;
2606
2607   /* There's no easy way to detect the case we need to set EDOM.  */
2608   if (flag_errno_math)
2609     return NULL_RTX;
2610
2611   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2612      gcc_unreachable ();
2613  
2614   arg = CALL_EXPR_ARG (exp, 0);
2615
2616   switch (DECL_FUNCTION_CODE (fndecl))
2617     {
2618     CASE_FLT_FN (BUILT_IN_LRINT):
2619     CASE_FLT_FN (BUILT_IN_LLRINT):
2620       builtin_optab = lrint_optab; break;
2621     CASE_FLT_FN (BUILT_IN_LROUND):
2622     CASE_FLT_FN (BUILT_IN_LLROUND):
2623       builtin_optab = lround_optab; break;
2624     default:
2625       gcc_unreachable ();
2626     }
2627
2628   /* Make a suitable register to place result in.  */
2629   mode = TYPE_MODE (TREE_TYPE (exp));
2630
2631   target = gen_reg_rtx (mode);
2632
2633   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2634      need to expand the argument again.  This way, we will not perform
2635      side-effects more the once.  */
2636   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2637
2638   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2639
2640   start_sequence ();
2641
2642   if (expand_sfix_optab (target, op0, builtin_optab))
2643     {
2644       /* Output the entire sequence.  */
2645       insns = get_insns ();
2646       end_sequence ();
2647       emit_insn (insns);
2648       return target;
2649     }
2650
2651   /* If we were unable to expand via the builtin, stop the sequence
2652      (without outputting the insns) and call to the library function
2653      with the stabilized argument list.  */
2654   end_sequence ();
2655
2656   target = expand_call (exp, target, target == const0_rtx);
2657
2658   return target;
2659 }
2660
2661 /* To evaluate powi(x,n), the floating point value x raised to the
2662    constant integer exponent n, we use a hybrid algorithm that
2663    combines the "window method" with look-up tables.  For an
2664    introduction to exponentiation algorithms and "addition chains",
2665    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2666    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2667    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2668    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2669
2670 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2671    multiplications to inline before calling the system library's pow
2672    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2673    so this default never requires calling pow, powf or powl.  */
2674
2675 #ifndef POWI_MAX_MULTS
2676 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2677 #endif
2678
2679 /* The size of the "optimal power tree" lookup table.  All
2680    exponents less than this value are simply looked up in the
2681    powi_table below.  This threshold is also used to size the
2682    cache of pseudo registers that hold intermediate results.  */
2683 #define POWI_TABLE_SIZE 256
2684
2685 /* The size, in bits of the window, used in the "window method"
2686    exponentiation algorithm.  This is equivalent to a radix of
2687    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2688 #define POWI_WINDOW_SIZE 3
2689
2690 /* The following table is an efficient representation of an
2691    "optimal power tree".  For each value, i, the corresponding
2692    value, j, in the table states than an optimal evaluation
2693    sequence for calculating pow(x,i) can be found by evaluating
2694    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2695    100 integers is given in Knuth's "Seminumerical algorithms".  */
2696
2697 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2698   {
2699       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2700       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2701       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2702      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2703      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2704      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2705      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2706      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2707      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2708      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2709      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2710      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2711      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2712      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2713      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2714      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2715      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2716      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2717      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2718      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2719      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2720      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2721      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2722      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2723      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2724     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2725     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2726     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2727     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2728     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2729     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2730     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2731   };
2732
2733
2734 /* Return the number of multiplications required to calculate
2735    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2736    subroutine of powi_cost.  CACHE is an array indicating
2737    which exponents have already been calculated.  */
2738
2739 static int
2740 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2741 {
2742   /* If we've already calculated this exponent, then this evaluation
2743      doesn't require any additional multiplications.  */
2744   if (cache[n])
2745     return 0;
2746
2747   cache[n] = true;
2748   return powi_lookup_cost (n - powi_table[n], cache)
2749          + powi_lookup_cost (powi_table[n], cache) + 1;
2750 }
2751
2752 /* Return the number of multiplications required to calculate
2753    powi(x,n) for an arbitrary x, given the exponent N.  This
2754    function needs to be kept in sync with expand_powi below.  */
2755
2756 static int
2757 powi_cost (HOST_WIDE_INT n)
2758 {
2759   bool cache[POWI_TABLE_SIZE];
2760   unsigned HOST_WIDE_INT digit;
2761   unsigned HOST_WIDE_INT val;
2762   int result;
2763
2764   if (n == 0)
2765     return 0;
2766
2767   /* Ignore the reciprocal when calculating the cost.  */
2768   val = (n < 0) ? -n : n;
2769
2770   /* Initialize the exponent cache.  */
2771   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2772   cache[1] = true;
2773
2774   result = 0;
2775
2776   while (val >= POWI_TABLE_SIZE)
2777     {
2778       if (val & 1)
2779         {
2780           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2781           result += powi_lookup_cost (digit, cache)
2782                     + POWI_WINDOW_SIZE + 1;
2783           val >>= POWI_WINDOW_SIZE;
2784         }
2785       else
2786         {
2787           val >>= 1;
2788           result++;
2789         }
2790     }
2791
2792   return result + powi_lookup_cost (val, cache);
2793 }
2794
2795 /* Recursive subroutine of expand_powi.  This function takes the array,
2796    CACHE, of already calculated exponents and an exponent N and returns
2797    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2798
2799 static rtx
2800 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2801 {
2802   unsigned HOST_WIDE_INT digit;
2803   rtx target, result;
2804   rtx op0, op1;
2805
2806   if (n < POWI_TABLE_SIZE)
2807     {
2808       if (cache[n])
2809         return cache[n];
2810
2811       target = gen_reg_rtx (mode);
2812       cache[n] = target;
2813
2814       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2815       op1 = expand_powi_1 (mode, powi_table[n], cache);
2816     }
2817   else if (n & 1)
2818     {
2819       target = gen_reg_rtx (mode);
2820       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2821       op0 = expand_powi_1 (mode, n - digit, cache);
2822       op1 = expand_powi_1 (mode, digit, cache);
2823     }
2824   else
2825     {
2826       target = gen_reg_rtx (mode);
2827       op0 = expand_powi_1 (mode, n >> 1, cache);
2828       op1 = op0;
2829     }
2830
2831   result = expand_mult (mode, op0, op1, target, 0);
2832   if (result != target)
2833     emit_move_insn (target, result);
2834   return target;
2835 }
2836
2837 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2838    floating point operand in mode MODE, and N is the exponent.  This
2839    function needs to be kept in sync with powi_cost above.  */
2840
2841 static rtx
2842 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2843 {
2844   unsigned HOST_WIDE_INT val;
2845   rtx cache[POWI_TABLE_SIZE];
2846   rtx result;
2847
2848   if (n == 0)
2849     return CONST1_RTX (mode);
2850
2851   val = (n < 0) ? -n : n;
2852
2853   memset (cache, 0, sizeof (cache));
2854   cache[1] = x;
2855
2856   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2857
2858   /* If the original exponent was negative, reciprocate the result.  */
2859   if (n < 0)
2860     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2861                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2862
2863   return result;
2864 }
2865
2866 /* Expand a call to the pow built-in mathematical function.  Return NULL_RTX if
2867    a normal call should be emitted rather than expanding the function
2868    in-line.  EXP is the expression that is a call to the builtin
2869    function; if convenient, the result should be placed in TARGET.  */
2870
2871 static rtx
2872 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2873 {
2874   tree arg0, arg1;
2875   tree fn, narg0;
2876   tree type = TREE_TYPE (exp);
2877   REAL_VALUE_TYPE cint, c, c2;
2878   HOST_WIDE_INT n;
2879   rtx op, op2;
2880   enum machine_mode mode = TYPE_MODE (type);
2881
2882   if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2883     return NULL_RTX;
2884
2885   arg0 = CALL_EXPR_ARG (exp, 0);
2886   arg1 = CALL_EXPR_ARG (exp, 1);
2887
2888   if (TREE_CODE (arg1) != REAL_CST
2889       || TREE_OVERFLOW (arg1))
2890     return expand_builtin_mathfn_2 (exp, target, subtarget);
2891
2892   /* Handle constant exponents.  */
2893
2894   /* For integer valued exponents we can expand to an optimal multiplication
2895      sequence using expand_powi.  */
2896   c = TREE_REAL_CST (arg1);
2897   n = real_to_integer (&c);
2898   real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2899   if (real_identical (&c, &cint)
2900       && ((n >= -1 && n <= 2)
2901           || (flag_unsafe_math_optimizations
2902               && !optimize_size
2903               && powi_cost (n) <= POWI_MAX_MULTS)))
2904     {
2905       op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2906       if (n != 1)
2907         {
2908           op = force_reg (mode, op);
2909           op = expand_powi (op, mode, n);
2910         }
2911       return op;
2912     }
2913
2914   narg0 = builtin_save_expr (arg0);
2915
2916   /* If the exponent is not integer valued, check if it is half of an integer.
2917      In this case we can expand to sqrt (x) * x**(n/2).  */
2918   fn = mathfn_built_in (type, BUILT_IN_SQRT);
2919   if (fn != NULL_TREE)
2920     {
2921       real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2922       n = real_to_integer (&c2);
2923       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2924       if (real_identical (&c2, &cint)
2925           && ((flag_unsafe_math_optimizations
2926                && !optimize_size
2927                && powi_cost (n/2) <= POWI_MAX_MULTS)
2928               || n == 1))
2929         {
2930           tree call_expr = build_call_expr (fn, 1, narg0);
2931           /* Use expand_expr in case the newly built call expression
2932              was folded to a non-call.  */
2933           op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
2934           if (n != 1)
2935             {
2936               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2937               op2 = force_reg (mode, op2);
2938               op2 = expand_powi (op2, mode, abs (n / 2));
2939               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2940                                         0, OPTAB_LIB_WIDEN);
2941               /* If the original exponent was negative, reciprocate the
2942                  result.  */
2943               if (n < 0)
2944                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2945                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2946             }
2947           return op;
2948         }
2949     }
2950
2951   /* Try if the exponent is a third of an integer.  In this case
2952      we can expand to x**(n/3) * cbrt(x)**(n%3).  As cbrt (x) is
2953      different from pow (x, 1./3.) due to rounding and behavior
2954      with negative x we need to constrain this transformation to
2955      unsafe math and positive x or finite math.  */
2956   fn = mathfn_built_in (type, BUILT_IN_CBRT);
2957   if (fn != NULL_TREE
2958       && flag_unsafe_math_optimizations
2959       && (tree_expr_nonnegative_p (arg0)
2960           || !HONOR_NANS (mode)))
2961     {
2962       REAL_VALUE_TYPE dconst3;
2963       real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
2964       real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2965       real_round (&c2, mode, &c2);
2966       n = real_to_integer (&c2);
2967       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2968       real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2969       real_convert (&c2, mode, &c2);
2970       if (real_identical (&c2, &c)
2971           && ((!optimize_size
2972                && powi_cost (n/3) <= POWI_MAX_MULTS)
2973               || n == 1))
2974         {
2975           tree call_expr = build_call_expr (fn, 1,narg0);
2976           op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
2977           if (abs (n) % 3 == 2)
2978             op = expand_simple_binop (mode, MULT, op, op, op,
2979                                       0, OPTAB_LIB_WIDEN);
2980           if (n != 1)
2981             {
2982               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2983               op2 = force_reg (mode, op2);
2984               op2 = expand_powi (op2, mode, abs (n / 3));
2985               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2986                                         0, OPTAB_LIB_WIDEN);
2987               /* If the original exponent was negative, reciprocate the
2988                  result.  */
2989               if (n < 0)
2990                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2991                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2992             }
2993           return op;
2994         }
2995     }
2996
2997   /* Fall back to optab expansion.  */
2998   return expand_builtin_mathfn_2 (exp, target, subtarget);
2999 }
3000
3001 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
3002    a normal call should be emitted rather than expanding the function
3003    in-line.  EXP is the expression that is a call to the builtin
3004    function; if convenient, the result should be placed in TARGET.  */
3005
3006 static rtx
3007 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3008 {
3009   tree arg0, arg1;
3010   rtx op0, op1;
3011   enum machine_mode mode;
3012   enum machine_mode mode2;
3013
3014   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3015     return NULL_RTX;
3016
3017   arg0 = CALL_EXPR_ARG (exp, 0);
3018   arg1 = CALL_EXPR_ARG (exp, 1);
3019   mode = TYPE_MODE (TREE_TYPE (exp));
3020
3021   /* Handle constant power.  */
3022
3023   if (TREE_CODE (arg1) == INTEGER_CST
3024       && !TREE_OVERFLOW (arg1))
3025     {
3026       HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3027
3028       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3029          Otherwise, check the number of multiplications required.  */
3030       if ((TREE_INT_CST_HIGH (arg1) == 0
3031            || TREE_INT_CST_HIGH (arg1) == -1)
3032           && ((n >= -1 && n <= 2)
3033               || (! optimize_size
3034                   && powi_cost (n) <= POWI_MAX_MULTS)))
3035         {
3036           op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
3037           op0 = force_reg (mode, op0);
3038           return expand_powi (op0, mode, n);
3039         }
3040     }
3041
3042   /* Emit a libcall to libgcc.  */
3043
3044   /* Mode of the 2nd argument must match that of an int.  */
3045   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3046
3047   if (target == NULL_RTX)
3048     target = gen_reg_rtx (mode);
3049
3050   op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
3051   if (GET_MODE (op0) != mode)
3052     op0 = convert_to_mode (mode, op0, 0);
3053   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
3054   if (GET_MODE (op1) != mode2)
3055     op1 = convert_to_mode (mode2, op1, 0);
3056
3057   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
3058                                     target, LCT_CONST, mode, 2,
3059                                     op0, mode, op1, mode2);
3060
3061   return target;
3062 }
3063
3064 /* Expand expression EXP which is a call to the strlen builtin.  Return 
3065    NULL_RTX if we failed the caller should emit a normal call, otherwise
3066    try to get the result in TARGET, if convenient.  */
3067
3068 static rtx
3069 expand_builtin_strlen (tree exp, rtx target,
3070                        enum machine_mode target_mode)
3071 {
3072   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3073     return NULL_RTX;
3074   else
3075     {
3076       rtx pat;
3077       tree len;
3078       tree src = CALL_EXPR_ARG (exp, 0);
3079       rtx result, src_reg, char_rtx, before_strlen;
3080       enum machine_mode insn_mode = target_mode, char_mode;
3081       enum insn_code icode = CODE_FOR_nothing;
3082       int align;
3083
3084       /* If the length can be computed at compile-time, return it.  */
3085       len = c_strlen (src, 0);
3086       if (len)
3087         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3088
3089       /* If the length can be computed at compile-time and is constant
3090          integer, but there are side-effects in src, evaluate
3091          src for side-effects, then return len.
3092          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3093          can be optimized into: i++; x = 3;  */
3094       len = c_strlen (src, 1);
3095       if (len && TREE_CODE (len) == INTEGER_CST)
3096         {
3097           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3098           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3099         }
3100
3101       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3102
3103       /* If SRC is not a pointer type, don't do this operation inline.  */
3104       if (align == 0)
3105         return NULL_RTX;
3106
3107       /* Bail out if we can't compute strlen in the right mode.  */
3108       while (insn_mode != VOIDmode)
3109         {
3110           icode = optab_handler (strlen_optab, insn_mode)->insn_code;
3111           if (icode != CODE_FOR_nothing)
3112             break;
3113
3114           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3115         }
3116       if (insn_mode == VOIDmode)
3117         return NULL_RTX;
3118
3119       /* Make a place to write the result of the instruction.  */
3120       result = target;
3121       if (! (result != 0
3122              && REG_P (result)
3123              && GET_MODE (result) == insn_mode
3124              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3125         result = gen_reg_rtx (insn_mode);
3126
3127       /* Make a place to hold the source address.  We will not expand
3128          the actual source until we are sure that the expansion will
3129          not fail -- there are trees that cannot be expanded twice.  */
3130       src_reg = gen_reg_rtx (Pmode);
3131
3132       /* Mark the beginning of the strlen sequence so we can emit the
3133          source operand later.  */
3134       before_strlen = get_last_insn ();
3135
3136       char_rtx = const0_rtx;
3137       char_mode = insn_data[(int) icode].operand[2].mode;
3138       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3139                                                             char_mode))
3140         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3141
3142       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3143                              char_rtx, GEN_INT (align));
3144       if (! pat)
3145         return NULL_RTX;
3146       emit_insn (pat);
3147
3148       /* Now that we are assured of success, expand the source.  */
3149       start_sequence ();
3150       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
3151       if (pat != src_reg)
3152         emit_move_insn (src_reg, pat);
3153       pat = get_insns ();
3154       end_sequence ();
3155
3156       if (before_strlen)
3157         emit_insn_after (pat, before_strlen);
3158       else
3159         emit_insn_before (pat, get_insns ());
3160
3161       /* Return the value in the proper mode for this function.  */
3162       if (GET_MODE (result) == target_mode)
3163         target = result;
3164       else if (target != 0)
3165         convert_move (target, result, 0);
3166       else
3167         target = convert_to_mode (target_mode, result, 0);
3168
3169       return target;
3170     }
3171 }
3172
3173 /* Expand a call to the strstr builtin.  Return NULL_RTX if we failed the
3174    caller should emit a normal call, otherwise try to get the result
3175    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3176
3177 static rtx
3178 expand_builtin_strstr (tree exp, rtx target, enum machine_mode mode)
3179 {
3180   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3181     {
3182       tree type = TREE_TYPE (exp);
3183       tree result = fold_builtin_strstr (CALL_EXPR_ARG (exp, 0),
3184                                          CALL_EXPR_ARG (exp, 1), type);
3185       if (result)
3186         return expand_expr (result, target, mode, EXPAND_NORMAL);
3187     }
3188   return NULL_RTX;
3189 }
3190
3191 /* Expand a call to the strchr builtin.  Return NULL_RTX if we failed the
3192    caller should emit a normal call, otherwise try to get the result
3193    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3194
3195 static rtx
3196 expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
3197 {
3198   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3199     {
3200       tree type = TREE_TYPE (exp);
3201       tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3202                                          CALL_EXPR_ARG (exp, 1), type);
3203       if (result)
3204         return expand_expr (result, target, mode, EXPAND_NORMAL);
3205
3206       /* FIXME: Should use strchrM optab so that ports can optimize this.  */
3207     }
3208   return NULL_RTX;
3209 }
3210
3211 /* Expand a call to the strrchr builtin.  Return NULL_RTX if we failed the
3212    caller should emit a normal call, otherwise try to get the result
3213    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3214
3215 static rtx
3216 expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
3217 {
3218   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3219     {
3220       tree type = TREE_TYPE (exp);
3221       tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3222                                           CALL_EXPR_ARG (exp, 1), type);
3223       if (result)
3224         return expand_expr (result, target, mode, EXPAND_NORMAL);
3225     }
3226   return NULL_RTX;
3227 }
3228
3229 /* Expand a call to the strpbrk builtin.  Return NULL_RTX if we failed the
3230    caller should emit a normal call, otherwise try to get the result
3231    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3232
3233 static rtx
3234 expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
3235 {
3236   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3237     {
3238       tree type = TREE_TYPE (exp);
3239       tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3240                                           CALL_EXPR_ARG (exp, 1), type);
3241       if (result)
3242         return expand_expr (result, target, mode, EXPAND_NORMAL);
3243     }
3244   return NULL_RTX;
3245 }
3246
3247 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3248    bytes from constant string DATA + OFFSET and return it as target
3249    constant.  */
3250
3251 static rtx
3252 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3253                          enum machine_mode mode)
3254 {
3255   const char *str = (const char *) data;
3256
3257   gcc_assert (offset >= 0
3258               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3259                   <= strlen (str) + 1));
3260
3261   return c_readstr (str + offset, mode);
3262 }
3263
3264 /* Expand a call EXP to the memcpy builtin.
3265    Return NULL_RTX if we failed, the caller should emit a normal call,
3266    otherwise try to get the result in TARGET, if convenient (and in
3267    mode MODE if that's convenient).  */
3268
3269 static rtx
3270 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
3271 {
3272   tree fndecl = get_callee_fndecl (exp);
3273
3274   if (!validate_arglist (exp,
3275                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3276     return NULL_RTX;
3277   else
3278     {
3279       tree dest = CALL_EXPR_ARG (exp, 0);
3280       tree src = CALL_EXPR_ARG (exp, 1);
3281       tree len = CALL_EXPR_ARG (exp, 2);
3282       const char *src_str;
3283       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3284       unsigned int dest_align
3285         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3286       rtx dest_mem, src_mem, dest_addr, len_rtx;
3287       tree result = fold_builtin_memory_op (dest, src, len, 
3288                                             TREE_TYPE (TREE_TYPE (fndecl)),
3289                                             false, /*endp=*/0);
3290       HOST_WIDE_INT expected_size = -1;
3291       unsigned int expected_align = 0;
3292
3293       if (result)
3294         {
3295           while (TREE_CODE (result) == COMPOUND_EXPR)
3296             {
3297               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3298                            EXPAND_NORMAL);
3299               result = TREE_OPERAND (result, 1);
3300             }
3301           return expand_expr (result, target, mode, EXPAND_NORMAL);
3302         }
3303
3304       /* If DEST is not a pointer type, call the normal function.  */
3305       if (dest_align == 0)
3306         return NULL_RTX;
3307
3308       /* If either SRC is not a pointer type, don't do this
3309          operation in-line.  */
3310       if (src_align == 0)
3311         return NULL_RTX;
3312  
3313       stringop_block_profile (exp, &expected_align, &expected_size);
3314       if (expected_align < dest_align)
3315         expected_align = dest_align;
3316       dest_mem = get_memory_rtx (dest, len);
3317       set_mem_align (dest_mem, dest_align);
3318       len_rtx = expand_normal (len);
3319       src_str = c_getstr (src);
3320
3321       /* If SRC is a string constant and block move would be done
3322          by pieces, we can avoid loading the string from memory
3323          and only stored the computed constants.  */
3324       if (src_str
3325           && GET_CODE (len_rtx) == CONST_INT
3326           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3327           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3328                                   CONST_CAST (char *, src_str),
3329                                   dest_align, false))
3330         {
3331           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3332                                       builtin_memcpy_read_str,
3333                                       CONST_CAST (char *, src_str),
3334                                       dest_align, false, 0);
3335           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3336           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3337           return dest_mem;
3338         }
3339
3340       src_mem = get_memory_rtx (src, len);
3341       set_mem_align (src_mem, src_align);
3342
3343       /* Copy word part most expediently.  */
3344       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3345                                          CALL_EXPR_TAILCALL (exp)
3346                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3347                                          expected_align, expected_size);
3348
3349       if (dest_addr == 0)
3350         {
3351           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3352           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3353         }
3354       return dest_addr;
3355     }
3356 }
3357
3358 /* Expand a call EXP to the mempcpy builtin.
3359    Return NULL_RTX if we failed; the caller should emit a normal call,
3360    otherwise try to get the result in TARGET, if convenient (and in
3361    mode MODE if that's convenient).  If ENDP is 0 return the
3362    destination pointer, if ENDP is 1 return the end pointer ala
3363    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3364    stpcpy.  */
3365
3366 static rtx
3367 expand_builtin_mempcpy(tree exp, rtx target, enum machine_mode mode)
3368 {
3369   if (!validate_arglist (exp,
3370                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3371     return NULL_RTX;
3372   else
3373     {
3374       tree dest = CALL_EXPR_ARG (exp, 0);
3375       tree src = CALL_EXPR_ARG (exp, 1);
3376       tree len = CALL_EXPR_ARG (exp, 2);
3377       return expand_builtin_mempcpy_args (dest, src, len,
3378                                           TREE_TYPE (exp),
3379                                           target, mode, /*endp=*/ 1);
3380     }
3381 }
3382
3383 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3384    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3385    so that this can also be called without constructing an actual CALL_EXPR.
3386    TYPE is the return type of the call.  The other arguments and return value
3387    are the same as for expand_builtin_mempcpy.  */
3388
3389 static rtx
3390 expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3391                              rtx target, enum machine_mode mode, int endp)
3392 {
3393     /* If return value is ignored, transform mempcpy into memcpy.  */
3394   if (target == const0_rtx)
3395     {
3396       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3397
3398       if (!fn)
3399         return NULL_RTX;
3400
3401       return expand_expr (build_call_expr (fn, 3, dest, src, len),
3402                           target, mode, EXPAND_NORMAL);
3403     }
3404   else
3405     {
3406       const char *src_str;
3407       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3408       unsigned int dest_align
3409         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3410       rtx dest_mem, src_mem, len_rtx;
3411       tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
3412
3413       if (result)
3414         {
3415           while (TREE_CODE (result) == COMPOUND_EXPR)
3416             {
3417               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3418                            EXPAND_NORMAL);
3419               result = TREE_OPERAND (result, 1);
3420             }
3421           return expand_expr (result, target, mode, EXPAND_NORMAL);
3422         }
3423
3424       /* If either SRC or DEST is not a pointer type, don't do this
3425          operation in-line.  */
3426       if (dest_align == 0 || src_align == 0)
3427         return NULL_RTX;
3428
3429       /* If LEN is not constant, call the normal function.  */
3430       if (! host_integerp (len, 1))
3431         return NULL_RTX;
3432
3433       len_rtx = expand_normal (len);
3434       src_str = c_getstr (src);
3435
3436       /* If SRC is a string constant and block move would be done
3437          by pieces, we can avoid loading the string from memory
3438          and only stored the computed constants.  */
3439       if (src_str
3440           && GET_CODE (len_rtx) == CONST_INT
3441           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3442           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3443                                   CONST_CAST (char *, src_str),
3444                                   dest_align, false))
3445         {
3446           dest_mem = get_memory_rtx (dest, len);
3447           set_mem_align (dest_mem, dest_align);
3448           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3449                                       builtin_memcpy_read_str,
3450                                       CONST_CAST (char *, src_str),
3451                                       dest_align, false, endp);
3452           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3453           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3454           return dest_mem;
3455         }
3456
3457       if (GET_CODE (len_rtx) == CONST_INT
3458           && can_move_by_pieces (INTVAL (len_rtx),
3459                                  MIN (dest_align, src_align)))
3460         {
3461           dest_mem = get_memory_rtx (dest, len);
3462           set_mem_align (dest_mem, dest_align);
3463           src_mem = get_memory_rtx (src, len);
3464           set_mem_align (src_mem, src_align);
3465           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3466                                      MIN (dest_align, src_align), endp);
3467           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3468           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3469           return dest_mem;
3470         }
3471
3472       return NULL_RTX;
3473     }
3474 }
3475
3476 /* Expand expression EXP, which is a call to the memmove builtin.  Return 
3477    NULL_RTX if we failed; the caller should emit a normal call.  */
3478
3479 static rtx
3480 expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
3481 {
3482   if (!validate_arglist (exp,
3483                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3484     return NULL_RTX;
3485   else
3486     {
3487       tree dest = CALL_EXPR_ARG (exp, 0);
3488       tree src = CALL_EXPR_ARG (exp, 1);
3489       tree len = CALL_EXPR_ARG (exp, 2);
3490       return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp), 
3491                                           target, mode, ignore);
3492     }
3493 }
3494
3495 /* Helper function to do the actual work for expand_builtin_memmove.  The
3496    arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3497    so that this can also be called without constructing an actual CALL_EXPR.
3498    TYPE is the return type of the call.  The other arguments and return value
3499    are the same as for expand_builtin_memmove.  */
3500
3501 static rtx
3502 expand_builtin_memmove_args (tree dest, tree src, tree len,
3503                              tree type, rtx target, enum machine_mode mode, 
3504                              int ignore)
3505 {
3506   tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3507
3508   if (result)
3509     {
3510       STRIP_TYPE_NOPS (result);
3511       while (TREE_CODE (result) == COMPOUND_EXPR)
3512         {
3513           expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3514                        EXPAND_NORMAL);
3515           result = TREE_OPERAND (result, 1);
3516         }
3517       return expand_expr (result, target, mode, EXPAND_NORMAL);
3518     }
3519   
3520   /* Otherwise, call the normal function.  */
3521   return NULL_RTX;
3522 }
3523
3524 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 
3525    NULL_RTX if we failed the caller should emit a normal call.  */
3526
3527 static rtx
3528 expand_builtin_bcopy (tree exp, int ignore)
3529 {
3530   tree type = TREE_TYPE (exp);
3531   tree src, dest, size;
3532
3533   if (!validate_arglist (exp,
3534                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3535     return NULL_RTX;
3536
3537   src = CALL_EXPR_ARG (exp, 0);
3538   dest = CALL_EXPR_ARG (exp, 1);
3539   size = CALL_EXPR_ARG (exp, 2);
3540
3541   /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3542      This is done this way so that if it isn't expanded inline, we fall
3543      back to calling bcopy instead of memmove.  */
3544   return expand_builtin_memmove_args (dest, src,
3545                                       fold_convert (sizetype, size),
3546                                       type, const0_rtx, VOIDmode, 
3547                                       ignore);
3548 }
3549
3550 #ifndef HAVE_movstr
3551 # define HAVE_movstr 0
3552 # define CODE_FOR_movstr CODE_FOR_nothing
3553 #endif
3554
3555 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3556    we failed, the caller should emit a normal call, otherwise try to
3557    get the result in TARGET, if convenient.  If ENDP is 0 return the
3558    destination pointer, if ENDP is 1 return the end pointer ala
3559    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3560    stpcpy.  */
3561
3562 static rtx
3563 expand_movstr (tree dest, tree src, rtx target, int endp)
3564 {
3565   rtx end;
3566   rtx dest_mem;
3567   rtx src_mem;
3568   rtx insn;
3569   const struct insn_data * data;
3570
3571   if (!HAVE_movstr)
3572     return NULL_RTX;
3573
3574   dest_mem = get_memory_rtx (dest, NULL);
3575   src_mem = get_memory_rtx (src, NULL);
3576   if (!endp)
3577     {
3578       target = force_reg (Pmode, XEXP (dest_mem, 0));
3579       dest_mem = replace_equiv_address (dest_mem, target);
3580       end = gen_reg_rtx (Pmode);
3581     }
3582   else
3583     {
3584       if (target == 0 || target == const0_rtx)
3585         {
3586           end = gen_reg_rtx (Pmode);
3587           if (target == 0)
3588             target = end;
3589         }
3590       else
3591         end = target;
3592     }
3593
3594   data = insn_data + CODE_FOR_movstr;
3595
3596   if (data->operand[0].mode != VOIDmode)
3597     end = gen_lowpart (data->operand[0].mode, end);
3598
3599   insn = data->genfun (end, dest_mem, src_mem);
3600
3601   gcc_assert (insn);
3602
3603   emit_insn (insn);
3604
3605   /* movstr is supposed to set end to the address of the NUL
3606      terminator.  If the caller requested a mempcpy-like return value,
3607      adjust it.  */
3608   if (endp == 1 && target != const0_rtx)
3609     {
3610       rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3611       emit_move_insn (target, force_operand (tem, NULL_RTX));
3612     }
3613
3614   return target;
3615 }
3616
3617 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 
3618    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3619    try to get the result in TARGET, if convenient (and in mode MODE if that's
3620    convenient).  */
3621
3622 static rtx
3623 expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
3624 {
3625   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3626    {
3627      tree dest = CALL_EXPR_ARG (exp, 0);
3628      tree src = CALL_EXPR_ARG (exp, 1);
3629      return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3630    }
3631    return NULL_RTX;
3632 }
3633
3634 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3635    arguments to the builtin_strcpy call DEST and SRC are broken out
3636    so that this can also be called without constructing an actual CALL_EXPR.
3637    The other arguments and return value are the same as for
3638    expand_builtin_strcpy.  */
3639
3640 static rtx
3641 expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3642                             rtx target, enum machine_mode mode)
3643 {
3644   tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3645   if (result)
3646     return expand_expr (result, target, mode, EXPAND_NORMAL);
3647   return expand_movstr (dest, src, target, /*endp=*/0);
3648
3649 }
3650
3651 /* Expand a call EXP to the stpcpy builtin.
3652    Return NULL_RTX if we failed the caller should emit a normal call,
3653    otherwise try to get the result in TARGET, if convenient (and in
3654    mode MODE if that's convenient).  */
3655
3656 static rtx
3657 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3658 {
3659   tree dst, src;
3660
3661   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3662     return NULL_RTX;
3663
3664   dst = CALL_EXPR_ARG (exp, 0);
3665   src = CALL_EXPR_ARG (exp, 1);
3666
3667   /* If return value is ignored, transform stpcpy into strcpy.  */
3668   if (target == const0_rtx)
3669     {
3670       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3671       if (!fn)
3672         return NULL_RTX;
3673
3674       return expand_expr (build_call_expr (fn, 2, dst, src),
3675                           target, mode, EXPAND_NORMAL);
3676     }
3677   else
3678     {
3679       tree len, lenp1;
3680       rtx ret;
3681
3682       /* Ensure we get an actual string whose length can be evaluated at
3683          compile-time, not an expression containing a string.  This is
3684          because the latter will potentially produce pessimized code
3685          when used to produce the return value.  */
3686       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3687         return expand_movstr (dst, src, target, /*endp=*/2);
3688
3689       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3690       ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3691                                          target, mode, /*endp=*/2);
3692
3693       if (ret)
3694         return ret;
3695
3696       if (TREE_CODE (len) == INTEGER_CST)
3697         {
3698           rtx len_rtx = expand_normal (len);
3699
3700           if (GET_CODE (len_rtx) == CONST_INT)
3701             {
3702               ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3703                                                 dst, src, target, mode);
3704
3705               if (ret)
3706                 {
3707                   if (! target)
3708                     {
3709                       if (mode != VOIDmode)
3710                         target = gen_reg_rtx (mode);
3711                       else
3712                         target = gen_reg_rtx (GET_MODE (ret));
3713                     }
3714                   if (GET_MODE (target) != GET_MODE (ret))
3715                     ret = gen_lowpart (GET_MODE (target), ret);
3716
3717                   ret = plus_constant (ret, INTVAL (len_rtx));
3718                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3719                   gcc_assert (ret);
3720
3721                   return target;
3722                 }
3723             }
3724         }
3725
3726       return expand_movstr (dst, src, target, /*endp=*/2);
3727     }
3728 }
3729
3730 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3731    bytes from constant string DATA + OFFSET and return it as target
3732    constant.  */
3733
3734 rtx
3735 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3736                           enum machine_mode mode)
3737 {
3738   const char *str = (const char *) data;
3739
3740   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3741     return const0_rtx;
3742
3743   return c_readstr (str + offset, mode);
3744 }
3745
3746 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 
3747    NULL_RTX if we failed the caller should emit a normal call.  */
3748
3749 static rtx
3750 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3751 {
3752   tree fndecl = get_callee_fndecl (exp);
3753
3754   if (validate_arglist (exp,
3755                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3756     {
3757       tree dest = CALL_EXPR_ARG (exp, 0);
3758       tree src = CALL_EXPR_ARG (exp, 1);
3759       tree len = CALL_EXPR_ARG (exp, 2);
3760       tree slen = c_strlen (src, 1);
3761       tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
3762
3763       if (result)
3764         {
3765           while (TREE_CODE (result) == COMPOUND_EXPR)
3766             {
3767               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3768                            EXPAND_NORMAL);
3769               result = TREE_OPERAND (result, 1);
3770             }
3771           return expand_expr (result, target, mode, EXPAND_NORMAL);
3772         }
3773
3774       /* We must be passed a constant len and src parameter.  */
3775       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3776         return NULL_RTX;
3777
3778       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3779
3780       /* We're required to pad with trailing zeros if the requested
3781          len is greater than strlen(s2)+1.  In that case try to
3782          use store_by_pieces, if it fails, punt.  */
3783       if (tree_int_cst_lt (slen, len))
3784         {
3785           unsigned int dest_align
3786             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3787           const char *p = c_getstr (src);
3788           rtx dest_mem;
3789
3790           if (!p || dest_align == 0 || !host_integerp (len, 1)
3791               || !can_store_by_pieces (tree_low_cst (len, 1),
3792                                        builtin_strncpy_read_str,
3793                                        CONST_CAST (char *, p),
3794                                        dest_align, false))
3795             return NULL_RTX;
3796
3797           dest_mem = get_memory_rtx (dest, len);
3798           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3799                            builtin_strncpy_read_str,
3800                            CONST_CAST (char *, p), dest_align, false, 0);
3801           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3802           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3803           return dest_mem;
3804         }
3805     }
3806   return NULL_RTX;
3807 }
3808
3809 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3810    bytes from constant string DATA + OFFSET and return it as target
3811    constant.  */
3812
3813 rtx
3814 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3815                          enum machine_mode mode)
3816 {
3817   const char *c = (const char *) data;
3818   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3819
3820   memset (p, *c, GET_MODE_SIZE (mode));
3821
3822   return c_readstr (p, mode);
3823 }
3824
3825 /* Callback routine for store_by_pieces.  Return the RTL of a register
3826    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3827    char value given in the RTL register data.  For example, if mode is
3828    4 bytes wide, return the RTL for 0x01010101*data.  */
3829
3830 static rtx
3831 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3832                         enum machine_mode mode)
3833 {
3834   rtx target, coeff;
3835   size_t size;
3836   char *p;
3837
3838   size = GET_MODE_SIZE (mode);
3839   if (size == 1)
3840     return (rtx) data;
3841
3842   p = XALLOCAVEC (char, size);
3843   memset (p, 1, size);
3844   coeff = c_readstr (p, mode);
3845
3846   target = convert_to_mode (mode, (rtx) data, 1);
3847   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3848   return force_reg (mode, target);
3849 }
3850
3851 /* Expand expression EXP, which is a call to the memset builtin.  Return 
3852    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3853    try to get the result in TARGET, if convenient (and in mode MODE if that's
3854    convenient).  */
3855
3856 static rtx
3857 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3858 {
3859   if (!validate_arglist (exp,
3860                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3861     return NULL_RTX;
3862   else
3863     {
3864       tree dest = CALL_EXPR_ARG (exp, 0);
3865       tree val = CALL_EXPR_ARG (exp, 1);
3866       tree len = CALL_EXPR_ARG (exp, 2);
3867       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3868     }
3869 }
3870
3871 /* Helper function to do the actual work for expand_builtin_memset.  The
3872    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3873    so that this can also be called without constructing an actual CALL_EXPR.
3874    The other arguments and return value are the same as for
3875    expand_builtin_memset.  */
3876
3877 static rtx
3878 expand_builtin_memset_args (tree dest, tree val, tree len,
3879                             rtx target, enum machine_mode mode, tree orig_exp)
3880 {
3881   tree fndecl, fn;
3882   enum built_in_function fcode;
3883   char c;
3884   unsigned int dest_align;
3885   rtx dest_mem, dest_addr, len_rtx;
3886   HOST_WIDE_INT expected_size = -1;
3887   unsigned int expected_align = 0;
3888
3889   dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3890
3891   /* If DEST is not a pointer type, don't do this operation in-line.  */
3892   if (dest_align == 0)
3893     return NULL_RTX;
3894
3895   stringop_block_profile (orig_exp, &expected_align, &expected_size);
3896   if (expected_align < dest_align)
3897     expected_align = dest_align;
3898
3899   /* If the LEN parameter is zero, return DEST.  */
3900   if (integer_zerop (len))
3901     {
3902       /* Evaluate and ignore VAL in case it has side-effects.  */
3903       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3904       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3905     }
3906
3907   /* Stabilize the arguments in case we fail.  */
3908   dest = builtin_save_expr (dest);
3909   val = builtin_save_expr (val);
3910   len = builtin_save_expr (len);
3911
3912   len_rtx = expand_normal (len);
3913   dest_mem = get_memory_rtx (dest, len);
3914
3915   if (TREE_CODE (val) != INTEGER_CST)
3916     {
3917       rtx val_rtx;
3918
3919       val_rtx = expand_normal (val);
3920       val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3921                                  val_rtx, 0);
3922
3923       /* Assume that we can memset by pieces if we can store
3924        * the coefficients by pieces (in the required modes).
3925        * We can't pass builtin_memset_gen_str as that emits RTL.  */
3926       c = 1;
3927       if (host_integerp (len, 1)
3928           && can_store_by_pieces (tree_low_cst (len, 1),
3929                                   builtin_memset_read_str, &c, dest_align,
3930                                   true))
3931         {
3932           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3933                                val_rtx);
3934           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3935                            builtin_memset_gen_str, val_rtx, dest_align,
3936                            true, 0);
3937         }
3938       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3939                                         dest_align, expected_align,
3940                                         expected_size))
3941         goto do_libcall;
3942       
3943       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3944       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3945       return dest_mem;
3946     }
3947
3948   if (target_char_cast (val, &c))
3949     goto do_libcall;
3950
3951   if (c)
3952     {
3953       if (host_integerp (len, 1)
3954           && can_store_by_pieces (tree_low_cst (len, 1),
3955                                   builtin_memset_read_str, &c, dest_align,
3956                                   true))
3957         store_by_pieces (dest_mem, tree_low_cst (len, 1),
3958                          builtin_memset_read_str, &c, dest_align, true, 0);
3959       else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3960                                         dest_align, expected_align,
3961                                         expected_size))
3962         goto do_libcall;
3963       
3964       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3965       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3966       return dest_mem;
3967     }
3968
3969   set_mem_align (dest_mem, dest_align);
3970   dest_addr = clear_storage_hints (dest_mem, len_rtx,
3971                                    CALL_EXPR_TAILCALL (orig_exp)
3972                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3973                                    expected_align, expected_size);
3974
3975   if (dest_addr == 0)
3976     {
3977       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3978       dest_addr = convert_memory_address (ptr_mode, dest_addr);
3979     }
3980
3981   return dest_addr;
3982
3983  do_libcall:
3984   fndecl = get_callee_fndecl (orig_exp);
3985   fcode = DECL_FUNCTION_CODE (fndecl);
3986   if (fcode == BUILT_IN_MEMSET)
3987     fn = build_call_expr (fndecl, 3, dest, val, len);
3988   else if (fcode == BUILT_IN_BZERO)
3989     fn = build_call_expr (fndecl, 2, dest, len);
3990   else
3991     gcc_unreachable ();
3992   if (TREE_CODE (fn) == CALL_EXPR)
3993     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3994   return expand_call (fn, target, target == const0_rtx);
3995 }
3996
3997 /* Expand expression EXP, which is a call to the bzero builtin.  Return 
3998    NULL_RTX if we failed the caller should emit a normal call.  */
3999
4000 static rtx
4001 expand_builtin_bzero (tree exp)
4002 {
4003   tree dest, size;
4004
4005   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4006     return NULL_RTX;
4007
4008   dest = CALL_EXPR_ARG (exp, 0);
4009   size = CALL_EXPR_ARG (exp, 1);
4010
4011   /* New argument list transforming bzero(ptr x, int y) to
4012      memset(ptr x, int 0, size_t y).   This is done this way
4013      so that if it isn't expanded inline, we fallback to
4014      calling bzero instead of memset.  */
4015
4016   return expand_builtin_memset_args (dest, integer_zero_node,
4017                                      fold_convert (sizetype, size),
4018                                      const0_rtx, VOIDmode, exp);
4019 }
4020
4021 /* Expand a call to the memchr builtin.  Return NULL_RTX if we failed the
4022    caller should emit a normal call, otherwise try to get the result
4023    in TARGET, if convenient (and in mode MODE if that's convenient).  */
4024
4025 static rtx
4026 expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4027 {
4028   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4029                         INTEGER_TYPE, VOID_TYPE))
4030     {
4031       tree type = TREE_TYPE (exp);
4032       tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4033                                          CALL_EXPR_ARG (exp, 1),
4034                                          CALL_EXPR_ARG (exp, 2), type);
4035       if (result)
4036         return expand_expr (result, target, mode, EXPAND_NORMAL);
4037     }
4038   return NULL_RTX;
4039 }
4040
4041 /* Expand expression EXP, which is a call to the memcmp built-in function.
4042    Return NULL_RTX if we failed and the
4043    caller should emit a normal call, otherwise try to get the result in
4044    TARGET, if convenient (and in mode MODE, if that's convenient).  */
4045
4046 static rtx
4047 expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
4048 {
4049   if (!validate_arglist (exp,
4050                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4051     return NULL_RTX;
4052   else
4053     {
4054       tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4055                                          CALL_EXPR_ARG (exp, 1),
4056                                          CALL_EXPR_ARG (exp, 2));
4057       if (result)
4058         return expand_expr (result, target, mode, EXPAND_NORMAL);
4059     }
4060
4061 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
4062   {
4063     rtx arg1_rtx, arg2_rtx, arg3_rtx;
4064     rtx result;
4065     rtx insn;
4066     tree arg1 = CALL_EXPR_ARG (exp, 0);
4067     tree arg2 = CALL_EXPR_ARG (exp, 1);
4068     tree len = CALL_EXPR_ARG (exp, 2);
4069
4070     int arg1_align
4071       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4072     int arg2_align
4073       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4074     enum machine_mode insn_mode;
4075
4076 #ifdef HAVE_cmpmemsi
4077     if (HAVE_cmpmemsi)
4078       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4079     else
4080 #endif
4081 #ifdef HAVE_cmpstrnsi
4082     if (HAVE_cmpstrnsi)
4083       insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4084     else
4085 #endif
4086       return NULL_RTX;
4087
4088     /* If we don't have POINTER_TYPE, call the function.  */
4089     if (arg1_align == 0 || arg2_align == 0)
4090       return NULL_RTX;
4091
4092     /* Make a place to write the result of the instruction.  */
4093     result = target;
4094     if (! (result != 0
4095            && REG_P (result) && GET_MODE (result) == insn_mode
4096            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4097       result = gen_reg_rtx (insn_mode);
4098
4099     arg1_rtx = get_memory_rtx (arg1, len);
4100     arg2_rtx = get_memory_rtx (arg2, len);
4101     arg3_rtx = expand_normal (len);
4102
4103     /* Set MEM_SIZE as appropriate.  */
4104     if (GET_CODE (arg3_rtx) == CONST_INT)
4105       {
4106         set_mem_size (arg1_rtx, arg3_rtx);
4107         set_mem_size (arg2_rtx, arg3_rtx);
4108       }
4109
4110 #ifdef HAVE_cmpmemsi
4111     if (HAVE_cmpmemsi)
4112       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4113                            GEN_INT (MIN (arg1_align, arg2_align)));
4114     else
4115 #endif
4116 #ifdef HAVE_cmpstrnsi
4117     if (HAVE_cmpstrnsi)
4118       insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4119                             GEN_INT (MIN (arg1_align, arg2_align)));
4120     else
4121 #endif
4122       gcc_unreachable ();
4123
4124     if (insn)
4125       emit_insn (insn);
4126     else
4127       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
4128                                TYPE_MODE (integer_type_node), 3,
4129                                XEXP (arg1_rtx, 0), Pmode,
4130                                XEXP (arg2_rtx, 0), Pmode,
4131                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
4132                                                 TYPE_UNSIGNED (sizetype)),
4133                                TYPE_MODE (sizetype));
4134
4135     /* Return the value in the proper mode for this function.  */
4136     mode = TYPE_MODE (TREE_TYPE (exp));
4137     if (GET_MODE (result) == mode)
4138       return result;
4139     else if (target != 0)
4140       {
4141         convert_move (target, result, 0);
4142         return target;
4143       }
4144     else
4145       return convert_to_mode (mode, result, 0);
4146   }
4147 #endif
4148
4149   return NULL_RTX;
4150 }
4151
4152 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
4153    if we failed the caller should emit a normal call, otherwise try to get
4154    the result in TARGET, if convenient.  */
4155
4156 static rtx
4157 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
4158 {
4159   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4160     return NULL_RTX;
4161   else
4162     {
4163       tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4164                                          CALL_EXPR_ARG (exp, 1));
4165       if (result)
4166         return expand_expr (result, target, mode, EXPAND_NORMAL);
4167     }
4168
4169 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4170   if (cmpstr_optab[SImode] != CODE_FOR_nothing
4171       || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4172     {
4173       rtx arg1_rtx, arg2_rtx;
4174       rtx result, insn = NULL_RTX;
4175       tree fndecl, fn;
4176       tree arg1 = CALL_EXPR_ARG (exp, 0);
4177       tree arg2 = CALL_EXPR_ARG (exp, 1);
4178
4179       int arg1_align
4180         = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4181       int arg2_align
4182         = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4183
4184       /* If we don't have POINTER_TYPE, call the function.  */
4185       if (arg1_align == 0 || arg2_align == 0)
4186         return NULL_RTX;
4187
4188       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
4189       arg1 = builtin_save_expr (arg1);
4190       arg2 = builtin_save_expr (arg2);
4191
4192       arg1_rtx = get_memory_rtx (arg1, NULL);
4193       arg2_rtx = get_memory_rtx (arg2, NULL);
4194
4195 #ifdef HAVE_cmpstrsi
4196       /* Try to call cmpstrsi.  */
4197       if (HAVE_cmpstrsi)
4198         {
4199           enum machine_mode insn_mode
4200             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4201
4202           /* Make a place to write the result of the instruction.  */
4203           result = target;
4204           if (! (result != 0
4205                  && REG_P (result) && GET_MODE (result) == insn_mode
4206                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4207             result = gen_reg_rtx (insn_mode);
4208
4209           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4210                                GEN_INT (MIN (arg1_align, arg2_align)));
4211         }
4212 #endif
4213 #ifdef HAVE_cmpstrnsi
4214       /* Try to determine at least one length and call cmpstrnsi.  */
4215       if (!insn && HAVE_cmpstrnsi)
4216         {
4217           tree len;
4218           rtx arg3_rtx;
4219
4220           enum machine_mode insn_mode
4221             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4222           tree len1 = c_strlen (arg1, 1);
4223           tree len2 = c_strlen (arg2, 1);
4224
4225           if (len1)
4226             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4227           if (len2)
4228             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4229
4230           /* If we don't have a constant length for the first, use the length
4231              of the second, if we know it.  We don't require a constant for
4232              this case; some cost analysis could be done if both are available
4233              but neither is constant.  For now, assume they're equally cheap,
4234              unless one has side effects.  If both strings have constant lengths,
4235              use the smaller.  */
4236
4237           if (!len1)
4238             len = len2;
4239           else if (!len2)
4240             len = len1;
4241           else if (TREE_SIDE_EFFECTS (len1))
4242             len = len2;
4243           else if (TREE_SIDE_EFFECTS (len2))
4244             len = len1;
4245           else if (TREE_CODE (len1) != INTEGER_CST)
4246             len = len2;
4247           else if (TREE_CODE (len2) != INTEGER_CST)
4248             len = len1;
4249           else if (tree_int_cst_lt (len1, len2))
4250             len = len1;
4251           else
4252             len = len2;
4253
4254           /* If both arguments have side effects, we cannot optimize.  */
4255           if (!len || TREE_SIDE_EFFECTS (len))
4256             goto do_libcall;
4257
4258           arg3_rtx = expand_normal (len);
4259
4260           /* Make a place to write the result of the instruction.  */
4261           result = target;
4262           if (! (result != 0
4263                  && REG_P (result) && GET_MODE (result) == insn_mode
4264                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4265             result = gen_reg_rtx (insn_mode);
4266
4267           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4268                                 GEN_INT (MIN (arg1_align, arg2_align)));
4269         }
4270 #endif
4271
4272       if (insn)
4273         {
4274           emit_insn (insn);
4275
4276           /* Return the value in the proper mode for this function.  */
4277           mode = TYPE_MODE (TREE_TYPE (exp));
4278           if (GET_MODE (result) == mode)
4279             return result;
4280           if (target == 0)
4281             return convert_to_mode (mode, result, 0);
4282           convert_move (target, result, 0);
4283           return target;
4284         }
4285
4286       /* Expand the library call ourselves using a stabilized argument
4287          list to avoid re-evaluating the function's arguments twice.  */
4288 #ifdef HAVE_cmpstrnsi
4289     do_libcall:
4290 #endif
4291       fndecl = get_callee_fndecl (exp);
4292       fn = build_call_expr (fndecl, 2, arg1, arg2);
4293       if (TREE_CODE (fn) == CALL_EXPR)
4294         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4295       return expand_call (fn, target, target == const0_rtx);
4296     }
4297 #endif
4298   return NULL_RTX;
4299 }
4300
4301 /* Expand expression EXP, which is a call to the strncmp builtin. Return 
4302    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
4303    the result in TARGET, if convenient.  */
4304
4305 static rtx
4306 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4307 {
4308   if (!validate_arglist (exp,
4309                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4310     return NULL_RTX;
4311   else
4312     {
4313       tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4314                                           CALL_EXPR_ARG (exp, 1),
4315                                           CALL_EXPR_ARG (exp, 2));
4316       if (result)
4317         return expand_expr (result, target, mode, EXPAND_NORMAL);
4318     }
4319
4320   /* If c_strlen can determine an expression for one of the string
4321      lengths, and it doesn't have side effects, then emit cmpstrnsi
4322      using length MIN(strlen(string)+1, arg3).  */
4323 #ifdef HAVE_cmpstrnsi
4324   if (HAVE_cmpstrnsi)
4325   {
4326     tree len, len1, len2;
4327     rtx arg1_rtx, arg2_rtx, arg3_rtx;
4328     rtx result, insn;
4329     tree fndecl, fn;
4330     tree arg1 = CALL_EXPR_ARG (exp, 0);
4331     tree arg2 = CALL_EXPR_ARG (exp, 1);
4332     tree arg3 = CALL_EXPR_ARG (exp, 2);
4333
4334     int arg1_align
4335       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4336     int arg2_align
4337       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4338     enum machine_mode insn_mode
4339       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4340
4341     len1 = c_strlen (arg1, 1);
4342     len2 = c_strlen (arg2, 1);
4343
4344     if (len1)
4345       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4346     if (len2)
4347       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4348
4349     /* If we don't have a constant length for the first, use the length
4350        of the second, if we know it.  We don't require a constant for
4351        this case; some cost analysis could be done if both are available
4352        but neither is constant.  For now, assume they're equally cheap,
4353        unless one has side effects.  If both strings have constant lengths,
4354        use the smaller.  */
4355
4356     if (!len1)
4357       len = len2;
4358     else if (!len2)
4359       len = len1;
4360     else if (TREE_SIDE_EFFECTS (len1))
4361       len = len2;
4362     else if (TREE_SIDE_EFFECTS (len2))
4363       len = len1;
4364     else if (TREE_CODE (len1) != INTEGER_CST)
4365       len = len2;
4366     else if (TREE_CODE (len2) != INTEGER_CST)
4367       len = len1;
4368     else if (tree_int_cst_lt (len1, len2))
4369       len = len1;
4370     else
4371       len = len2;
4372
4373     /* If both arguments have side effects, we cannot optimize.  */
4374     if (!len || TREE_SIDE_EFFECTS (len))
4375       return NULL_RTX;
4376
4377     /* The actual new length parameter is MIN(len,arg3).  */
4378     len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4379                        fold_convert (TREE_TYPE (len), arg3));
4380
4381     /* If we don't have POINTER_TYPE, call the function.  */
4382     if (arg1_align == 0 || arg2_align == 0)
4383       return NULL_RTX;
4384
4385     /* Make a place to write the result of the instruction.  */
4386     result = target;
4387     if (! (result != 0
4388            && REG_P (result) && GET_MODE (result) == insn_mode
4389            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4390       result = gen_reg_rtx (insn_mode);
4391
4392     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
4393     arg1 = builtin_save_expr (arg1);
4394     arg2 = builtin_save_expr (arg2);
4395     len = builtin_save_expr (len);
4396
4397     arg1_rtx = get_memory_rtx (arg1, len);
4398     arg2_rtx = get_memory_rtx (arg2, len);
4399     arg3_rtx = expand_normal (len);
4400     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4401                           GEN_INT (MIN (arg1_align, arg2_align)));
4402     if (insn)
4403       {
4404         emit_insn (insn);
4405
4406         /* Return the value in the proper mode for this function.  */
4407         mode = TYPE_MODE (TREE_TYPE (exp));
4408         if (GET_MODE (result) == mode)
4409           return result;
4410         if (target == 0)
4411           return convert_to_mode (mode, result, 0);
4412         convert_move (target, result, 0);
4413         return target;
4414       }
4415
4416     /* Expand the library call ourselves using a stabilized argument
4417        list to avoid re-evaluating the function's arguments twice.  */
4418     fndecl = get_callee_fndecl (exp);
4419     fn = build_call_expr (fndecl, 3, arg1, arg2, len);
4420     if (TREE_CODE (fn) == CALL_EXPR)
4421       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4422     return expand_call (fn, target, target == const0_rtx);
4423   }
4424 #endif
4425   return NULL_RTX;
4426 }
4427
4428 /* Expand expression EXP, which is a call to the strcat builtin.
4429    Return NULL_RTX if we failed the caller should emit a normal call,
4430    otherwise try to get the result in TARGET, if convenient.  */
4431
4432 static rtx
4433 expand_builtin_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
4434 {
4435   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4436     return NULL_RTX;
4437   else
4438     {
4439       tree dst = CALL_EXPR_ARG (exp, 0);
4440       tree src = CALL_EXPR_ARG (exp, 1);
4441       const char *p = c_getstr (src);
4442
4443       /* If the string length is zero, return the dst parameter.  */
4444       if (p && *p == '\0')
4445         return expand_expr (dst, target, mode, EXPAND_NORMAL);
4446
4447       if (!optimize_size)
4448         {
4449           /* See if we can store by pieces into (dst + strlen(dst)).  */
4450           tree newsrc, newdst,
4451             strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4452           rtx insns;
4453
4454           /* Stabilize the argument list.  */
4455           newsrc = builtin_save_expr (src);
4456           dst = builtin_save_expr (dst);
4457
4458           start_sequence ();
4459
4460           /* Create strlen (dst).  */
4461           newdst = build_call_expr (strlen_fn, 1, dst);
4462           /* Create (dst p+ strlen (dst)).  */
4463
4464           newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4465           newdst = builtin_save_expr (newdst);
4466
4467           if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
4468             {
4469               end_sequence (); /* Stop sequence.  */
4470               return NULL_RTX;
4471             }
4472
4473           /* Output the entire sequence.  */
4474           insns = get_insns ();
4475           end_sequence ();
4476           emit_insn (insns);
4477
4478           return expand_expr (dst, target, mode, EXPAND_NORMAL);
4479         }
4480
4481       return NULL_RTX;
4482     }
4483 }
4484
4485 /* Expand expression EXP, which is a call to the strncat builtin.
4486    Return NULL_RTX if we failed the caller should emit a normal call,
4487    otherwise try to get the result in TARGET, if convenient.  */
4488
4489 static rtx
4490 expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
4491 {
4492   if (validate_arglist (exp,
4493                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4494     {
4495       tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4496                                           CALL_EXPR_ARG (exp, 1),
4497                                           CALL_EXPR_ARG (exp, 2));
4498       if (result)
4499         return expand_expr (result, target, mode, EXPAND_NORMAL);
4500     }
4501   return NULL_RTX;
4502 }
4503
4504 /* Expand expression EXP, which is a call to the strspn builtin.
4505    Return NULL_RTX if we failed the caller should emit a normal call,
4506    otherwise try to get the result in TARGET, if convenient.  */
4507
4508 static rtx
4509 expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
4510 {
4511   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4512     {
4513       tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4514                                          CALL_EXPR_ARG (exp, 1));
4515       if (result)
4516         return expand_expr (result, target, mode, EXPAND_NORMAL);
4517     }
4518   return NULL_RTX;
4519 }
4520
4521 /* Expand expression EXP, which is a call to the strcspn builtin.
4522    Return NULL_RTX if we failed the caller should emit a normal call,
4523    otherwise try to get the result in TARGET, if convenient.  */
4524
4525 static rtx
4526 expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
4527 {
4528   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4529     {
4530       tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4531                                           CALL_EXPR_ARG (exp, 1));
4532       if (result)
4533         return expand_expr (result, target, mode, EXPAND_NORMAL);
4534     }
4535   return NULL_RTX;
4536 }
4537
4538 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4539    if that's convenient.  */
4540
4541 rtx
4542 expand_builtin_saveregs (void)
4543 {
4544   rtx val, seq;
4545
4546   /* Don't do __builtin_saveregs more than once in a function.
4547      Save the result of the first call and reuse it.  */
4548   if (saveregs_value != 0)
4549     return saveregs_value;
4550
4551   /* When this function is called, it means that registers must be
4552      saved on entry to this function.  So we migrate the call to the
4553      first insn of this function.  */
4554
4555   start_sequence ();
4556
4557   /* Do whatever the machine needs done in this case.  */
4558   val = targetm.calls.expand_builtin_saveregs ();
4559
4560   seq = get_insns ();
4561   end_sequence ();
4562
4563   saveregs_value = val;
4564
4565   /* Put the insns after the NOTE that starts the function.  If this
4566      is inside a start_sequence, make the outer-level insn chain current, so
4567      the code is placed at the start of the function.  */
4568   push_topmost_sequence ();
4569   emit_insn_after (seq, entry_of_function ());
4570   pop_topmost_sequence ();
4571
4572   return val;
4573 }
4574
4575 /* __builtin_args_info (N) returns word N of the arg space info
4576    for the current function.  The number and meanings of words
4577    is controlled by the definition of CUMULATIVE_ARGS.  */
4578
4579 static rtx
4580 expand_builtin_args_info (tree exp)
4581 {
4582   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4583   int *word_ptr = (int *) &crtl->args.info;
4584
4585   gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4586
4587   if (call_expr_nargs (exp) != 0)
4588     {
4589       if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
4590         error ("argument of %<__builtin_args_info%> must be constant");
4591       else
4592         {
4593           HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
4594
4595           if (wordnum < 0 || wordnum >= nwords)
4596             error ("argument of %<__builtin_args_info%> out of range");
4597           else
4598             return GEN_INT (word_ptr[wordnum]);
4599         }
4600     }
4601   else
4602     error ("missing argument in %<__builtin_args_info%>");
4603
4604   return const0_rtx;
4605 }
4606
4607 /* Expand a call to __builtin_next_arg.  */
4608
4609 static rtx
4610 expand_builtin_next_arg (void)
4611 {
4612   /* Checking arguments is already done in fold_builtin_next_arg
4613      that must be called before this function.  */
4614   return expand_binop (ptr_mode, add_optab,
4615                        crtl->args.internal_arg_pointer,
4616                        crtl->args.arg_offset_rtx,
4617                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4618 }
4619
4620 /* Make it easier for the backends by protecting the valist argument
4621    from multiple evaluations.  */
4622
4623 static tree
4624 stabilize_va_list (tree valist, int needs_lvalue)
4625 {
4626   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4627   if (vatype !=NULL && TREE_CODE (vatype) == ARRAY_TYPE)
4628     {
4629       if (TREE_SIDE_EFFECTS (valist))
4630         valist = save_expr (valist);
4631
4632       /* For this case, the backends will be expecting a pointer to
4633          vatype, but it's possible we've actually been given an array
4634          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4635          So fix it.  */
4636       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4637         {
4638           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4639           valist = build_fold_addr_expr_with_type (valist, p1);
4640         }
4641     }
4642   else
4643     {
4644       tree pt;
4645
4646       if (! needs_lvalue)
4647         {
4648           if (! TREE_SIDE_EFFECTS (valist))
4649             return valist;
4650
4651           pt = build_pointer_type (vatype);
4652           valist = fold_build1 (ADDR_EXPR, pt, valist);
4653           TREE_SIDE_EFFECTS (valist) = 1;
4654         }
4655
4656       if (TREE_SIDE_EFFECTS (valist))
4657         valist = save_expr (valist);
4658       valist = build_fold_indirect_ref (valist);
4659     }
4660
4661   return valist;
4662 }
4663
4664 /* The "standard" definition of va_list is void*.  */
4665
4666 tree
4667 std_build_builtin_va_list (void)
4668 {
4669   return ptr_type_node;
4670 }
4671
4672 /* The "standard" abi va_list is va_list_type_node.  */
4673
4674 tree
4675 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4676 {
4677   return va_list_type_node;
4678 }
4679
4680 /* The "standard" type of va_list is va_list_type_node.  */
4681
4682 tree
4683 std_canonical_va_list_type (tree type)
4684 {
4685   tree wtype, htype;
4686
4687   wtype = va_list_type_node;
4688   htype = type;
4689   if (TREE_CODE (wtype) == ARRAY_TYPE)
4690     {
4691       /* If va_list is an array type, the argument may have decayed
4692          to a pointer type, e.g. by being passed to another function.
4693          In that case, unwrap both types so that we can compare the
4694          underlying records.  */
4695       if (TREE_CODE (htype) == ARRAY_TYPE
4696           || POINTER_TYPE_P (htype))
4697         {
4698           wtype = TREE_TYPE (wtype);
4699           htype = TREE_TYPE (htype);
4700         }
4701     }
4702   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4703     return va_list_type_node;
4704
4705   return NULL_TREE;
4706 }
4707
4708 /* The "standard" implementation of va_start: just assign `nextarg' to
4709    the variable.  */
4710
4711 void
4712 std_expand_builtin_va_start (tree valist, rtx nextarg)
4713 {
4714   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4715   convert_move (va_r, nextarg, 0);
4716 }
4717
4718 /* Expand EXP, a call to __builtin_va_start.  */
4719
4720 static rtx
4721 expand_builtin_va_start (tree exp)
4722 {
4723   rtx nextarg;
4724   tree valist;
4725
4726   if (call_expr_nargs (exp) < 2)
4727     {
4728       error ("too few arguments to function %<va_start%>");
4729       return const0_rtx;
4730     }
4731
4732   if (fold_builtin_next_arg (exp, true))
4733     return const0_rtx;
4734
4735   nextarg = expand_builtin_next_arg ();
4736   valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
4737
4738   if (targetm.expand_builtin_va_start)
4739     targetm.expand_builtin_va_start (valist, nextarg);
4740   else
4741     std_expand_builtin_va_start (valist, nextarg);
4742
4743   return const0_rtx;
4744 }
4745
4746 /* The "standard" implementation of va_arg: read the value from the
4747    current (padded) address and increment by the (padded) size.  */
4748
4749 tree
4750 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4751 {
4752   tree addr, t, type_size, rounded_size, valist_tmp;
4753   unsigned HOST_WIDE_INT align, boundary;
4754   bool indirect;
4755
4756 #ifdef ARGS_GROW_DOWNWARD
4757   /* All of the alignment and movement below is for args-grow-up machines.
4758      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4759      implement their own specialized gimplify_va_arg_expr routines.  */
4760   gcc_unreachable ();
4761 #endif
4762
4763   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4764   if (indirect)
4765     type = build_pointer_type (type);
4766
4767   align = PARM_BOUNDARY / BITS_PER_UNIT;
4768   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4769
4770   /* Hoist the valist value into a temporary for the moment.  */
4771   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4772
4773   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4774      requires greater alignment, we must perform dynamic alignment.  */
4775   if (boundary > align
4776       && !integer_zerop (TYPE_SIZE (type)))
4777     {
4778       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4779                   fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4780                                valist_tmp, size_int (boundary - 1)));
4781       gimplify_and_add (t, pre_p);
4782
4783       t = fold_convert (sizetype, valist_tmp);
4784       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4785                   fold_convert (TREE_TYPE (valist),
4786                                 fold_build2 (BIT_AND_EXPR, sizetype, t,
4787                                              size_int (-boundary))));
4788       gimplify_and_add (t, pre_p);
4789     }
4790   else
4791     boundary = align;
4792
4793   /* If the actual alignment is less than the alignment of the type,
4794      adjust the type accordingly so that we don't assume strict alignment
4795      when dereferencing the pointer.  */
4796   boundary *= BITS_PER_UNIT;
4797   if (boundary < TYPE_ALIGN (type))
4798     {
4799       type = build_variant_type_copy (type);
4800       TYPE_ALIGN (type) = boundary;
4801     }
4802
4803   /* Compute the rounded size of the type.  */
4804   type_size = size_in_bytes (type);
4805   rounded_size = round_up (type_size, align);
4806
4807   /* Reduce rounded_size so it's sharable with the postqueue.  */
4808   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4809
4810   /* Get AP.  */
4811   addr = valist_tmp;
4812   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4813     {
4814       /* Small args are padded downward.  */
4815       t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4816       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4817                        size_binop (MINUS_EXPR, rounded_size, type_size));
4818       addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
4819     }
4820
4821   /* Compute new value for AP.  */
4822   t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
4823   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4824   gimplify_and_add (t, pre_p);
4825
4826   addr = fold_convert (build_pointer_type (type), addr);
4827
4828   if (indirect)
4829     addr = build_va_arg_indirect_ref (addr);
4830
4831   return build_va_arg_indirect_ref (addr);
4832 }
4833
4834 /* Build an indirect-ref expression over the given TREE, which represents a
4835    piece of a va_arg() expansion.  */
4836 tree
4837 build_va_arg_indirect_ref (tree addr)
4838 {
4839   addr = build_fold_indirect_ref (addr);
4840
4841   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4842     mf_mark (addr);
4843
4844   return addr;
4845 }
4846
4847 /* Return a dummy expression of type TYPE in order to keep going after an
4848    error.  */
4849
4850 static tree
4851 dummy_object (tree type)
4852 {
4853   tree t = build_int_cst (build_pointer_type (type), 0);
4854   return build1 (INDIRECT_REF, type, t);
4855 }
4856
4857 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4858    builtin function, but a very special sort of operator.  */
4859
4860 enum gimplify_status
4861 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4862 {
4863   tree promoted_type, have_va_type;
4864   tree valist = TREE_OPERAND (*expr_p, 0);
4865   tree type = TREE_TYPE (*expr_p);
4866   tree t;
4867
4868   /* Verify that valist is of the proper type.  */
4869   have_va_type = TREE_TYPE (valist);
4870   if (have_va_type == error_mark_node)
4871     return GS_ERROR;
4872   have_va_type = targetm.canonical_va_list_type (have_va_type);
4873
4874   if (have_va_type == NULL_TREE)
4875     {
4876       error ("first argument to %<va_arg%> not of type %<va_list%>");
4877       return GS_ERROR;
4878     }
4879
4880   /* Generate a diagnostic for requesting data of a type that cannot
4881      be passed through `...' due to type promotion at the call site.  */
4882   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4883            != type)
4884     {
4885       static bool gave_help;
4886
4887       /* Unfortunately, this is merely undefined, rather than a constraint
4888          violation, so we cannot make this an error.  If this call is never
4889          executed, the program is still strictly conforming.  */
4890       warning (0, "%qT is promoted to %qT when passed through %<...%>",
4891                type, promoted_type);
4892       if (! gave_help)
4893         {
4894           gave_help = true;
4895           inform ("(so you should pass %qT not %qT to %<va_arg%>)",
4896                    promoted_type, type);
4897         }
4898
4899       /* We can, however, treat "undefined" any way we please.
4900          Call abort to encourage the user to fix the program.  */
4901       inform ("if this code is reached, the program will abort");
4902       t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
4903       append_to_statement_list (t, pre_p);
4904
4905       /* This is dead code, but go ahead and finish so that the
4906          mode of the result comes out right.  */
4907       *expr_p = dummy_object (type);
4908       return GS_ALL_DONE;
4909     }
4910   else
4911     {
4912       /* Make it easier for the backends by protecting the valist argument
4913          from multiple evaluations.  */
4914       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4915         {
4916           /* For this case, the backends will be expecting a pointer to
4917              TREE_TYPE (abi), but it's possible we've
4918              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4919              So fix it.  */
4920           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4921             {
4922               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4923               valist = build_fold_addr_expr_with_type (valist, p1);
4924             }
4925           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4926         }
4927       else
4928         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4929
4930       if (!targetm.gimplify_va_arg_expr)
4931         /* FIXME:Once most targets are converted we should merely
4932            assert this is non-null.  */
4933         return GS_ALL_DONE;
4934
4935       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4936       return GS_OK;
4937     }
4938 }
4939
4940 /* Expand EXP, a call to __builtin_va_end.  */
4941
4942 static rtx
4943 expand_builtin_va_end (tree exp)
4944 {
4945   tree valist = CALL_EXPR_ARG (exp, 0);
4946
4947   /* Evaluate for side effects, if needed.  I hate macros that don't
4948      do that.  */
4949   if (TREE_SIDE_EFFECTS (valist))
4950     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4951
4952   return const0_rtx;
4953 }
4954
4955 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
4956    builtin rather than just as an assignment in stdarg.h because of the
4957    nastiness of array-type va_list types.  */
4958
4959 static rtx
4960 expand_builtin_va_copy (tree exp)
4961 {
4962   tree dst, src, t;
4963
4964   dst = CALL_EXPR_ARG (exp, 0);
4965   src = CALL_EXPR_ARG (exp, 1);
4966
4967   dst = stabilize_va_list (dst, 1);
4968   src = stabilize_va_list (src, 0);
4969
4970   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4971
4972   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4973     {
4974       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4975       TREE_SIDE_EFFECTS (t) = 1;
4976       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4977     }
4978   else
4979     {
4980       rtx dstb, srcb, size;
4981
4982       /* Evaluate to pointers.  */
4983       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4984       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4985       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4986                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
4987
4988       dstb = convert_memory_address (Pmode, dstb);
4989       srcb = convert_memory_address (Pmode, srcb);
4990
4991       /* "Dereference" to BLKmode memories.  */
4992       dstb = gen_rtx_MEM (BLKmode, dstb);
4993       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4994       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4995       srcb = gen_rtx_MEM (BLKmode, srcb);
4996       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4997       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4998
4999       /* Copy.  */
5000       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
5001     }
5002
5003   return const0_rtx;
5004 }
5005
5006 /* Expand a call to one of the builtin functions __builtin_frame_address or
5007    __builtin_return_address.  */
5008
5009 static rtx
5010 expand_builtin_frame_address (tree fndecl, tree exp)
5011 {
5012   /* The argument must be a nonnegative integer constant.
5013      It counts the number of frames to scan up the stack.
5014      The value is the return address saved in that frame.  */
5015   if (call_expr_nargs (exp) == 0)
5016     /* Warning about missing arg was already issued.  */
5017     return const0_rtx;
5018   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
5019     {
5020       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5021         error ("invalid argument to %<__builtin_frame_address%>");
5022       else
5023         error ("invalid argument to %<__builtin_return_address%>");
5024       return const0_rtx;
5025     }
5026   else
5027     {
5028       rtx tem
5029         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
5030                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
5031
5032       /* Some ports cannot access arbitrary stack frames.  */
5033       if (tem == NULL)
5034         {
5035           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5036             warning (0, "unsupported argument to %<__builtin_frame_address%>");
5037           else
5038             warning (0, "unsupported argument to %<__builtin_return_address%>");
5039           return const0_rtx;
5040         }
5041
5042       /* For __builtin_frame_address, return what we've got.  */
5043       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5044         return tem;
5045
5046       if (!REG_P (tem)
5047           && ! CONSTANT_P (tem))
5048         tem = copy_to_mode_reg (Pmode, tem);
5049       return tem;
5050     }
5051 }
5052
5053 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if
5054    we failed and the caller should emit a normal call, otherwise try to get
5055    the result in TARGET, if convenient.  */
5056
5057 static rtx
5058 expand_builtin_alloca (tree exp, rtx target)
5059 {
5060   rtx op0;
5061   rtx result;
5062
5063   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
5064      should always expand to function calls.  These can be intercepted
5065      in libmudflap.  */
5066   if (flag_mudflap)
5067     return NULL_RTX;
5068
5069   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5070     return NULL_RTX;
5071
5072   /* Compute the argument.  */
5073   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
5074
5075   /* Allocate the desired space.  */
5076   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
5077   result = convert_memory_address (ptr_mode, result);
5078
5079   return result;
5080 }
5081
5082 /* Expand a call to a bswap builtin with argument ARG0.  MODE
5083    is the mode to expand with.  */
5084
5085 static rtx
5086 expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
5087 {
5088   enum machine_mode mode;
5089   tree arg;
5090   rtx op0;
5091
5092   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5093     return NULL_RTX;
5094
5095   arg = CALL_EXPR_ARG (exp, 0);
5096   mode = TYPE_MODE (TREE_TYPE (arg));
5097   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5098
5099   target = expand_unop (mode, bswap_optab, op0, target, 1);
5100
5101   gcc_assert (target);
5102
5103   return convert_to_mode (mode, target, 0);
5104 }
5105
5106 /* Expand a call to a unary builtin in EXP.
5107    Return NULL_RTX if a normal call should be emitted rather than expanding the
5108    function in-line.  If convenient, the result should be placed in TARGET.
5109    SUBTARGET may be used as the target for computing one of EXP's operands.  */
5110
5111 static rtx
5112 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
5113                      rtx subtarget, optab op_optab)
5114 {
5115   rtx op0;
5116
5117   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5118     return NULL_RTX;
5119
5120   /* Compute the argument.  */
5121   op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5122                      VOIDmode, EXPAND_NORMAL);
5123   /* Compute op, into TARGET if possible.
5124      Set TARGET to wherever the result comes back.  */
5125   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
5126                         op_optab, op0, target, 1);
5127   gcc_assert (target);
5128
5129   return convert_to_mode (target_mode, target, 0);
5130 }
5131
5132 /* If the string passed to fputs is a constant and is one character
5133    long, we attempt to transform this call into __builtin_fputc().  */
5134
5135 static rtx
5136 expand_builtin_fputs (tree exp, rtx target, bool unlocked)
5137 {
5138   /* Verify the arguments in the original call.  */
5139   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5140     {
5141       tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5142                                         CALL_EXPR_ARG (exp, 1),
5143                                         (target == const0_rtx),
5144                                         unlocked, NULL_TREE);
5145       if (result)
5146         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
5147     }
5148   return NULL_RTX;
5149 }
5150
5151 /* Expand a call to __builtin_expect.  We just return our argument 
5152    as the builtin_expect semantic should've been already executed by
5153    tree branch prediction pass. */
5154
5155 static rtx
5156 expand_builtin_expect (tree exp, rtx target)
5157 {
5158   tree arg, c;
5159
5160   if (call_expr_nargs (exp) < 2)
5161     return const0_rtx;
5162   arg = CALL_EXPR_ARG (exp, 0);
5163   c = CALL_EXPR_ARG (exp, 1);
5164
5165   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5166   /* When guessing was done, the hints should be already stripped away.  */
5167   gcc_assert (!flag_guess_branch_prob
5168               || optimize == 0 || errorcount || sorrycount);
5169   return target;
5170 }
5171
5172 void
5173 expand_builtin_trap (void)
5174 {
5175 #ifdef HAVE_trap
5176   if (HAVE_trap)
5177     emit_insn (gen_trap ());
5178   else
5179 #endif
5180     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5181   emit_barrier ();
5182 }
5183
5184 /* Expand EXP, a call to fabs, fabsf or fabsl.
5185    Return NULL_RTX if a normal call should be emitted rather than expanding
5186    the function inline.  If convenient, the result should be placed
5187    in TARGET.  SUBTARGET may be used as the target for computing
5188    the operand.  */
5189
5190 static rtx
5191 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
5192 {
5193   enum machine_mode mode;
5194   tree arg;
5195   rtx op0;
5196
5197   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5198     return NULL_RTX;
5199
5200   arg = CALL_EXPR_ARG (exp, 0);
5201   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
5202   mode = TYPE_MODE (TREE_TYPE (arg));
5203   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5204   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5205 }
5206
5207 /* Expand EXP, a call to copysign, copysignf, or copysignl.
5208    Return NULL is a normal call should be emitted rather than expanding the
5209    function inline.  If convenient, the result should be placed in TARGET.
5210    SUBTARGET may be used as the target for computing the operand.  */
5211
5212 static rtx
5213 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
5214 {
5215   rtx op0, op1;
5216   tree arg;
5217
5218   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5219     return NULL_RTX;
5220
5221   arg = CALL_EXPR_ARG (exp, 0);
5222   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5223
5224   arg = CALL_EXPR_ARG (exp, 1);
5225   op1 = expand_normal (arg);
5226
5227   return expand_copysign (op0, op1, target);
5228 }
5229
5230 /* Create a new constant string literal and return a char* pointer to it.
5231    The STRING_CST value is the LEN characters at STR.  */
5232 tree
5233 build_string_literal (int len, const char *str)
5234 {
5235   tree t, elem, index, type;
5236
5237   t = build_string (len, str);
5238   elem = build_type_variant (char_type_node, 1, 0);
5239   index = build_index_type (size_int (len - 1));
5240   type = build_array_type (elem, index);
5241   TREE_TYPE (t) = type;
5242   TREE_CONSTANT (t) = 1;
5243   TREE_READONLY (t) = 1;
5244   TREE_STATIC (t) = 1;
5245
5246   type = build_pointer_type (elem);
5247   t = build1 (ADDR_EXPR, type,
5248               build4 (ARRAY_REF, elem,
5249                       t, integer_zero_node, NULL_TREE, NULL_TREE));
5250   return t;
5251 }
5252
5253 /* Expand EXP, a call to printf or printf_unlocked.
5254    Return NULL_RTX if a normal call should be emitted rather than transforming
5255    the function inline.  If convenient, the result should be placed in
5256    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
5257    call.  */
5258 static rtx
5259 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
5260                        bool unlocked)
5261 {
5262   /* If we're using an unlocked function, assume the other unlocked
5263      functions exist explicitly.  */
5264   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5265     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5266   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5267     : implicit_built_in_decls[BUILT_IN_PUTS];
5268   const char *fmt_str;
5269   tree fn = 0;
5270   tree fmt, arg;
5271   int nargs = call_expr_nargs (exp);
5272
5273   /* If the return value is used, don't do the transformation.  */
5274   if (target != const0_rtx)
5275     return NULL_RTX;
5276
5277   /* Verify the required arguments in the original call.  */
5278   if (nargs == 0)
5279     return NULL_RTX;
5280   fmt = CALL_EXPR_ARG (exp, 0);
5281   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5282     return NULL_RTX;
5283
5284   /* Check whether the format is a literal string constant.  */
5285   fmt_str = c_getstr (fmt);
5286   if (fmt_str == NULL)
5287     return NULL_RTX;
5288
5289   if (!init_target_chars ())
5290     return NULL_RTX;
5291
5292   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
5293   if (strcmp (fmt_str, target_percent_s_newline) == 0)
5294     {
5295       if ((nargs != 2)
5296           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5297         return NULL_RTX;
5298       if (fn_puts)
5299         fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
5300     }
5301   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
5302   else if (strcmp (fmt_str, target_percent_c) == 0)
5303     {
5304       if ((nargs != 2)
5305           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5306         return NULL_RTX;
5307       if (fn_putchar)
5308         fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
5309     }
5310   else
5311     {
5312       /* We can't handle anything else with % args or %% ... yet.  */
5313       if (strchr (fmt_str, target_percent))
5314         return NULL_RTX;
5315
5316       if (nargs > 1)
5317         return NULL_RTX;
5318
5319       /* If the format specifier was "", printf does nothing.  */
5320       if (fmt_str[0] == '\0')
5321         return const0_rtx;
5322       /* If the format specifier has length of 1, call putchar.  */
5323       if (fmt_str[1] == '\0')
5324         {
5325           /* Given printf("c"), (where c is any one character,)
5326              convert "c"[0] to an int and pass that to the replacement
5327              function.  */
5328           arg = build_int_cst (NULL_TREE, fmt_str[0]);
5329           if (fn_putchar)
5330             fn = build_call_expr (fn_putchar, 1, arg);
5331         }
5332       else
5333         {
5334           /* If the format specifier was "string\n", call puts("string").  */
5335           size_t len = strlen (fmt_str);
5336           if ((unsigned char)fmt_str[len - 1] == target_newline)
5337             {
5338               /* Create a NUL-terminated string that's one char shorter
5339                  than the original, stripping off the trailing '\n'.  */
5340               char *newstr = XALLOCAVEC (char, len);
5341               memcpy (newstr, fmt_str, len - 1);
5342               newstr[len - 1] = 0;
5343               arg = build_string_literal (len, newstr);
5344               if (fn_puts)
5345                 fn = build_call_expr (fn_puts, 1, arg);
5346             }
5347           else
5348             /* We'd like to arrange to call fputs(string,stdout) here,
5349                but we need stdout and don't have a way to get it yet.  */
5350             return NULL_RTX;
5351         }
5352     }
5353
5354   if (!fn)
5355     return NULL_RTX;
5356   if (TREE_CODE (fn) == CALL_EXPR)
5357     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5358   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5359 }
5360
5361 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5362    Return NULL_RTX if a normal call should be emitted rather than transforming
5363    the function inline.  If convenient, the result should be placed in
5364    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5365    call.  */
5366 static rtx
5367 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5368                         bool unlocked)
5369 {
5370   /* If we're using an unlocked function, assume the other unlocked
5371      functions exist explicitly.  */
5372   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5373     : implicit_built_in_decls[BUILT_IN_FPUTC];
5374   tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5375     : implicit_built_in_decls[BUILT_IN_FPUTS];
5376   const char *fmt_str;
5377   tree fn = 0;
5378   tree fmt, fp, arg;
5379   int nargs = call_expr_nargs (exp);
5380
5381   /* If the return value is used, don't do the transformation.  */
5382   if (target != const0_rtx)
5383     return NULL_RTX;
5384
5385   /* Verify the required arguments in the original call.  */
5386   if (nargs < 2)
5387     return NULL_RTX;
5388   fp = CALL_EXPR_ARG (exp, 0);
5389   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5390     return NULL_RTX;
5391   fmt = CALL_EXPR_ARG (exp, 1);
5392   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5393     return NULL_RTX;
5394
5395   /* Check whether the format is a literal string constant.  */
5396   fmt_str = c_getstr (fmt);
5397   if (fmt_str == NULL)
5398     return NULL_RTX;
5399
5400   if (!init_target_chars ())
5401     return NULL_RTX;
5402
5403   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5404   if (strcmp (fmt_str, target_percent_s) == 0)
5405     {
5406       if ((nargs != 3)
5407           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5408         return NULL_RTX;
5409       arg = CALL_EXPR_ARG (exp, 2);
5410       if (fn_fputs)
5411         fn = build_call_expr (fn_fputs, 2, arg, fp);
5412     }
5413   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5414   else if (strcmp (fmt_str, target_percent_c) == 0)
5415     {
5416       if ((nargs != 3)
5417           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5418         return NULL_RTX;
5419       arg = CALL_EXPR_ARG (exp, 2);
5420       if (fn_fputc)
5421         fn = build_call_expr (fn_fputc, 2, arg, fp);
5422     }
5423   else
5424     {
5425       /* We can't handle anything else with % args or %% ... yet.  */
5426       if (strchr (fmt_str, target_percent))
5427         return NULL_RTX;
5428
5429       if (nargs > 2)
5430         return NULL_RTX;
5431
5432       /* If the format specifier was "", fprintf does nothing.  */
5433       if (fmt_str[0] == '\0')
5434         {
5435           /* Evaluate and ignore FILE* argument for side-effects.  */
5436           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5437           return const0_rtx;
5438         }
5439
5440       /* When "string" doesn't contain %, replace all cases of
5441          fprintf(stream,string) with fputs(string,stream).  The fputs
5442          builtin will take care of special cases like length == 1.  */
5443       if (fn_fputs)
5444         fn = build_call_expr (fn_fputs, 2, fmt, fp);
5445     }
5446
5447   if (!fn)
5448     return NULL_RTX;
5449   if (TREE_CODE (fn) == CALL_EXPR)
5450     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5451   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5452 }
5453
5454 /* Expand a call EXP to sprintf.  Return NULL_RTX if
5455    a normal call should be emitted rather than expanding the function
5456    inline.  If convenient, the result should be placed in TARGET with
5457    mode MODE.  */
5458
5459 static rtx
5460 expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
5461 {
5462   tree dest, fmt;
5463   const char *fmt_str;
5464   int nargs = call_expr_nargs (exp);
5465
5466   /* Verify the required arguments in the original call.  */
5467   if (nargs < 2)
5468     return NULL_RTX;
5469   dest = CALL_EXPR_ARG (exp, 0);
5470   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5471     return NULL_RTX;
5472   fmt = CALL_EXPR_ARG (exp, 0);
5473   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5474     return NULL_RTX;
5475
5476   /* Check whether the format is a literal string constant.  */
5477   fmt_str = c_getstr (fmt);
5478   if (fmt_str == NULL)
5479     return NULL_RTX;
5480
5481   if (!init_target_chars ())
5482     return NULL_RTX;
5483
5484   /* If the format doesn't contain % args or %%, use strcpy.  */
5485   if (strchr (fmt_str, target_percent) == 0)
5486     {
5487       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5488       tree exp;
5489
5490       if ((nargs > 2) || ! fn)
5491         return NULL_RTX;
5492       expand_expr (build_call_expr (fn, 2, dest, fmt),
5493                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5494       if (target == const0_rtx)
5495         return const0_rtx;
5496       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5497       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5498     }
5499   /* If the format is "%s", use strcpy if the result isn't used.  */
5500   else if (strcmp (fmt_str, target_percent_s) == 0)
5501     {
5502       tree fn, arg, len;
5503       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5504
5505       if (! fn)
5506         return NULL_RTX;
5507       if (nargs != 3)
5508         return NULL_RTX;
5509       arg = CALL_EXPR_ARG (exp, 2);
5510       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5511         return NULL_RTX;
5512
5513       if (target != const0_rtx)
5514         {
5515           len = c_strlen (arg, 1);
5516           if (! len || TREE_CODE (len) != INTEGER_CST)
5517             return NULL_RTX;
5518         }
5519       else
5520         len = NULL_TREE;
5521
5522       expand_expr (build_call_expr (fn, 2, dest, arg),
5523                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5524
5525       if (target == const0_rtx)
5526         return const0_rtx;
5527       return expand_expr (len, target, mode, EXPAND_NORMAL);
5528     }
5529
5530   return NULL_RTX;
5531 }
5532
5533 /* Expand a call to either the entry or exit function profiler.  */
5534
5535 static rtx
5536 expand_builtin_profile_func (bool exitp)
5537 {
5538   rtx this, which;
5539
5540   this = DECL_RTL (current_function_decl);
5541   gcc_assert (MEM_P (this));
5542   this = XEXP (this, 0);
5543
5544   if (exitp)
5545     which = profile_function_exit_libfunc;
5546   else
5547     which = profile_function_entry_libfunc;
5548
5549   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5550                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5551                                                  0),
5552                      Pmode);
5553
5554   return const0_rtx;
5555 }
5556
5557 /* Expand a call to __builtin___clear_cache.  */
5558
5559 static rtx
5560 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5561 {
5562 #ifndef HAVE_clear_cache
5563 #ifdef CLEAR_INSN_CACHE
5564   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5565      does something.  Just do the default expansion to a call to
5566      __clear_cache().  */
5567   return NULL_RTX;
5568 #else
5569   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5570      does nothing.  There is no need to call it.  Do nothing.  */
5571   return const0_rtx;
5572 #endif /* CLEAR_INSN_CACHE */
5573 #else
5574   /* We have a "clear_cache" insn, and it will handle everything.  */
5575   tree begin, end;
5576   rtx begin_rtx, end_rtx;
5577   enum insn_code icode;
5578
5579   /* We must not expand to a library call.  If we did, any
5580      fallback library function in libgcc that might contain a call to
5581      __builtin___clear_cache() would recurse infinitely.  */
5582   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5583     {
5584       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5585       return const0_rtx;
5586     }
5587
5588   if (HAVE_clear_cache)
5589     {
5590       icode = CODE_FOR_clear_cache;
5591
5592       begin = CALL_EXPR_ARG (exp, 0);
5593       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5594       begin_rtx = convert_memory_address (Pmode, begin_rtx);
5595       if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5596         begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5597
5598       end = CALL_EXPR_ARG (exp, 1);
5599       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5600       end_rtx = convert_memory_address (Pmode, end_rtx);
5601       if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5602         end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5603
5604       emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5605     }
5606   return const0_rtx;
5607 #endif /* HAVE_clear_cache */
5608 }
5609
5610 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5611
5612 static rtx
5613 round_trampoline_addr (rtx tramp)
5614 {
5615   rtx temp, addend, mask;
5616
5617   /* If we don't need too much alignment, we'll have been guaranteed
5618      proper alignment by get_trampoline_type.  */
5619   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5620     return tramp;
5621
5622   /* Round address up to desired boundary.  */
5623   temp = gen_reg_rtx (Pmode);
5624   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5625   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5626
5627   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5628                                temp, 0, OPTAB_LIB_WIDEN);
5629   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5630                                temp, 0, OPTAB_LIB_WIDEN);
5631
5632   return tramp;
5633 }
5634
5635 static rtx
5636 expand_builtin_init_trampoline (tree exp)
5637 {
5638   tree t_tramp, t_func, t_chain;
5639   rtx r_tramp, r_func, r_chain;
5640 #ifdef TRAMPOLINE_TEMPLATE
5641   rtx blktramp;
5642 #endif
5643
5644   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
5645                          POINTER_TYPE, VOID_TYPE))
5646     return NULL_RTX;
5647
5648   t_tramp = CALL_EXPR_ARG (exp, 0);
5649   t_func = CALL_EXPR_ARG (exp, 1);
5650   t_chain = CALL_EXPR_ARG (exp, 2);
5651
5652   r_tramp = expand_normal (t_tramp);
5653   r_func = expand_normal (t_func);
5654   r_chain = expand_normal (t_chain);
5655
5656   /* Generate insns to initialize the trampoline.  */
5657   r_tramp = round_trampoline_addr (r_tramp);
5658 #ifdef TRAMPOLINE_TEMPLATE
5659   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5660   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5661   emit_block_move (blktramp, assemble_trampoline_template (),
5662                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5663 #endif
5664   trampolines_created = 1;
5665   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5666
5667   return const0_rtx;
5668 }
5669
5670 static rtx
5671 expand_builtin_adjust_trampoline (tree exp)
5672 {
5673   rtx tramp;
5674
5675   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5676     return NULL_RTX;
5677
5678   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
5679   tramp = round_trampoline_addr (tramp);
5680 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5681   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5682 #endif
5683
5684   return tramp;
5685 }
5686
5687 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
5688    function.  The function first checks whether the back end provides
5689    an insn to implement signbit for the respective mode.  If not, it
5690    checks whether the floating point format of the value is such that
5691    the sign bit can be extracted.  If that is not the case, the
5692    function returns NULL_RTX to indicate that a normal call should be
5693    emitted rather than expanding the function in-line.  EXP is the
5694    expression that is a call to the builtin function; if convenient,
5695    the result should be placed in TARGET.  */
5696 static rtx
5697 expand_builtin_signbit (tree exp, rtx target)
5698 {
5699   const struct real_format *fmt;
5700   enum machine_mode fmode, imode, rmode;
5701   HOST_WIDE_INT hi, lo;
5702   tree arg;
5703   int word, bitpos;
5704   enum insn_code icode;
5705   rtx temp;
5706
5707   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5708     return NULL_RTX;
5709
5710   arg = CALL_EXPR_ARG (exp, 0);
5711   fmode = TYPE_MODE (TREE_TYPE (arg));
5712   rmode = TYPE_MODE (TREE_TYPE (exp));
5713   fmt = REAL_MODE_FORMAT (fmode);
5714
5715   arg = builtin_save_expr (arg);
5716
5717   /* Expand the argument yielding a RTX expression. */
5718   temp = expand_normal (arg);
5719
5720   /* Check if the back end provides an insn that handles signbit for the
5721      argument's mode. */
5722   icode = signbit_optab->handlers [(int) fmode].insn_code;
5723   if (icode != CODE_FOR_nothing)
5724     {
5725       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
5726       emit_unop_insn (icode, target, temp, UNKNOWN);
5727       return target;
5728     }
5729
5730   /* For floating point formats without a sign bit, implement signbit
5731      as "ARG < 0.0".  */
5732   bitpos = fmt->signbit_ro;
5733   if (bitpos < 0)
5734   {
5735     /* But we can't do this if the format supports signed zero.  */
5736     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5737       return NULL_RTX;
5738
5739     arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5740                        build_real (TREE_TYPE (arg), dconst0));
5741     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5742   }
5743
5744   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5745     {
5746       imode = int_mode_for_mode (fmode);
5747       if (imode == BLKmode)
5748         return NULL_RTX;
5749       temp = gen_lowpart (imode, temp);
5750     }
5751   else
5752     {
5753       imode = word_mode;
5754       /* Handle targets with different FP word orders.  */
5755       if (FLOAT_WORDS_BIG_ENDIAN)
5756         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5757       else
5758         word = bitpos / BITS_PER_WORD;
5759       temp = operand_subword_force (temp, word, fmode);
5760       bitpos = bitpos % BITS_PER_WORD;
5761     }
5762
5763   /* Force the intermediate word_mode (or narrower) result into a
5764      register.  This avoids attempting to create paradoxical SUBREGs
5765      of floating point modes below.  */
5766   temp = force_reg (imode, temp);
5767
5768   /* If the bitpos is within the "result mode" lowpart, the operation
5769      can be implement with a single bitwise AND.  Otherwise, we need
5770      a right shift and an AND.  */
5771
5772   if (bitpos < GET_MODE_BITSIZE (rmode))
5773     {
5774       if (bitpos < HOST_BITS_PER_WIDE_INT)
5775         {
5776           hi = 0;
5777           lo = (HOST_WIDE_INT) 1 << bitpos;
5778         }
5779       else
5780         {
5781           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5782           lo = 0;
5783         }
5784
5785       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5786         temp = gen_lowpart (rmode, temp);
5787       temp = expand_binop (rmode, and_optab, temp,
5788                            immed_double_const (lo, hi, rmode),
5789                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5790     }
5791   else
5792     {
5793       /* Perform a logical right shift to place the signbit in the least
5794          significant bit, then truncate the result to the desired mode
5795          and mask just this bit.  */
5796       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5797                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5798       temp = gen_lowpart (rmode, temp);
5799       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5800                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5801     }
5802
5803   return temp;
5804 }
5805
5806 /* Expand fork or exec calls.  TARGET is the desired target of the
5807    call.  EXP is the call. FN is the
5808    identificator of the actual function.  IGNORE is nonzero if the
5809    value is to be ignored.  */
5810
5811 static rtx
5812 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5813 {
5814   tree id, decl;
5815   tree call;
5816
5817   /* If we are not profiling, just call the function.  */
5818   if (!profile_arc_flag)
5819     return NULL_RTX;
5820
5821   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5822      compiler, so the code does not diverge, and the wrapper may run the
5823      code necessary for keeping the profiling sane.  */
5824
5825   switch (DECL_FUNCTION_CODE (fn))
5826     {
5827     case BUILT_IN_FORK:
5828       id = get_identifier ("__gcov_fork");
5829       break;
5830
5831     case BUILT_IN_EXECL:
5832       id = get_identifier ("__gcov_execl");
5833       break;
5834
5835     case BUILT_IN_EXECV:
5836       id = get_identifier ("__gcov_execv");
5837       break;
5838
5839     case BUILT_IN_EXECLP:
5840       id = get_identifier ("__gcov_execlp");
5841       break;
5842
5843     case BUILT_IN_EXECLE:
5844       id = get_identifier ("__gcov_execle");
5845       break;
5846
5847     case BUILT_IN_EXECVP:
5848       id = get_identifier ("__gcov_execvp");
5849       break;
5850
5851     case BUILT_IN_EXECVE:
5852       id = get_identifier ("__gcov_execve");
5853       break;
5854
5855     default:
5856       gcc_unreachable ();
5857     }
5858
5859   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5860   DECL_EXTERNAL (decl) = 1;
5861   TREE_PUBLIC (decl) = 1;
5862   DECL_ARTIFICIAL (decl) = 1;
5863   TREE_NOTHROW (decl) = 1;
5864   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5865   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5866   call = rewrite_call_expr (exp, 0, decl, 0);
5867   return expand_call (call, target, ignore);
5868  }
5869   
5870
5871 \f
5872 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5873    the pointer in these functions is void*, the tree optimizers may remove
5874    casts.  The mode computed in expand_builtin isn't reliable either, due
5875    to __sync_bool_compare_and_swap.
5876
5877    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5878    group of builtins.  This gives us log2 of the mode size.  */
5879
5880 static inline enum machine_mode
5881 get_builtin_sync_mode (int fcode_diff)
5882 {
5883   /* The size is not negotiable, so ask not to get BLKmode in return
5884      if the target indicates that a smaller size would be better.  */
5885   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5886 }
5887
5888 /* Expand the memory expression LOC and return the appropriate memory operand
5889    for the builtin_sync operations.  */
5890
5891 static rtx
5892 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5893 {
5894   rtx addr, mem;
5895
5896   addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
5897
5898   /* Note that we explicitly do not want any alias information for this
5899      memory, so that we kill all other live memories.  Otherwise we don't
5900      satisfy the full barrier semantics of the intrinsic.  */
5901   mem = validize_mem (gen_rtx_MEM (mode, addr));
5902
5903   set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5904   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5905   MEM_VOLATILE_P (mem) = 1;
5906
5907   return mem;
5908 }
5909
5910 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5911    EXP is the CALL_EXPR.  CODE is the rtx code
5912    that corresponds to the arithmetic or logical operation from the name;
5913    an exception here is that NOT actually means NAND.  TARGET is an optional
5914    place for us to store the results; AFTER is true if this is the
5915    fetch_and_xxx form.  IGNORE is true if we don't actually care about
5916    the result of the operation at all.  */
5917
5918 static rtx
5919 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5920                                enum rtx_code code, bool after,
5921                                rtx target, bool ignore)
5922 {
5923   rtx val, mem;
5924   enum machine_mode old_mode;
5925
5926   /* Expand the operands.  */
5927   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5928
5929   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5930   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5931      of CONST_INTs, where we know the old_mode only from the call argument.  */
5932   old_mode = GET_MODE (val);
5933   if (old_mode == VOIDmode)
5934     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5935   val = convert_modes (mode, old_mode, val, 1);
5936
5937   if (ignore)
5938     return expand_sync_operation (mem, val, code);
5939   else
5940     return expand_sync_fetch_operation (mem, val, code, after, target);
5941 }
5942
5943 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5944    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5945    true if this is the boolean form.  TARGET is a place for us to store the
5946    results; this is NOT optional if IS_BOOL is true.  */
5947
5948 static rtx
5949 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5950                                  bool is_bool, rtx target)
5951 {
5952   rtx old_val, new_val, mem;
5953   enum machine_mode old_mode;
5954
5955   /* Expand the operands.  */
5956   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5957
5958
5959   old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
5960                          mode, EXPAND_NORMAL);
5961   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5962      of CONST_INTs, where we know the old_mode only from the call argument.  */
5963   old_mode = GET_MODE (old_val);
5964   if (old_mode == VOIDmode)
5965     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5966   old_val = convert_modes (mode, old_mode, old_val, 1);
5967
5968   new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
5969                          mode, EXPAND_NORMAL);
5970   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5971      of CONST_INTs, where we know the old_mode only from the call argument.  */
5972   old_mode = GET_MODE (new_val);
5973   if (old_mode == VOIDmode)
5974     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
5975   new_val = convert_modes (mode, old_mode, new_val, 1);
5976
5977   if (is_bool)
5978     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5979   else
5980     return expand_val_compare_and_swap (mem, old_val, new_val, target);
5981 }
5982
5983 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5984    general form is actually an atomic exchange, and some targets only
5985    support a reduced form with the second argument being a constant 1.
5986    EXP is the CALL_EXPR; TARGET is an optional place for us to store 
5987    the results.  */
5988
5989 static rtx
5990 expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
5991                                   rtx target)
5992 {
5993   rtx val, mem;
5994   enum machine_mode old_mode;
5995
5996   /* Expand the operands.  */
5997   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5998   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5999   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
6000      of CONST_INTs, where we know the old_mode only from the call argument.  */
6001   old_mode = GET_MODE (val);
6002   if (old_mode == VOIDmode)
6003     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6004   val = convert_modes (mode, old_mode, val, 1);
6005
6006   return expand_sync_lock_test_and_set (mem, val, target);
6007 }
6008
6009 /* Expand the __sync_synchronize intrinsic.  */
6010
6011 static void
6012 expand_builtin_synchronize (void)
6013 {
6014   tree x;
6015
6016 #ifdef HAVE_memory_barrier
6017   if (HAVE_memory_barrier)
6018     {
6019       emit_insn (gen_memory_barrier ());
6020       return;
6021     }
6022 #endif
6023
6024   if (synchronize_libfunc != NULL_RTX)
6025     {
6026       emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6027       return;
6028     }
6029
6030   /* If no explicit memory barrier instruction is available, create an
6031      empty asm stmt with a memory clobber.  */
6032   x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6033               tree_cons (NULL, build_string (6, "memory"), NULL));
6034   ASM_VOLATILE_P (x) = 1;
6035   expand_asm_expr (x);
6036 }
6037
6038 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
6039
6040 static void
6041 expand_builtin_lock_release (enum machine_mode mode, tree exp)
6042 {
6043   enum insn_code icode;
6044   rtx mem, insn;
6045   rtx val = const0_rtx;
6046
6047   /* Expand the operands.  */
6048   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6049
6050   /* If there is an explicit operation in the md file, use it.  */
6051   icode = sync_lock_release[mode];
6052   if (icode != CODE_FOR_nothing)
6053     {
6054       if (!insn_data[icode].operand[1].predicate (val, mode))
6055         val = force_reg (mode, val);
6056
6057       insn = GEN_FCN (icode) (mem, val);
6058       if (insn)
6059         {
6060           emit_insn (insn);
6061           return;
6062         }
6063     }
6064
6065   /* Otherwise we can implement this operation by emitting a barrier
6066      followed by a store of zero.  */
6067   expand_builtin_synchronize ();
6068   emit_move_insn (mem, val);
6069 }
6070 \f
6071 /* Expand an expression EXP that calls a built-in function,
6072    with result going to TARGET if that's convenient
6073    (and in mode MODE if that's convenient).
6074    SUBTARGET may be used as the target for computing one of EXP's operands.
6075    IGNORE is nonzero if the value is to be ignored.  */
6076
6077 rtx
6078 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6079                 int ignore)
6080 {
6081   tree fndecl = get_callee_fndecl (exp);
6082   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6083   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
6084
6085   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6086     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
6087
6088   /* When not optimizing, generate calls to library functions for a certain
6089      set of builtins.  */
6090   if (!optimize
6091       && !called_as_built_in (fndecl)
6092       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
6093       && fcode != BUILT_IN_ALLOCA)
6094     return expand_call (exp, target, ignore);
6095
6096   /* The built-in function expanders test for target == const0_rtx
6097      to determine whether the function's result will be ignored.  */
6098   if (ignore)
6099     target = const0_rtx;
6100
6101   /* If the result of a pure or const built-in function is ignored, and
6102      none of its arguments are volatile, we can avoid expanding the
6103      built-in call and just evaluate the arguments for side-effects.  */
6104   if (target == const0_rtx
6105       && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
6106     {
6107       bool volatilep = false;
6108       tree arg;
6109       call_expr_arg_iterator iter;
6110
6111       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6112         if (TREE_THIS_VOLATILE (arg))
6113           {
6114             volatilep = true;
6115             break;
6116           }
6117
6118       if (! volatilep)
6119         {
6120           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6121             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
6122           return const0_rtx;
6123         }
6124     }
6125
6126   switch (fcode)
6127     {
6128     CASE_FLT_FN (BUILT_IN_FABS):
6129       target = expand_builtin_fabs (exp, target, subtarget);
6130       if (target)
6131         return target;
6132       break;
6133
6134     CASE_FLT_FN (BUILT_IN_COPYSIGN):
6135       target = expand_builtin_copysign (exp, target, subtarget);
6136       if (target)
6137         return target;
6138       break;
6139
6140       /* Just do a normal library call if we were unable to fold
6141          the values.  */
6142     CASE_FLT_FN (BUILT_IN_CABS):
6143       break;
6144
6145     CASE_FLT_FN (BUILT_IN_EXP):
6146     CASE_FLT_FN (BUILT_IN_EXP10):
6147     CASE_FLT_FN (BUILT_IN_POW10):
6148     CASE_FLT_FN (BUILT_IN_EXP2):
6149     CASE_FLT_FN (BUILT_IN_EXPM1):
6150     CASE_FLT_FN (BUILT_IN_LOGB):
6151     CASE_FLT_FN (BUILT_IN_LOG):
6152     CASE_FLT_FN (BUILT_IN_LOG10):
6153     CASE_FLT_FN (BUILT_IN_LOG2):
6154     CASE_FLT_FN (BUILT_IN_LOG1P):
6155     CASE_FLT_FN (BUILT_IN_TAN):
6156     CASE_FLT_FN (BUILT_IN_ASIN):
6157     CASE_FLT_FN (BUILT_IN_ACOS):
6158     CASE_FLT_FN (BUILT_IN_ATAN):
6159       /* Treat these like sqrt only if unsafe math optimizations are allowed,
6160          because of possible accuracy problems.  */
6161       if (! flag_unsafe_math_optimizations)
6162         break;
6163     CASE_FLT_FN (BUILT_IN_SQRT):
6164     CASE_FLT_FN (BUILT_IN_FLOOR):
6165     CASE_FLT_FN (BUILT_IN_CEIL):
6166     CASE_FLT_FN (BUILT_IN_TRUNC):
6167     CASE_FLT_FN (BUILT_IN_ROUND):
6168     CASE_FLT_FN (BUILT_IN_NEARBYINT):
6169     CASE_FLT_FN (BUILT_IN_RINT):
6170       target = expand_builtin_mathfn (exp, target, subtarget);
6171       if (target)
6172         return target;
6173       break;
6174
6175     CASE_FLT_FN (BUILT_IN_ILOGB):
6176       if (! flag_unsafe_math_optimizations)
6177         break;
6178     CASE_FLT_FN (BUILT_IN_ISINF):
6179     CASE_FLT_FN (BUILT_IN_FINITE):
6180     case BUILT_IN_ISFINITE:
6181     case BUILT_IN_ISNORMAL:
6182       target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6183       if (target)
6184         return target;
6185       break;
6186
6187     CASE_FLT_FN (BUILT_IN_LCEIL):
6188     CASE_FLT_FN (BUILT_IN_LLCEIL):
6189     CASE_FLT_FN (BUILT_IN_LFLOOR):
6190     CASE_FLT_FN (BUILT_IN_LLFLOOR):
6191       target = expand_builtin_int_roundingfn (exp, target, subtarget);
6192       if (target)
6193         return target;
6194       break;
6195
6196     CASE_FLT_FN (BUILT_IN_LRINT):
6197     CASE_FLT_FN (BUILT_IN_LLRINT):
6198     CASE_FLT_FN (BUILT_IN_LROUND):
6199     CASE_FLT_FN (BUILT_IN_LLROUND):
6200       target = expand_builtin_int_roundingfn_2 (exp, target, subtarget);
6201       if (target)
6202         return target;
6203       break;
6204
6205     CASE_FLT_FN (BUILT_IN_POW):
6206       target = expand_builtin_pow (exp, target, subtarget);
6207       if (target)
6208         return target;
6209       break;
6210
6211     CASE_FLT_FN (BUILT_IN_POWI):
6212       target = expand_builtin_powi (exp, target, subtarget);
6213       if (target)
6214         return target;
6215       break;
6216
6217     CASE_FLT_FN (BUILT_IN_ATAN2):
6218     CASE_FLT_FN (BUILT_IN_LDEXP):
6219     CASE_FLT_FN (BUILT_IN_SCALB):
6220     CASE_FLT_FN (BUILT_IN_SCALBN):
6221     CASE_FLT_FN (BUILT_IN_SCALBLN):
6222       if (! flag_unsafe_math_optimizations)
6223         break;
6224
6225     CASE_FLT_FN (BUILT_IN_FMOD):
6226     CASE_FLT_FN (BUILT_IN_REMAINDER):
6227     CASE_FLT_FN (BUILT_IN_DREM):
6228       target = expand_builtin_mathfn_2 (exp, target, subtarget);
6229       if (target)
6230         return target;
6231       break;
6232
6233     CASE_FLT_FN (BUILT_IN_CEXPI):
6234       target = expand_builtin_cexpi (exp, target, subtarget);
6235       gcc_assert (target);
6236       return target;
6237
6238     CASE_FLT_FN (BUILT_IN_SIN):
6239     CASE_FLT_FN (BUILT_IN_COS):
6240       if (! flag_unsafe_math_optimizations)
6241         break;
6242       target = expand_builtin_mathfn_3 (exp, target, subtarget);
6243       if (target)
6244         return target;
6245       break;
6246
6247     CASE_FLT_FN (BUILT_IN_SINCOS):
6248       if (! flag_unsafe_math_optimizations)
6249         break;
6250       target = expand_builtin_sincos (exp);
6251       if (target)
6252         return target;
6253       break;
6254
6255     case BUILT_IN_APPLY_ARGS:
6256       return expand_builtin_apply_args ();
6257
6258       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6259          FUNCTION with a copy of the parameters described by
6260          ARGUMENTS, and ARGSIZE.  It returns a block of memory
6261          allocated on the stack into which is stored all the registers
6262          that might possibly be used for returning the result of a
6263          function.  ARGUMENTS is the value returned by
6264          __builtin_apply_args.  ARGSIZE is the number of bytes of
6265          arguments that must be copied.  ??? How should this value be
6266          computed?  We'll also need a safe worst case value for varargs
6267          functions.  */
6268     case BUILT_IN_APPLY:
6269       if (!validate_arglist (exp, POINTER_TYPE,
6270                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
6271           && !validate_arglist (exp, REFERENCE_TYPE,
6272                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6273         return const0_rtx;
6274       else
6275         {
6276           rtx ops[3];
6277
6278           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6279           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6280           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6281
6282           return expand_builtin_apply (ops[0], ops[1], ops[2]);
6283         }
6284
6285       /* __builtin_return (RESULT) causes the function to return the
6286          value described by RESULT.  RESULT is address of the block of
6287          memory returned by __builtin_apply.  */
6288     case BUILT_IN_RETURN:
6289       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6290         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6291       return const0_rtx;
6292
6293     case BUILT_IN_SAVEREGS:
6294       return expand_builtin_saveregs ();
6295
6296     case BUILT_IN_ARGS_INFO:
6297       return expand_builtin_args_info (exp);
6298
6299     case BUILT_IN_VA_ARG_PACK:
6300       /* All valid uses of __builtin_va_arg_pack () are removed during
6301          inlining.  */
6302       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6303       return const0_rtx;
6304
6305     case BUILT_IN_VA_ARG_PACK_LEN:
6306       /* All valid uses of __builtin_va_arg_pack_len () are removed during
6307          inlining.  */
6308       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6309       return const0_rtx;
6310
6311       /* Return the address of the first anonymous stack arg.  */
6312     case BUILT_IN_NEXT_ARG:
6313       if (fold_builtin_next_arg (exp, false))
6314         return const0_rtx;
6315       return expand_builtin_next_arg ();
6316
6317     case BUILT_IN_CLEAR_CACHE:
6318       target = expand_builtin___clear_cache (exp);
6319       if (target)
6320         return target;
6321       break;
6322
6323     case BUILT_IN_CLASSIFY_TYPE:
6324       return expand_builtin_classify_type (exp);
6325
6326     case BUILT_IN_CONSTANT_P:
6327       return const0_rtx;
6328
6329     case BUILT_IN_FRAME_ADDRESS:
6330     case BUILT_IN_RETURN_ADDRESS:
6331       return expand_builtin_frame_address (fndecl, exp);
6332
6333     /* Returns the address of the area where the structure is returned.
6334        0 otherwise.  */
6335     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6336       if (call_expr_nargs (exp) != 0
6337           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6338           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6339         return const0_rtx;
6340       else
6341         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6342
6343     case BUILT_IN_ALLOCA:
6344       target = expand_builtin_alloca (exp, target);
6345       if (target)
6346         return target;
6347       break;
6348
6349     case BUILT_IN_STACK_SAVE:
6350       return expand_stack_save ();
6351
6352     case BUILT_IN_STACK_RESTORE:
6353       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6354       return const0_rtx;
6355
6356     case BUILT_IN_BSWAP32:
6357     case BUILT_IN_BSWAP64:
6358       target = expand_builtin_bswap (exp, target, subtarget);
6359
6360       if (target)
6361         return target;
6362       break;
6363
6364     CASE_INT_FN (BUILT_IN_FFS):
6365     case BUILT_IN_FFSIMAX:
6366       target = expand_builtin_unop (target_mode, exp, target,
6367                                     subtarget, ffs_optab);
6368       if (target)
6369         return target;
6370       break;
6371
6372     CASE_INT_FN (BUILT_IN_CLZ):
6373     case BUILT_IN_CLZIMAX:
6374       target = expand_builtin_unop (target_mode, exp, target,
6375                                     subtarget, clz_optab);
6376       if (target)
6377         return target;
6378       break;
6379
6380     CASE_INT_FN (BUILT_IN_CTZ):
6381     case BUILT_IN_CTZIMAX:
6382       target = expand_builtin_unop (target_mode, exp, target,
6383                                     subtarget, ctz_optab);
6384       if (target)
6385         return target;
6386       break;
6387
6388     CASE_INT_FN (BUILT_IN_POPCOUNT):
6389     case BUILT_IN_POPCOUNTIMAX:
6390       target = expand_builtin_unop (target_mode, exp, target,
6391                                     subtarget, popcount_optab);
6392       if (target)
6393         return target;
6394       break;
6395
6396     CASE_INT_FN (BUILT_IN_PARITY):
6397     case BUILT_IN_PARITYIMAX:
6398       target = expand_builtin_unop (target_mode, exp, target,
6399                                     subtarget, parity_optab);
6400       if (target)
6401         return target;
6402       break;
6403
6404     case BUILT_IN_STRLEN:
6405       target = expand_builtin_strlen (exp, target, target_mode);
6406       if (target)
6407         return target;
6408       break;
6409
6410     case BUILT_IN_STRCPY:
6411       target = expand_builtin_strcpy (fndecl, exp, target, mode);
6412       if (target)
6413         return target;
6414       break;
6415
6416     case BUILT_IN_STRNCPY:
6417       target = expand_builtin_strncpy (exp, target, mode);
6418       if (target)
6419         return target;
6420       break;
6421
6422     case BUILT_IN_STPCPY:
6423       target = expand_builtin_stpcpy (exp, target, mode);
6424       if (target)
6425         return target;
6426       break;
6427
6428     case BUILT_IN_STRCAT:
6429       target = expand_builtin_strcat (fndecl, exp, target, mode);
6430       if (target)
6431         return target;
6432       break;
6433
6434     case BUILT_IN_STRNCAT:
6435       target = expand_builtin_strncat (exp, target, mode);
6436       if (target)
6437         return target;
6438       break;
6439
6440     case BUILT_IN_STRSPN:
6441       target = expand_builtin_strspn (exp, target, mode);
6442       if (target)
6443         return target;
6444       break;
6445
6446     case BUILT_IN_STRCSPN:
6447       target = expand_builtin_strcspn (exp, target, mode);
6448       if (target)
6449         return target;
6450       break;
6451
6452     case BUILT_IN_STRSTR:
6453       target = expand_builtin_strstr (exp, target, mode);
6454       if (target)
6455         return target;
6456       break;
6457
6458     case BUILT_IN_STRPBRK:
6459       target = expand_builtin_strpbrk (exp, target, mode);
6460       if (target)
6461         return target;
6462       break;
6463
6464     case BUILT_IN_INDEX:
6465     case BUILT_IN_STRCHR:
6466       target = expand_builtin_strchr (exp, target, mode);
6467       if (target)
6468         return target;
6469       break;
6470
6471     case BUILT_IN_RINDEX:
6472     case BUILT_IN_STRRCHR:
6473       target = expand_builtin_strrchr (exp, target, mode);
6474       if (target)
6475         return target;
6476       break;
6477
6478     case BUILT_IN_MEMCPY:
6479       target = expand_builtin_memcpy (exp, target, mode);
6480       if (target)
6481         return target;
6482       break;
6483
6484     case BUILT_IN_MEMPCPY:
6485       target = expand_builtin_mempcpy (exp, target, mode);
6486       if (target)
6487         return target;
6488       break;
6489
6490     case BUILT_IN_MEMMOVE:
6491       target = expand_builtin_memmove (exp, target, mode, ignore);
6492       if (target)
6493         return target;
6494       break;
6495
6496     case BUILT_IN_BCOPY:
6497       target = expand_builtin_bcopy (exp, ignore);
6498       if (target)
6499         return target;
6500       break;
6501
6502     case BUILT_IN_MEMSET:
6503       target = expand_builtin_memset (exp, target, mode);
6504       if (target)
6505         return target;
6506       break;
6507
6508     case BUILT_IN_BZERO:
6509       target = expand_builtin_bzero (exp);
6510       if (target)
6511         return target;
6512       break;
6513
6514     case BUILT_IN_STRCMP:
6515       target = expand_builtin_strcmp (exp, target, mode);
6516       if (target)
6517         return target;
6518       break;
6519
6520     case BUILT_IN_STRNCMP:
6521       target = expand_builtin_strncmp (exp, target, mode);
6522       if (target)
6523         return target;
6524       break;
6525
6526     case BUILT_IN_MEMCHR:
6527       target = expand_builtin_memchr (exp, target, mode);
6528       if (target)
6529         return target;
6530       break;
6531
6532     case BUILT_IN_BCMP:
6533     case BUILT_IN_MEMCMP:
6534       target = expand_builtin_memcmp (exp, target, mode);
6535       if (target)
6536         return target;
6537       break;
6538
6539     case BUILT_IN_SETJMP:
6540       /* This should have been lowered to the builtins below.  */
6541       gcc_unreachable ();
6542
6543     case BUILT_IN_SETJMP_SETUP:
6544       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6545           and the receiver label.  */
6546       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6547         {
6548           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6549                                       VOIDmode, EXPAND_NORMAL);
6550           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6551           rtx label_r = label_rtx (label);
6552
6553           /* This is copied from the handling of non-local gotos.  */
6554           expand_builtin_setjmp_setup (buf_addr, label_r);
6555           nonlocal_goto_handler_labels
6556             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6557                                  nonlocal_goto_handler_labels);
6558           /* ??? Do not let expand_label treat us as such since we would
6559              not want to be both on the list of non-local labels and on
6560              the list of forced labels.  */
6561           FORCED_LABEL (label) = 0;
6562           return const0_rtx;
6563         }
6564       break;
6565
6566     case BUILT_IN_SETJMP_DISPATCHER:
6567        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6568       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6569         {
6570           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6571           rtx label_r = label_rtx (label);
6572
6573           /* Remove the dispatcher label from the list of non-local labels
6574              since the receiver labels have been added to it above.  */
6575           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6576           return const0_rtx;
6577         }
6578       break;
6579
6580     case BUILT_IN_SETJMP_RECEIVER:
6581        /* __builtin_setjmp_receiver is passed the receiver label.  */
6582       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6583         {
6584           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6585           rtx label_r = label_rtx (label);
6586
6587           expand_builtin_setjmp_receiver (label_r);
6588           return const0_rtx;
6589         }
6590       break;
6591
6592       /* __builtin_longjmp is passed a pointer to an array of five words.
6593          It's similar to the C library longjmp function but works with
6594          __builtin_setjmp above.  */
6595     case BUILT_IN_LONGJMP:
6596       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6597         {
6598           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6599                                       VOIDmode, EXPAND_NORMAL);
6600           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6601
6602           if (value != const1_rtx)
6603             {
6604               error ("%<__builtin_longjmp%> second argument must be 1");
6605               return const0_rtx;
6606             }
6607
6608           expand_builtin_longjmp (buf_addr, value);
6609           return const0_rtx;
6610         }
6611       break;
6612
6613     case BUILT_IN_NONLOCAL_GOTO:
6614       target = expand_builtin_nonlocal_goto (exp);
6615       if (target)
6616         return target;
6617       break;
6618
6619       /* This updates the setjmp buffer that is its argument with the value
6620          of the current stack pointer.  */
6621     case BUILT_IN_UPDATE_SETJMP_BUF:
6622       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6623         {
6624           rtx buf_addr
6625             = expand_normal (CALL_EXPR_ARG (exp, 0));
6626
6627           expand_builtin_update_setjmp_buf (buf_addr);
6628           return const0_rtx;
6629         }
6630       break;
6631
6632     case BUILT_IN_TRAP:
6633       expand_builtin_trap ();
6634       return const0_rtx;
6635
6636     case BUILT_IN_PRINTF:
6637       target = expand_builtin_printf (exp, target, mode, false);
6638       if (target)
6639         return target;
6640       break;
6641
6642     case BUILT_IN_PRINTF_UNLOCKED:
6643       target = expand_builtin_printf (exp, target, mode, true);
6644       if (target)
6645         return target;
6646       break;
6647
6648     case BUILT_IN_FPUTS:
6649       target = expand_builtin_fputs (exp, target, false);
6650       if (target)
6651         return target;
6652       break;
6653     case BUILT_IN_FPUTS_UNLOCKED:
6654       target = expand_builtin_fputs (exp, target, true);
6655       if (target)
6656         return target;
6657       break;
6658
6659     case BUILT_IN_FPRINTF:
6660       target = expand_builtin_fprintf (exp, target, mode, false);
6661       if (target)
6662         return target;
6663       break;
6664
6665     case BUILT_IN_FPRINTF_UNLOCKED:
6666       target = expand_builtin_fprintf (exp, target, mode, true);
6667       if (target)
6668         return target;
6669       break;
6670
6671     case BUILT_IN_SPRINTF:
6672       target = expand_builtin_sprintf (exp, target, mode);
6673       if (target)
6674         return target;
6675       break;
6676
6677     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6678     case BUILT_IN_SIGNBITD32:
6679     case BUILT_IN_SIGNBITD64:
6680     case BUILT_IN_SIGNBITD128:
6681       target = expand_builtin_signbit (exp, target);
6682       if (target)
6683         return target;
6684       break;
6685
6686       /* Various hooks for the DWARF 2 __throw routine.  */
6687     case BUILT_IN_UNWIND_INIT:
6688       expand_builtin_unwind_init ();
6689       return const0_rtx;
6690     case BUILT_IN_DWARF_CFA:
6691       return virtual_cfa_rtx;
6692 #ifdef DWARF2_UNWIND_INFO
6693     case BUILT_IN_DWARF_SP_COLUMN:
6694       return expand_builtin_dwarf_sp_column ();
6695     case BUILT_IN_INIT_DWARF_REG_SIZES:
6696       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6697       return const0_rtx;
6698 #endif
6699     case BUILT_IN_FROB_RETURN_ADDR:
6700       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6701     case BUILT_IN_EXTRACT_RETURN_ADDR:
6702       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6703     case BUILT_IN_EH_RETURN:
6704       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6705                                 CALL_EXPR_ARG (exp, 1));
6706       return const0_rtx;
6707 #ifdef EH_RETURN_DATA_REGNO
6708     case BUILT_IN_EH_RETURN_DATA_REGNO:
6709       return expand_builtin_eh_return_data_regno (exp);
6710 #endif
6711     case BUILT_IN_EXTEND_POINTER:
6712       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6713
6714     case BUILT_IN_VA_START:
6715       return expand_builtin_va_start (exp);
6716     case BUILT_IN_VA_END:
6717       return expand_builtin_va_end (exp);
6718     case BUILT_IN_VA_COPY:
6719       return expand_builtin_va_copy (exp);
6720     case BUILT_IN_EXPECT:
6721       return expand_builtin_expect (exp, target);
6722     case BUILT_IN_PREFETCH:
6723       expand_builtin_prefetch (exp);
6724       return const0_rtx;
6725
6726     case BUILT_IN_PROFILE_FUNC_ENTER:
6727       return expand_builtin_profile_func (false);
6728     case BUILT_IN_PROFILE_FUNC_EXIT:
6729       return expand_builtin_profile_func (true);
6730
6731     case BUILT_IN_INIT_TRAMPOLINE:
6732       return expand_builtin_init_trampoline (exp);
6733     case BUILT_IN_ADJUST_TRAMPOLINE:
6734       return expand_builtin_adjust_trampoline (exp);
6735
6736     case BUILT_IN_FORK:
6737     case BUILT_IN_EXECL:
6738     case BUILT_IN_EXECV:
6739     case BUILT_IN_EXECLP:
6740     case BUILT_IN_EXECLE:
6741     case BUILT_IN_EXECVP:
6742     case BUILT_IN_EXECVE:
6743       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6744       if (target)
6745         return target;
6746       break;
6747
6748     case BUILT_IN_FETCH_AND_ADD_1:
6749     case BUILT_IN_FETCH_AND_ADD_2:
6750     case BUILT_IN_FETCH_AND_ADD_4:
6751     case BUILT_IN_FETCH_AND_ADD_8:
6752     case BUILT_IN_FETCH_AND_ADD_16:
6753       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6754       target = expand_builtin_sync_operation (mode, exp, PLUS,
6755                                               false, target, ignore);
6756       if (target)
6757         return target;
6758       break;
6759
6760     case BUILT_IN_FETCH_AND_SUB_1:
6761     case BUILT_IN_FETCH_AND_SUB_2:
6762     case BUILT_IN_FETCH_AND_SUB_4:
6763     case BUILT_IN_FETCH_AND_SUB_8:
6764     case BUILT_IN_FETCH_AND_SUB_16:
6765       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6766       target = expand_builtin_sync_operation (mode, exp, MINUS,
6767                                               false, target, ignore);
6768       if (target)
6769         return target;
6770       break;
6771
6772     case BUILT_IN_FETCH_AND_OR_1:
6773     case BUILT_IN_FETCH_AND_OR_2:
6774     case BUILT_IN_FETCH_AND_OR_4:
6775     case BUILT_IN_FETCH_AND_OR_8:
6776     case BUILT_IN_FETCH_AND_OR_16:
6777       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6778       target = expand_builtin_sync_operation (mode, exp, IOR,
6779                                               false, target, ignore);
6780       if (target)
6781         return target;
6782       break;
6783
6784     case BUILT_IN_FETCH_AND_AND_1:
6785     case BUILT_IN_FETCH_AND_AND_2:
6786     case BUILT_IN_FETCH_AND_AND_4:
6787     case BUILT_IN_FETCH_AND_AND_8:
6788     case BUILT_IN_FETCH_AND_AND_16:
6789       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6790       target = expand_builtin_sync_operation (mode, exp, AND,
6791                                               false, target, ignore);
6792       if (target)
6793         return target;
6794       break;
6795
6796     case BUILT_IN_FETCH_AND_XOR_1:
6797     case BUILT_IN_FETCH_AND_XOR_2:
6798     case BUILT_IN_FETCH_AND_XOR_4:
6799     case BUILT_IN_FETCH_AND_XOR_8:
6800     case BUILT_IN_FETCH_AND_XOR_16:
6801       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6802       target = expand_builtin_sync_operation (mode, exp, XOR,
6803                                               false, target, ignore);
6804       if (target)
6805         return target;
6806       break;
6807
6808     case BUILT_IN_FETCH_AND_NAND_1:
6809     case BUILT_IN_FETCH_AND_NAND_2:
6810     case BUILT_IN_FETCH_AND_NAND_4:
6811     case BUILT_IN_FETCH_AND_NAND_8:
6812     case BUILT_IN_FETCH_AND_NAND_16:
6813       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6814       target = expand_builtin_sync_operation (mode, exp, NOT,
6815                                               false, target, ignore);
6816       if (target)
6817         return target;
6818       break;
6819
6820     case BUILT_IN_ADD_AND_FETCH_1:
6821     case BUILT_IN_ADD_AND_FETCH_2:
6822     case BUILT_IN_ADD_AND_FETCH_4:
6823     case BUILT_IN_ADD_AND_FETCH_8:
6824     case BUILT_IN_ADD_AND_FETCH_16:
6825       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6826       target = expand_builtin_sync_operation (mode, exp, PLUS,
6827                                               true, target, ignore);
6828       if (target)
6829         return target;
6830       break;
6831
6832     case BUILT_IN_SUB_AND_FETCH_1:
6833     case BUILT_IN_SUB_AND_FETCH_2:
6834     case BUILT_IN_SUB_AND_FETCH_4:
6835     case BUILT_IN_SUB_AND_FETCH_8:
6836     case BUILT_IN_SUB_AND_FETCH_16:
6837       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6838       target = expand_builtin_sync_operation (mode, exp, MINUS,
6839                                               true, target, ignore);
6840       if (target)
6841         return target;
6842       break;
6843
6844     case BUILT_IN_OR_AND_FETCH_1:
6845     case BUILT_IN_OR_AND_FETCH_2:
6846     case BUILT_IN_OR_AND_FETCH_4:
6847     case BUILT_IN_OR_AND_FETCH_8:
6848     case BUILT_IN_OR_AND_FETCH_16:
6849       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6850       target = expand_builtin_sync_operation (mode, exp, IOR,
6851                                               true, target, ignore);
6852       if (target)
6853         return target;
6854       break;
6855
6856     case BUILT_IN_AND_AND_FETCH_1:
6857     case BUILT_IN_AND_AND_FETCH_2:
6858     case BUILT_IN_AND_AND_FETCH_4:
6859     case BUILT_IN_AND_AND_FETCH_8:
6860     case BUILT_IN_AND_AND_FETCH_16:
6861       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6862       target = expand_builtin_sync_operation (mode, exp, AND,
6863                                               true, target, ignore);
6864       if (target)
6865         return target;
6866       break;
6867
6868     case BUILT_IN_XOR_AND_FETCH_1:
6869     case BUILT_IN_XOR_AND_FETCH_2:
6870     case BUILT_IN_XOR_AND_FETCH_4:
6871     case BUILT_IN_XOR_AND_FETCH_8:
6872     case BUILT_IN_XOR_AND_FETCH_16:
6873       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6874       target = expand_builtin_sync_operation (mode, exp, XOR,
6875                                               true, target, ignore);
6876       if (target)
6877         return target;
6878       break;
6879
6880     case BUILT_IN_NAND_AND_FETCH_1:
6881     case BUILT_IN_NAND_AND_FETCH_2:
6882     case BUILT_IN_NAND_AND_FETCH_4:
6883     case BUILT_IN_NAND_AND_FETCH_8:
6884     case BUILT_IN_NAND_AND_FETCH_16:
6885       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6886       target = expand_builtin_sync_operation (mode, exp, NOT,
6887                                               true, target, ignore);
6888       if (target)
6889         return target;
6890       break;
6891
6892     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6893     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6894     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6895     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6896     case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6897       if (mode == VOIDmode)
6898         mode = TYPE_MODE (boolean_type_node);
6899       if (!target || !register_operand (target, mode))
6900         target = gen_reg_rtx (mode);
6901
6902       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6903       target = expand_builtin_compare_and_swap (mode, exp, true, target);
6904       if (target)
6905         return target;
6906       break;
6907
6908     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6909     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6910     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6911     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6912     case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6913       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6914       target = expand_builtin_compare_and_swap (mode, exp, false, target);
6915       if (target)
6916         return target;
6917       break;
6918
6919     case BUILT_IN_LOCK_TEST_AND_SET_1:
6920     case BUILT_IN_LOCK_TEST_AND_SET_2:
6921     case BUILT_IN_LOCK_TEST_AND_SET_4:
6922     case BUILT_IN_LOCK_TEST_AND_SET_8:
6923     case BUILT_IN_LOCK_TEST_AND_SET_16:
6924       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6925       target = expand_builtin_lock_test_and_set (mode, exp, target);
6926       if (target)
6927         return target;
6928       break;
6929
6930     case BUILT_IN_LOCK_RELEASE_1:
6931     case BUILT_IN_LOCK_RELEASE_2:
6932     case BUILT_IN_LOCK_RELEASE_4:
6933     case BUILT_IN_LOCK_RELEASE_8:
6934     case BUILT_IN_LOCK_RELEASE_16:
6935       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6936       expand_builtin_lock_release (mode, exp);
6937       return const0_rtx;
6938
6939     case BUILT_IN_SYNCHRONIZE:
6940       expand_builtin_synchronize ();
6941       return const0_rtx;
6942
6943     case BUILT_IN_OBJECT_SIZE:
6944       return expand_builtin_object_size (exp);
6945
6946     case BUILT_IN_MEMCPY_CHK:
6947     case BUILT_IN_MEMPCPY_CHK:
6948     case BUILT_IN_MEMMOVE_CHK:
6949     case BUILT_IN_MEMSET_CHK:
6950       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6951       if (target)
6952         return target;
6953       break;
6954
6955     case BUILT_IN_STRCPY_CHK:
6956     case BUILT_IN_STPCPY_CHK:
6957     case BUILT_IN_STRNCPY_CHK:
6958     case BUILT_IN_STRCAT_CHK:
6959     case BUILT_IN_STRNCAT_CHK:
6960     case BUILT_IN_SNPRINTF_CHK:
6961     case BUILT_IN_VSNPRINTF_CHK:
6962       maybe_emit_chk_warning (exp, fcode);
6963       break;
6964
6965     case BUILT_IN_SPRINTF_CHK:
6966     case BUILT_IN_VSPRINTF_CHK:
6967       maybe_emit_sprintf_chk_warning (exp, fcode);
6968       break;
6969
6970     default:    /* just do library call, if unknown builtin */
6971       break;
6972     }
6973
6974   /* The switch statement above can drop through to cause the function
6975      to be called normally.  */
6976   return expand_call (exp, target, ignore);
6977 }
6978
6979 /* Determine whether a tree node represents a call to a built-in
6980    function.  If the tree T is a call to a built-in function with
6981    the right number of arguments of the appropriate types, return
6982    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6983    Otherwise the return value is END_BUILTINS.  */
6984
6985 enum built_in_function
6986 builtin_mathfn_code (const_tree t)
6987 {
6988   const_tree fndecl, arg, parmlist;
6989   const_tree argtype, parmtype;
6990   const_call_expr_arg_iterator iter;
6991
6992   if (TREE_CODE (t) != CALL_EXPR
6993       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6994     return END_BUILTINS;
6995
6996   fndecl = get_callee_fndecl (t);
6997   if (fndecl == NULL_TREE
6998       || TREE_CODE (fndecl) != FUNCTION_DECL
6999       || ! DECL_BUILT_IN (fndecl)
7000       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7001     return END_BUILTINS;
7002
7003   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
7004   init_const_call_expr_arg_iterator (t, &iter);
7005   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
7006     {
7007       /* If a function doesn't take a variable number of arguments,
7008          the last element in the list will have type `void'.  */
7009       parmtype = TREE_VALUE (parmlist);
7010       if (VOID_TYPE_P (parmtype))
7011         {
7012           if (more_const_call_expr_args_p (&iter))
7013             return END_BUILTINS;
7014           return DECL_FUNCTION_CODE (fndecl);
7015         }
7016
7017       if (! more_const_call_expr_args_p (&iter))
7018         return END_BUILTINS;
7019       
7020       arg = next_const_call_expr_arg (&iter);
7021       argtype = TREE_TYPE (arg);
7022
7023       if (SCALAR_FLOAT_TYPE_P (parmtype))
7024         {
7025           if (! SCALAR_FLOAT_TYPE_P (argtype))
7026             return END_BUILTINS;
7027         }
7028       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7029         {
7030           if (! COMPLEX_FLOAT_TYPE_P (argtype))
7031             return END_BUILTINS;
7032         }
7033       else if (POINTER_TYPE_P (parmtype))
7034         {
7035           if (! POINTER_TYPE_P (argtype))
7036             return END_BUILTINS;
7037         }
7038       else if (INTEGRAL_TYPE_P (parmtype))
7039         {
7040           if (! INTEGRAL_TYPE_P (argtype))
7041             return END_BUILTINS;
7042         }
7043       else
7044         return END_BUILTINS;
7045     }
7046
7047   /* Variable-length argument list.  */
7048   return DECL_FUNCTION_CODE (fndecl);
7049 }
7050
7051 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
7052    evaluate to a constant.  */
7053
7054 static tree
7055 fold_builtin_constant_p (tree arg)
7056 {
7057   /* We return 1 for a numeric type that's known to be a constant
7058      value at compile-time or for an aggregate type that's a
7059      literal constant.  */
7060   STRIP_NOPS (arg);
7061
7062   /* If we know this is a constant, emit the constant of one.  */
7063   if (CONSTANT_CLASS_P (arg)
7064       || (TREE_CODE (arg) == CONSTRUCTOR
7065           && TREE_CONSTANT (arg)))
7066     return integer_one_node;
7067   if (TREE_CODE (arg) == ADDR_EXPR)
7068     {
7069        tree op = TREE_OPERAND (arg, 0);
7070        if (TREE_CODE (op) == STRING_CST
7071            || (TREE_CODE (op) == ARRAY_REF
7072                && integer_zerop (TREE_OPERAND (op, 1))
7073                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7074          return integer_one_node;
7075     }
7076
7077   /* If this expression has side effects, show we don't know it to be a
7078      constant.  Likewise if it's a pointer or aggregate type since in
7079      those case we only want literals, since those are only optimized
7080      when generating RTL, not later.
7081      And finally, if we are compiling an initializer, not code, we
7082      need to return a definite result now; there's not going to be any
7083      more optimization done.  */
7084   if (TREE_SIDE_EFFECTS (arg)
7085       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7086       || POINTER_TYPE_P (TREE_TYPE (arg))
7087       || cfun == 0
7088       || folding_initializer)
7089     return integer_zero_node;
7090
7091   return NULL_TREE;
7092 }
7093
7094 /* Create builtin_expect with PRED and EXPECTED as its arguments and
7095    return it as a truthvalue.  */
7096
7097 static tree
7098 build_builtin_expect_predicate (tree pred, tree expected)
7099 {
7100   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
7101
7102   fn = built_in_decls[BUILT_IN_EXPECT];
7103   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7104   ret_type = TREE_TYPE (TREE_TYPE (fn));
7105   pred_type = TREE_VALUE (arg_types);
7106   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7107
7108   pred = fold_convert (pred_type, pred);
7109   expected = fold_convert (expected_type, expected);
7110   call_expr = build_call_expr (fn, 2, pred, expected);
7111
7112   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7113                  build_int_cst (ret_type, 0));
7114 }
7115
7116 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
7117    NULL_TREE if no simplification is possible.  */
7118
7119 static tree
7120 fold_builtin_expect (tree arg0, tree arg1)
7121 {
7122   tree inner, fndecl;
7123   enum tree_code code;
7124
7125   /* If this is a builtin_expect within a builtin_expect keep the
7126      inner one.  See through a comparison against a constant.  It
7127      might have been added to create a thruthvalue.  */
7128   inner = arg0;
7129   if (COMPARISON_CLASS_P (inner)
7130       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7131     inner = TREE_OPERAND (inner, 0);
7132
7133   if (TREE_CODE (inner) == CALL_EXPR
7134       && (fndecl = get_callee_fndecl (inner))
7135       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7136       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7137     return arg0;
7138
7139   /* Distribute the expected value over short-circuiting operators.
7140      See through the cast from truthvalue_type_node to long.  */
7141   inner = arg0;
7142   while (TREE_CODE (inner) == NOP_EXPR
7143          && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7144          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7145     inner = TREE_OPERAND (inner, 0);
7146
7147   code = TREE_CODE (inner);
7148   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7149     {
7150       tree op0 = TREE_OPERAND (inner, 0);
7151       tree op1 = TREE_OPERAND (inner, 1);
7152
7153       op0 = build_builtin_expect_predicate (op0, arg1);
7154       op1 = build_builtin_expect_predicate (op1, arg1);
7155       inner = build2 (code, TREE_TYPE (inner), op0, op1);
7156
7157       return fold_convert (TREE_TYPE (arg0), inner);
7158     }
7159
7160   /* If the argument isn't invariant then there's nothing else we can do.  */
7161   if (!TREE_CONSTANT (arg0))
7162     return NULL_TREE;
7163
7164   /* If we expect that a comparison against the argument will fold to
7165      a constant return the constant.  In practice, this means a true
7166      constant or the address of a non-weak symbol.  */
7167   inner = arg0;
7168   STRIP_NOPS (inner);
7169   if (TREE_CODE (inner) == ADDR_EXPR)
7170     {
7171       do
7172         {
7173           inner = TREE_OPERAND (inner, 0);
7174         }
7175       while (TREE_CODE (inner) == COMPONENT_REF
7176              || TREE_CODE (inner) == ARRAY_REF);
7177       if (DECL_P (inner) && DECL_WEAK (inner))
7178         return NULL_TREE;
7179     }
7180
7181   /* Otherwise, ARG0 already has the proper type for the return value.  */
7182   return arg0;
7183 }
7184
7185 /* Fold a call to __builtin_classify_type with argument ARG.  */
7186
7187 static tree
7188 fold_builtin_classify_type (tree arg)
7189 {
7190   if (arg == 0)
7191     return build_int_cst (NULL_TREE, no_type_class);
7192
7193   return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
7194 }
7195
7196 /* Fold a call to __builtin_strlen with argument ARG.  */
7197
7198 static tree
7199 fold_builtin_strlen (tree arg)
7200 {
7201   if (!validate_arg (arg, POINTER_TYPE))
7202     return NULL_TREE;
7203   else
7204     {
7205       tree len = c_strlen (arg, 0);
7206
7207       if (len)
7208         {
7209           /* Convert from the internal "sizetype" type to "size_t".  */
7210           if (size_type_node)
7211             len = fold_convert (size_type_node, len);
7212           return len;
7213         }
7214
7215       return NULL_TREE;
7216     }
7217 }
7218
7219 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
7220
7221 static tree
7222 fold_builtin_inf (tree type, int warn)
7223 {
7224   REAL_VALUE_TYPE real;
7225
7226   /* __builtin_inff is intended to be usable to define INFINITY on all
7227      targets.  If an infinity is not available, INFINITY expands "to a
7228      positive constant of type float that overflows at translation
7229      time", footnote "In this case, using INFINITY will violate the
7230      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7231      Thus we pedwarn to ensure this constraint violation is
7232      diagnosed.  */
7233   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7234     pedwarn ("target format does not support infinity");
7235
7236   real_inf (&real);
7237   return build_real (type, real);
7238 }
7239
7240 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7241
7242 static tree
7243 fold_builtin_nan (tree arg, tree type, int quiet)
7244 {
7245   REAL_VALUE_TYPE real;
7246   const char *str;
7247
7248   if (!validate_arg (arg, POINTER_TYPE))
7249     return NULL_TREE;
7250   str = c_getstr (arg);
7251   if (!str)
7252     return NULL_TREE;
7253
7254   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7255     return NULL_TREE;
7256
7257   return build_real (type, real);
7258 }
7259
7260 /* Return true if the floating point expression T has an integer value.
7261    We also allow +Inf, -Inf and NaN to be considered integer values.  */
7262
7263 static bool
7264 integer_valued_real_p (tree t)
7265 {
7266   switch (TREE_CODE (t))
7267     {
7268     case FLOAT_EXPR:
7269       return true;
7270
7271     case ABS_EXPR:
7272     case SAVE_EXPR:
7273       return integer_valued_real_p (TREE_OPERAND (t, 0));
7274
7275     case COMPOUND_EXPR:
7276     case MODIFY_EXPR:
7277     case BIND_EXPR:
7278       return integer_valued_real_p (GENERIC_TREE_OPERAND (t, 1));
7279
7280     case PLUS_EXPR:
7281     case MINUS_EXPR:
7282     case MULT_EXPR:
7283     case MIN_EXPR:
7284     case MAX_EXPR:
7285       return integer_valued_real_p (TREE_OPERAND (t, 0))
7286              && integer_valued_real_p (TREE_OPERAND (t, 1));
7287
7288     case COND_EXPR:
7289       return integer_valued_real_p (TREE_OPERAND (t, 1))
7290              && integer_valued_real_p (TREE_OPERAND (t, 2));
7291
7292     case REAL_CST:
7293       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7294
7295     case NOP_EXPR:
7296       {
7297         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7298         if (TREE_CODE (type) == INTEGER_TYPE)
7299           return true;
7300         if (TREE_CODE (type) == REAL_TYPE)
7301           return integer_valued_real_p (TREE_OPERAND (t, 0));
7302         break;
7303       }
7304
7305     case CALL_EXPR:
7306       switch (builtin_mathfn_code (t))
7307         {
7308         CASE_FLT_FN (BUILT_IN_CEIL):
7309         CASE_FLT_FN (BUILT_IN_FLOOR):
7310         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7311         CASE_FLT_FN (BUILT_IN_RINT):
7312         CASE_FLT_FN (BUILT_IN_ROUND):
7313         CASE_FLT_FN (BUILT_IN_TRUNC):
7314           return true;
7315
7316         CASE_FLT_FN (BUILT_IN_FMIN):
7317         CASE_FLT_FN (BUILT_IN_FMAX):
7318           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7319             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7320
7321         default:
7322           break;
7323         }
7324       break;
7325
7326     default:
7327       break;
7328     }
7329   return false;
7330 }
7331
7332 /* FNDECL is assumed to be a builtin where truncation can be propagated
7333    across (for instance floor((double)f) == (double)floorf (f).
7334    Do the transformation for a call with argument ARG.  */
7335
7336 static tree
7337 fold_trunc_transparent_mathfn (tree fndecl, tree arg)
7338 {
7339   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7340
7341   if (!validate_arg (arg, REAL_TYPE))
7342     return NULL_TREE;
7343
7344   /* Integer rounding functions are idempotent.  */
7345   if (fcode == builtin_mathfn_code (arg))
7346     return arg;
7347
7348   /* If argument is already integer valued, and we don't need to worry
7349      about setting errno, there's no need to perform rounding.  */
7350   if (! flag_errno_math && integer_valued_real_p (arg))
7351     return arg;
7352
7353   if (optimize)
7354     {
7355       tree arg0 = strip_float_extensions (arg);
7356       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7357       tree newtype = TREE_TYPE (arg0);
7358       tree decl;
7359
7360       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7361           && (decl = mathfn_built_in (newtype, fcode)))
7362         return fold_convert (ftype,
7363                              build_call_expr (decl, 1,
7364                                               fold_convert (newtype, arg0)));
7365     }
7366   return NULL_TREE;
7367 }
7368
7369 /* FNDECL is assumed to be builtin which can narrow the FP type of
7370    the argument, for instance lround((double)f) -> lroundf (f).
7371    Do the transformation for a call with argument ARG.  */
7372
7373 static tree
7374 fold_fixed_mathfn (tree fndecl, tree arg)
7375 {
7376   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7377
7378   if (!validate_arg (arg, REAL_TYPE))
7379     return NULL_TREE;
7380
7381   /* If argument is already integer valued, and we don't need to worry
7382      about setting errno, there's no need to perform rounding.  */
7383   if (! flag_errno_math && integer_valued_real_p (arg))
7384     return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
7385
7386   if (optimize)
7387     {
7388       tree ftype = TREE_TYPE (arg);
7389       tree arg0 = strip_float_extensions (arg);
7390       tree newtype = TREE_TYPE (arg0);
7391       tree decl;
7392
7393       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7394           && (decl = mathfn_built_in (newtype, fcode)))
7395         return build_call_expr (decl, 1, fold_convert (newtype, arg0));
7396     }
7397
7398   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7399      sizeof (long long) == sizeof (long).  */
7400   if (TYPE_PRECISION (long_long_integer_type_node)
7401       == TYPE_PRECISION (long_integer_type_node))
7402     {
7403       tree newfn = NULL_TREE;
7404       switch (fcode)
7405         {
7406         CASE_FLT_FN (BUILT_IN_LLCEIL):
7407           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7408           break;
7409
7410         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7411           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7412           break;
7413
7414         CASE_FLT_FN (BUILT_IN_LLROUND):
7415           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7416           break;
7417
7418         CASE_FLT_FN (BUILT_IN_LLRINT):
7419           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7420           break;
7421
7422         default:
7423           break;
7424         }
7425
7426       if (newfn)
7427         {
7428           tree newcall = build_call_expr(newfn, 1, arg);
7429           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7430         }
7431     }
7432
7433   return NULL_TREE;
7434 }
7435
7436 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7437    return type.  Return NULL_TREE if no simplification can be made.  */
7438
7439 static tree
7440 fold_builtin_cabs (tree arg, tree type, tree fndecl)
7441 {
7442   tree res;
7443
7444   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7445       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7446     return NULL_TREE;
7447
7448   /* Calculate the result when the argument is a constant.  */
7449   if (TREE_CODE (arg) == COMPLEX_CST
7450       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7451                               type, mpfr_hypot)))
7452     return res;
7453   
7454   if (TREE_CODE (arg) == COMPLEX_EXPR)
7455     {
7456       tree real = TREE_OPERAND (arg, 0);
7457       tree imag = TREE_OPERAND (arg, 1);
7458       
7459       /* If either part is zero, cabs is fabs of the other.  */
7460       if (real_zerop (real))
7461         return fold_build1 (ABS_EXPR, type, imag);
7462       if (real_zerop (imag))
7463         return fold_build1 (ABS_EXPR, type, real);
7464
7465       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7466       if (flag_unsafe_math_optimizations
7467           && operand_equal_p (real, imag, OEP_PURE_SAME))
7468         {
7469           const REAL_VALUE_TYPE sqrt2_trunc
7470             = real_value_truncate (TYPE_MODE (type),
7471                                    *get_real_const (rv_sqrt2));
7472           STRIP_NOPS (real);
7473           return fold_build2 (MULT_EXPR, type,
7474                               fold_build1 (ABS_EXPR, type, real),
7475                               build_real (type, sqrt2_trunc));
7476         }
7477     }
7478
7479   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7480   if (TREE_CODE (arg) == NEGATE_EXPR
7481       || TREE_CODE (arg) == CONJ_EXPR)
7482     return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
7483
7484   /* Don't do this when optimizing for size.  */
7485   if (flag_unsafe_math_optimizations
7486       && optimize && !optimize_size)
7487     {
7488       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7489
7490       if (sqrtfn != NULL_TREE)
7491         {
7492           tree rpart, ipart, result;
7493
7494           arg = builtin_save_expr (arg);
7495
7496           rpart = fold_build1 (REALPART_EXPR, type, arg);
7497           ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7498
7499           rpart = builtin_save_expr (rpart);
7500           ipart = builtin_save_expr (ipart);
7501
7502           result = fold_build2 (PLUS_EXPR, type,
7503                                 fold_build2 (MULT_EXPR, type,
7504                                              rpart, rpart),
7505                                 fold_build2 (MULT_EXPR, type,
7506                                              ipart, ipart));
7507
7508           return build_call_expr (sqrtfn, 1, result);
7509         }
7510     }
7511
7512   return NULL_TREE;
7513 }
7514
7515 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7516    Return NULL_TREE if no simplification can be made.  */
7517
7518 static tree
7519 fold_builtin_sqrt (tree arg, tree type)
7520 {
7521
7522   enum built_in_function fcode;
7523   tree res;
7524
7525   if (!validate_arg (arg, REAL_TYPE))
7526     return NULL_TREE;
7527
7528   /* Calculate the result when the argument is a constant.  */
7529   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7530     return res;
7531   
7532   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7533   fcode = builtin_mathfn_code (arg);
7534   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7535     {
7536       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7537       arg = fold_build2 (MULT_EXPR, type,
7538                          CALL_EXPR_ARG (arg, 0),
7539                          build_real (type, dconsthalf));
7540       return build_call_expr (expfn, 1, arg);
7541     }
7542
7543   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7544   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7545     {
7546       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7547
7548       if (powfn)
7549         {
7550           tree arg0 = CALL_EXPR_ARG (arg, 0);
7551           tree tree_root;
7552           /* The inner root was either sqrt or cbrt.  */
7553           REAL_VALUE_TYPE dconstroot =
7554             BUILTIN_SQRT_P (fcode) ? dconsthalf : *get_real_const (rv_third);
7555
7556           /* Adjust for the outer root.  */
7557           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7558           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7559           tree_root = build_real (type, dconstroot);
7560           return build_call_expr (powfn, 2, arg0, tree_root);
7561         }
7562     }
7563
7564   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7565   if (flag_unsafe_math_optimizations
7566       && (fcode == BUILT_IN_POW
7567           || fcode == BUILT_IN_POWF
7568           || fcode == BUILT_IN_POWL))
7569     {
7570       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7571       tree arg0 = CALL_EXPR_ARG (arg, 0);
7572       tree arg1 = CALL_EXPR_ARG (arg, 1);
7573       tree narg1;
7574       if (!tree_expr_nonnegative_p (arg0))
7575         arg0 = build1 (ABS_EXPR, type, arg0);
7576       narg1 = fold_build2 (MULT_EXPR, type, arg1,
7577                            build_real (type, dconsthalf));
7578       return build_call_expr (powfn, 2, arg0, narg1);
7579     }
7580
7581   return NULL_TREE;
7582 }
7583
7584 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7585    Return NULL_TREE if no simplification can be made.  */
7586
7587 static tree
7588 fold_builtin_cbrt (tree arg, tree type)
7589 {
7590   const enum built_in_function fcode = builtin_mathfn_code (arg);
7591   tree res;
7592
7593   if (!validate_arg (arg, REAL_TYPE))
7594     return NULL_TREE;
7595
7596   /* Calculate the result when the argument is a constant.  */
7597   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7598     return res;
7599
7600   if (flag_unsafe_math_optimizations)
7601     {
7602       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7603       if (BUILTIN_EXPONENT_P (fcode))
7604         {
7605           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7606           const REAL_VALUE_TYPE third_trunc =
7607             real_value_truncate (TYPE_MODE (type), *get_real_const (rv_third));
7608           arg = fold_build2 (MULT_EXPR, type,
7609                              CALL_EXPR_ARG (arg, 0),
7610                              build_real (type, third_trunc));
7611           return build_call_expr (expfn, 1, arg);
7612         }
7613
7614       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7615       if (BUILTIN_SQRT_P (fcode))
7616         {
7617           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7618
7619           if (powfn)
7620             {
7621               tree arg0 = CALL_EXPR_ARG (arg, 0);
7622               tree tree_root;
7623               REAL_VALUE_TYPE dconstroot = *get_real_const (rv_third);
7624
7625               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7626               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7627               tree_root = build_real (type, dconstroot);
7628               return build_call_expr (powfn, 2, arg0, tree_root);
7629             }
7630         }
7631
7632       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7633       if (BUILTIN_CBRT_P (fcode))
7634         {
7635           tree arg0 = CALL_EXPR_ARG (arg, 0);
7636           if (tree_expr_nonnegative_p (arg0))
7637             {
7638               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7639
7640               if (powfn)
7641                 {
7642                   tree tree_root;
7643                   REAL_VALUE_TYPE dconstroot;
7644
7645                   real_arithmetic (&dconstroot, MULT_EXPR,
7646                                    get_real_const (rv_third),
7647                                    get_real_const (rv_third));
7648                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7649                   tree_root = build_real (type, dconstroot);
7650                   return build_call_expr (powfn, 2, arg0, tree_root);
7651                 }
7652             }
7653         }
7654
7655       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7656       if (fcode == BUILT_IN_POW 
7657           || fcode == BUILT_IN_POWF
7658           || fcode == BUILT_IN_POWL)
7659         {
7660           tree arg00 = CALL_EXPR_ARG (arg, 0);
7661           tree arg01 = CALL_EXPR_ARG (arg, 1);
7662           if (tree_expr_nonnegative_p (arg00))
7663             {
7664               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7665               const REAL_VALUE_TYPE dconstroot
7666                 = real_value_truncate (TYPE_MODE (type),
7667                                        *get_real_const (rv_third));
7668               tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7669                                          build_real (type, dconstroot));
7670               return build_call_expr (powfn, 2, arg00, narg01);
7671             }
7672         }
7673     }
7674   return NULL_TREE;
7675 }
7676
7677 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7678    TYPE is the type of the return value.  Return NULL_TREE if no
7679    simplification can be made.  */
7680
7681 static tree
7682 fold_builtin_cos (tree arg, tree type, tree fndecl)
7683 {
7684   tree res, narg;
7685
7686   if (!validate_arg (arg, REAL_TYPE))
7687     return NULL_TREE;
7688
7689   /* Calculate the result when the argument is a constant.  */
7690   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7691     return res;
7692   
7693   /* Optimize cos(-x) into cos (x).  */
7694   if ((narg = fold_strip_sign_ops (arg)))
7695     return build_call_expr (fndecl, 1, narg);
7696
7697   return NULL_TREE;
7698 }
7699
7700 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7701    Return NULL_TREE if no simplification can be made.  */
7702
7703 static tree
7704 fold_builtin_cosh (tree arg, tree type, tree fndecl)
7705 {
7706   if (validate_arg (arg, REAL_TYPE))
7707     {
7708       tree res, narg;
7709
7710       /* Calculate the result when the argument is a constant.  */
7711       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7712         return res;
7713   
7714       /* Optimize cosh(-x) into cosh (x).  */
7715       if ((narg = fold_strip_sign_ops (arg)))
7716         return build_call_expr (fndecl, 1, narg);
7717     }
7718   
7719   return NULL_TREE;
7720 }
7721
7722 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7723    Return NULL_TREE if no simplification can be made.  */
7724
7725 static tree
7726 fold_builtin_tan (tree arg, tree type)
7727 {
7728   enum built_in_function fcode;
7729   tree res;
7730
7731   if (!validate_arg (arg, REAL_TYPE))
7732     return NULL_TREE;
7733
7734   /* Calculate the result when the argument is a constant.  */
7735   if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7736     return res;
7737   
7738   /* Optimize tan(atan(x)) = x.  */
7739   fcode = builtin_mathfn_code (arg);
7740   if (flag_unsafe_math_optimizations
7741       && (fcode == BUILT_IN_ATAN
7742           || fcode == BUILT_IN_ATANF
7743           || fcode == BUILT_IN_ATANL))
7744     return CALL_EXPR_ARG (arg, 0);
7745
7746   return NULL_TREE;
7747 }
7748
7749 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7750    NULL_TREE if no simplification can be made.  */
7751
7752 static tree
7753 fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
7754 {
7755   tree type;
7756   tree res, fn, call;
7757
7758   if (!validate_arg (arg0, REAL_TYPE)
7759       || !validate_arg (arg1, POINTER_TYPE)
7760       || !validate_arg (arg2, POINTER_TYPE))
7761     return NULL_TREE;
7762
7763   type = TREE_TYPE (arg0);
7764
7765   /* Calculate the result when the argument is a constant.  */
7766   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7767     return res;
7768
7769   /* Canonicalize sincos to cexpi.  */
7770   if (!TARGET_C99_FUNCTIONS)
7771     return NULL_TREE;
7772   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7773   if (!fn)
7774     return NULL_TREE;
7775
7776   call = build_call_expr (fn, 1, arg0);
7777   call = builtin_save_expr (call);
7778
7779   return build2 (COMPOUND_EXPR, type,
7780                  build2 (MODIFY_EXPR, void_type_node,
7781                          build_fold_indirect_ref (arg1),
7782                          build1 (IMAGPART_EXPR, type, call)),
7783                  build2 (MODIFY_EXPR, void_type_node,
7784                          build_fold_indirect_ref (arg2),
7785                          build1 (REALPART_EXPR, type, call)));
7786 }
7787
7788 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7789    NULL_TREE if no simplification can be made.  */
7790
7791 static tree
7792 fold_builtin_cexp (tree arg0, tree type)
7793 {
7794   tree rtype;
7795   tree realp, imagp, ifn;
7796
7797   if (!validate_arg (arg0, COMPLEX_TYPE))
7798     return NULL_TREE;
7799
7800   rtype = TREE_TYPE (TREE_TYPE (arg0));
7801
7802   /* In case we can figure out the real part of arg0 and it is constant zero
7803      fold to cexpi.  */
7804   if (!TARGET_C99_FUNCTIONS)
7805     return NULL_TREE;
7806   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7807   if (!ifn)
7808     return NULL_TREE;
7809
7810   if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7811       && real_zerop (realp))
7812     {
7813       tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7814       return build_call_expr (ifn, 1, narg);
7815     }
7816
7817   /* In case we can easily decompose real and imaginary parts split cexp
7818      to exp (r) * cexpi (i).  */
7819   if (flag_unsafe_math_optimizations
7820       && realp)
7821     {
7822       tree rfn, rcall, icall;
7823
7824       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7825       if (!rfn)
7826         return NULL_TREE;
7827
7828       imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7829       if (!imagp)
7830         return NULL_TREE;
7831
7832       icall = build_call_expr (ifn, 1, imagp);
7833       icall = builtin_save_expr (icall);
7834       rcall = build_call_expr (rfn, 1, realp);
7835       rcall = builtin_save_expr (rcall);
7836       return fold_build2 (COMPLEX_EXPR, type,
7837                           fold_build2 (MULT_EXPR, rtype,
7838                                        rcall,
7839                                        fold_build1 (REALPART_EXPR, rtype, icall)),
7840                           fold_build2 (MULT_EXPR, rtype,
7841                                        rcall,
7842                                        fold_build1 (IMAGPART_EXPR, rtype, icall)));
7843     }
7844
7845   return NULL_TREE;
7846 }
7847
7848 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7849    Return NULL_TREE if no simplification can be made.  */
7850
7851 static tree
7852 fold_builtin_trunc (tree fndecl, tree arg)
7853 {
7854   if (!validate_arg (arg, REAL_TYPE))
7855     return NULL_TREE;
7856
7857   /* Optimize trunc of constant value.  */
7858   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7859     {
7860       REAL_VALUE_TYPE r, x;
7861       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7862
7863       x = TREE_REAL_CST (arg);
7864       real_trunc (&r, TYPE_MODE (type), &x);
7865       return build_real (type, r);
7866     }
7867
7868   return fold_trunc_transparent_mathfn (fndecl, arg);
7869 }
7870
7871 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7872    Return NULL_TREE if no simplification can be made.  */
7873
7874 static tree
7875 fold_builtin_floor (tree fndecl, tree arg)
7876 {
7877   if (!validate_arg (arg, REAL_TYPE))
7878     return NULL_TREE;
7879
7880   /* Optimize floor of constant value.  */
7881   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7882     {
7883       REAL_VALUE_TYPE x;
7884
7885       x = TREE_REAL_CST (arg);
7886       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7887         {
7888           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7889           REAL_VALUE_TYPE r;
7890
7891           real_floor (&r, TYPE_MODE (type), &x);
7892           return build_real (type, r);
7893         }
7894     }
7895
7896   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7897   if (tree_expr_nonnegative_p (arg))
7898     {
7899       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7900       if (truncfn)
7901         return build_call_expr (truncfn, 1, arg);
7902     }
7903
7904   return fold_trunc_transparent_mathfn (fndecl, arg);
7905 }
7906
7907 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7908    Return NULL_TREE if no simplification can be made.  */
7909
7910 static tree
7911 fold_builtin_ceil (tree fndecl, tree arg)
7912 {
7913   if (!validate_arg (arg, REAL_TYPE))
7914     return NULL_TREE;
7915
7916   /* Optimize ceil of constant value.  */
7917   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7918     {
7919       REAL_VALUE_TYPE x;
7920
7921       x = TREE_REAL_CST (arg);
7922       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7923         {
7924           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7925           REAL_VALUE_TYPE r;
7926
7927           real_ceil (&r, TYPE_MODE (type), &x);
7928           return build_real (type, r);
7929         }
7930     }
7931
7932   return fold_trunc_transparent_mathfn (fndecl, arg);
7933 }
7934
7935 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7936    Return NULL_TREE if no simplification can be made.  */
7937
7938 static tree
7939 fold_builtin_round (tree fndecl, tree arg)
7940 {
7941   if (!validate_arg (arg, REAL_TYPE))
7942     return NULL_TREE;
7943
7944   /* Optimize round of constant value.  */
7945   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7946     {
7947       REAL_VALUE_TYPE x;
7948
7949       x = TREE_REAL_CST (arg);
7950       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7951         {
7952           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7953           REAL_VALUE_TYPE r;
7954
7955           real_round (&r, TYPE_MODE (type), &x);
7956           return build_real (type, r);
7957         }
7958     }
7959
7960   return fold_trunc_transparent_mathfn (fndecl, arg);
7961 }
7962
7963 /* Fold function call to builtin lround, lroundf or lroundl (or the
7964    corresponding long long versions) and other rounding functions.  ARG
7965    is the argument to the call.  Return NULL_TREE if no simplification
7966    can be made.  */
7967
7968 static tree
7969 fold_builtin_int_roundingfn (tree fndecl, tree arg)
7970 {
7971   if (!validate_arg (arg, REAL_TYPE))
7972     return NULL_TREE;
7973
7974   /* Optimize lround of constant value.  */
7975   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7976     {
7977       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7978
7979       if (real_isfinite (&x))
7980         {
7981           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7982           tree ftype = TREE_TYPE (arg);
7983           unsigned HOST_WIDE_INT lo2;
7984           HOST_WIDE_INT hi, lo;
7985           REAL_VALUE_TYPE r;
7986
7987           switch (DECL_FUNCTION_CODE (fndecl))
7988             {
7989             CASE_FLT_FN (BUILT_IN_LFLOOR):
7990             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7991               real_floor (&r, TYPE_MODE (ftype), &x);
7992               break;
7993
7994             CASE_FLT_FN (BUILT_IN_LCEIL):
7995             CASE_FLT_FN (BUILT_IN_LLCEIL):
7996               real_ceil (&r, TYPE_MODE (ftype), &x);
7997               break;
7998
7999             CASE_FLT_FN (BUILT_IN_LROUND):
8000             CASE_FLT_FN (BUILT_IN_LLROUND):
8001               real_round (&r, TYPE_MODE (ftype), &x);
8002               break;
8003
8004             default:
8005               gcc_unreachable ();
8006             }
8007
8008           REAL_VALUE_TO_INT (&lo, &hi, r);
8009           if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8010             return build_int_cst_wide (itype, lo2, hi);
8011         }
8012     }
8013
8014   switch (DECL_FUNCTION_CODE (fndecl))
8015     {
8016     CASE_FLT_FN (BUILT_IN_LFLOOR):
8017     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8018       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8019       if (tree_expr_nonnegative_p (arg))
8020         return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
8021                             arg);
8022       break;
8023     default:;
8024     }
8025
8026   return fold_fixed_mathfn (fndecl, arg);
8027 }
8028
8029 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8030    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8031    the argument to the call.  Return NULL_TREE if no simplification can
8032    be made.  */
8033
8034 static tree
8035 fold_builtin_bitop (tree fndecl, tree arg)
8036 {
8037   if (!validate_arg (arg, INTEGER_TYPE))
8038     return NULL_TREE;
8039
8040   /* Optimize for constant argument.  */
8041   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8042     {
8043       HOST_WIDE_INT hi, width, result;
8044       unsigned HOST_WIDE_INT lo;
8045       tree type;
8046
8047       type = TREE_TYPE (arg);
8048       width = TYPE_PRECISION (type);
8049       lo = TREE_INT_CST_LOW (arg);
8050
8051       /* Clear all the bits that are beyond the type's precision.  */
8052       if (width > HOST_BITS_PER_WIDE_INT)
8053         {
8054           hi = TREE_INT_CST_HIGH (arg);
8055           if (width < 2 * HOST_BITS_PER_WIDE_INT)
8056             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8057         }
8058       else
8059         {
8060           hi = 0;
8061           if (width < HOST_BITS_PER_WIDE_INT)
8062             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8063         }
8064
8065       switch (DECL_FUNCTION_CODE (fndecl))
8066         {
8067         CASE_INT_FN (BUILT_IN_FFS):
8068           if (lo != 0)
8069             result = exact_log2 (lo & -lo) + 1;
8070           else if (hi != 0)
8071             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8072           else
8073             result = 0;
8074           break;
8075
8076         CASE_INT_FN (BUILT_IN_CLZ):
8077           if (hi != 0)
8078             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8079           else if (lo != 0)
8080             result = width - floor_log2 (lo) - 1;
8081           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8082             result = width;
8083           break;
8084
8085         CASE_INT_FN (BUILT_IN_CTZ):
8086           if (lo != 0)
8087             result = exact_log2 (lo & -lo);
8088           else if (hi != 0)
8089             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8090           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8091             result = width;
8092           break;
8093
8094         CASE_INT_FN (BUILT_IN_POPCOUNT):
8095           result = 0;
8096           while (lo)
8097             result++, lo &= lo - 1;
8098           while (hi)
8099             result++, hi &= hi - 1;
8100           break;
8101
8102         CASE_INT_FN (BUILT_IN_PARITY):
8103           result = 0;
8104           while (lo)
8105             result++, lo &= lo - 1;
8106           while (hi)
8107             result++, hi &= hi - 1;
8108           result &= 1;
8109           break;
8110
8111         default:
8112           gcc_unreachable ();
8113         }
8114
8115       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8116     }
8117
8118   return NULL_TREE;
8119 }
8120
8121 /* Fold function call to builtin_bswap and the long and long long
8122    variants.  Return NULL_TREE if no simplification can be made.  */
8123 static tree
8124 fold_builtin_bswap (tree fndecl, tree arg)
8125 {
8126   if (! validate_arg (arg, INTEGER_TYPE))
8127     return NULL_TREE;
8128
8129   /* Optimize constant value.  */
8130   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8131     {
8132       HOST_WIDE_INT hi, width, r_hi = 0;
8133       unsigned HOST_WIDE_INT lo, r_lo = 0;
8134       tree type;
8135
8136       type = TREE_TYPE (arg);
8137       width = TYPE_PRECISION (type);
8138       lo = TREE_INT_CST_LOW (arg);
8139       hi = TREE_INT_CST_HIGH (arg);
8140
8141       switch (DECL_FUNCTION_CODE (fndecl))
8142         {
8143           case BUILT_IN_BSWAP32:
8144           case BUILT_IN_BSWAP64:
8145             {
8146               int s;
8147
8148               for (s = 0; s < width; s += 8)
8149                 {
8150                   int d = width - s - 8;
8151                   unsigned HOST_WIDE_INT byte;
8152
8153                   if (s < HOST_BITS_PER_WIDE_INT)
8154                     byte = (lo >> s) & 0xff;
8155                   else
8156                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8157
8158                   if (d < HOST_BITS_PER_WIDE_INT)
8159                     r_lo |= byte << d;
8160                   else
8161                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8162                 }
8163             }
8164
8165             break;
8166
8167         default:
8168           gcc_unreachable ();
8169         }
8170
8171       if (width < HOST_BITS_PER_WIDE_INT)
8172         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8173       else
8174         return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8175     }
8176
8177   return NULL_TREE;
8178 }
8179
8180 /* Return true if EXPR is the real constant contained in VALUE.  */
8181
8182 static bool
8183 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
8184 {
8185   STRIP_NOPS (expr);
8186
8187   return ((TREE_CODE (expr) == REAL_CST
8188            && !TREE_OVERFLOW (expr)
8189            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
8190           || (TREE_CODE (expr) == COMPLEX_CST
8191               && real_dconstp (TREE_REALPART (expr), value)
8192               && real_zerop (TREE_IMAGPART (expr))));
8193 }
8194
8195 /* A subroutine of fold_builtin to fold the various logarithmic
8196    functions.  Return NULL_TREE if no simplification can me made.
8197    FUNC is the corresponding MPFR logarithm function.  */
8198
8199 static tree
8200 fold_builtin_logarithm (tree fndecl, tree arg,
8201                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8202 {
8203   if (validate_arg (arg, REAL_TYPE))
8204     {
8205       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8206       tree res;
8207       const enum built_in_function fcode = builtin_mathfn_code (arg);
8208
8209       /* Optimize log(e) = 1.0.  We're never passed an exact 'e',
8210          instead we'll look for 'e' truncated to MODE.  So only do
8211          this if flag_unsafe_math_optimizations is set.  */
8212       if (flag_unsafe_math_optimizations && func == mpfr_log)
8213         {
8214           const REAL_VALUE_TYPE e_truncated =
8215             real_value_truncate (TYPE_MODE (type), *get_real_const (rv_e));
8216           if (real_dconstp (arg, &e_truncated))
8217             return build_real (type, dconst1);
8218         }
8219
8220       /* Calculate the result when the argument is a constant.  */
8221       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8222         return res;
8223
8224       /* Special case, optimize logN(expN(x)) = x.  */
8225       if (flag_unsafe_math_optimizations
8226           && ((func == mpfr_log
8227                && (fcode == BUILT_IN_EXP
8228                    || fcode == BUILT_IN_EXPF
8229                    || fcode == BUILT_IN_EXPL))
8230               || (func == mpfr_log2
8231                   && (fcode == BUILT_IN_EXP2
8232                       || fcode == BUILT_IN_EXP2F
8233                       || fcode == BUILT_IN_EXP2L))
8234               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8235         return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8236
8237       /* Optimize logN(func()) for various exponential functions.  We
8238          want to determine the value "x" and the power "exponent" in
8239          order to transform logN(x**exponent) into exponent*logN(x).  */
8240       if (flag_unsafe_math_optimizations)
8241         {
8242           tree exponent = 0, x = 0;
8243
8244           switch (fcode)
8245           {
8246           CASE_FLT_FN (BUILT_IN_EXP):
8247             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8248             x = build_real (type,
8249                             real_value_truncate (TYPE_MODE (type),
8250                                                  *get_real_const (rv_e)));
8251             exponent = CALL_EXPR_ARG (arg, 0);
8252             break;
8253           CASE_FLT_FN (BUILT_IN_EXP2):
8254             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8255             x = build_real (type, dconst2);
8256             exponent = CALL_EXPR_ARG (arg, 0);
8257             break;
8258           CASE_FLT_FN (BUILT_IN_EXP10):
8259           CASE_FLT_FN (BUILT_IN_POW10):
8260             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8261             {
8262               REAL_VALUE_TYPE dconst10;
8263               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8264               x = build_real (type, dconst10);
8265             }
8266             exponent = CALL_EXPR_ARG (arg, 0);
8267             break;
8268           CASE_FLT_FN (BUILT_IN_SQRT):
8269             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8270             x = CALL_EXPR_ARG (arg, 0);
8271             exponent = build_real (type, dconsthalf);
8272             break;
8273           CASE_FLT_FN (BUILT_IN_CBRT):
8274             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8275             x = CALL_EXPR_ARG (arg, 0);
8276             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8277                                                               *get_real_const (rv_third)));
8278             break;
8279           CASE_FLT_FN (BUILT_IN_POW):
8280             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8281             x = CALL_EXPR_ARG (arg, 0);
8282             exponent = CALL_EXPR_ARG (arg, 1);
8283             break;
8284           default:
8285             break;
8286           }
8287
8288           /* Now perform the optimization.  */
8289           if (x && exponent)
8290             {
8291               tree logfn = build_call_expr (fndecl, 1, x);
8292               return fold_build2 (MULT_EXPR, type, exponent, logfn);
8293             }
8294         }
8295     }
8296
8297   return NULL_TREE;
8298 }
8299
8300 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8301    NULL_TREE if no simplification can be made.  */
8302
8303 static tree
8304 fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
8305 {
8306   tree res, narg0, narg1;
8307
8308   if (!validate_arg (arg0, REAL_TYPE)
8309       || !validate_arg (arg1, REAL_TYPE))
8310     return NULL_TREE;
8311
8312   /* Calculate the result when the argument is a constant.  */
8313   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8314     return res;
8315   
8316   /* If either argument to hypot has a negate or abs, strip that off.
8317      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8318   narg0 = fold_strip_sign_ops (arg0);
8319   narg1 = fold_strip_sign_ops (arg1);
8320   if (narg0 || narg1)
8321     {
8322       return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0, 
8323                               narg1 ? narg1 : arg1);
8324     }
8325   
8326   /* If either argument is zero, hypot is fabs of the other.  */
8327   if (real_zerop (arg0))
8328     return fold_build1 (ABS_EXPR, type, arg1);
8329   else if (real_zerop (arg1))
8330     return fold_build1 (ABS_EXPR, type, arg0);
8331       
8332   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8333   if (flag_unsafe_math_optimizations
8334       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8335     {
8336       const REAL_VALUE_TYPE sqrt2_trunc
8337         = real_value_truncate (TYPE_MODE (type), *get_real_const (rv_sqrt2));
8338       return fold_build2 (MULT_EXPR, type,
8339                           fold_build1 (ABS_EXPR, type, arg0),
8340                           build_real (type, sqrt2_trunc));
8341     }
8342
8343   return NULL_TREE;
8344 }
8345
8346
8347 /* Fold a builtin function call to pow, powf, or powl.  Return
8348    NULL_TREE if no simplification can be made.  */
8349 static tree
8350 fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
8351 {
8352   tree res;
8353
8354   if (!validate_arg (arg0, REAL_TYPE)
8355        || !validate_arg (arg1, REAL_TYPE))
8356     return NULL_TREE;
8357
8358   /* Calculate the result when the argument is a constant.  */
8359   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8360     return res;
8361
8362   /* Optimize pow(1.0,y) = 1.0.  */
8363   if (real_onep (arg0))
8364     return omit_one_operand (type, build_real (type, dconst1), arg1);
8365
8366   if (TREE_CODE (arg1) == REAL_CST
8367       && !TREE_OVERFLOW (arg1))
8368     {
8369       REAL_VALUE_TYPE cint;
8370       REAL_VALUE_TYPE c;
8371       HOST_WIDE_INT n;
8372
8373       c = TREE_REAL_CST (arg1);
8374
8375       /* Optimize pow(x,0.0) = 1.0.  */
8376       if (REAL_VALUES_EQUAL (c, dconst0))
8377         return omit_one_operand (type, build_real (type, dconst1),
8378                                  arg0);
8379
8380       /* Optimize pow(x,1.0) = x.  */
8381       if (REAL_VALUES_EQUAL (c, dconst1))
8382         return arg0;
8383
8384       /* Optimize pow(x,-1.0) = 1.0/x.  */
8385       if (REAL_VALUES_EQUAL (c, dconstm1))
8386         return fold_build2 (RDIV_EXPR, type,
8387                             build_real (type, dconst1), arg0);
8388
8389       /* Optimize pow(x,0.5) = sqrt(x).  */
8390       if (flag_unsafe_math_optimizations
8391           && REAL_VALUES_EQUAL (c, dconsthalf))
8392         {
8393           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8394
8395           if (sqrtfn != NULL_TREE)
8396             return build_call_expr (sqrtfn, 1, arg0);
8397         }
8398
8399       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8400       if (flag_unsafe_math_optimizations)
8401         {
8402           const REAL_VALUE_TYPE dconstroot
8403             = real_value_truncate (TYPE_MODE (type),
8404                                    *get_real_const (rv_third));
8405
8406           if (REAL_VALUES_EQUAL (c, dconstroot))
8407             {
8408               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8409               if (cbrtfn != NULL_TREE)
8410                   return build_call_expr (cbrtfn, 1, arg0);
8411             }
8412         }
8413
8414       /* Check for an integer exponent.  */
8415       n = real_to_integer (&c);
8416       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8417       if (real_identical (&c, &cint))
8418         {
8419           /* Attempt to evaluate pow at compile-time.  */
8420           if (TREE_CODE (arg0) == REAL_CST
8421               && !TREE_OVERFLOW (arg0))
8422             {
8423               REAL_VALUE_TYPE x;
8424               bool inexact;
8425
8426               x = TREE_REAL_CST (arg0);
8427               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8428               if (flag_unsafe_math_optimizations || !inexact)
8429                 return build_real (type, x);
8430             }
8431
8432           /* Strip sign ops from even integer powers.  */
8433           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8434             {
8435               tree narg0 = fold_strip_sign_ops (arg0);
8436               if (narg0)
8437                 return build_call_expr (fndecl, 2, narg0, arg1);
8438             }
8439         }
8440     }
8441
8442   if (flag_unsafe_math_optimizations)
8443     {
8444       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8445
8446       /* Optimize pow(expN(x),y) = expN(x*y).  */
8447       if (BUILTIN_EXPONENT_P (fcode))
8448         {
8449           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8450           tree arg = CALL_EXPR_ARG (arg0, 0);
8451           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8452           return build_call_expr (expfn, 1, arg);
8453         }
8454
8455       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8456       if (BUILTIN_SQRT_P (fcode))
8457         {
8458           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8459           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8460                                     build_real (type, dconsthalf));
8461           return build_call_expr (fndecl, 2, narg0, narg1);
8462         }
8463
8464       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8465       if (BUILTIN_CBRT_P (fcode))
8466         {
8467           tree arg = CALL_EXPR_ARG (arg0, 0);
8468           if (tree_expr_nonnegative_p (arg))
8469             {
8470               const REAL_VALUE_TYPE dconstroot
8471                 = real_value_truncate (TYPE_MODE (type),
8472                                        *get_real_const (rv_third));
8473               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8474                                         build_real (type, dconstroot));
8475               return build_call_expr (fndecl, 2, arg, narg1);
8476             }
8477         }
8478
8479       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8480       if (fcode == BUILT_IN_POW
8481           || fcode == BUILT_IN_POWF
8482           || fcode == BUILT_IN_POWL)
8483         {
8484           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8485           tree arg01 = CALL_EXPR_ARG (arg0, 1);
8486           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8487           return build_call_expr (fndecl, 2, arg00, narg1);
8488         }
8489     }
8490
8491   return NULL_TREE;
8492 }
8493
8494 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8495    Return NULL_TREE if no simplification can be made.  */
8496 static tree
8497 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8498                    tree arg0, tree arg1, tree type)
8499 {
8500   if (!validate_arg (arg0, REAL_TYPE)
8501       || !validate_arg (arg1, INTEGER_TYPE))
8502     return NULL_TREE;
8503
8504   /* Optimize pow(1.0,y) = 1.0.  */
8505   if (real_onep (arg0))
8506     return omit_one_operand (type, build_real (type, dconst1), arg1);
8507
8508   if (host_integerp (arg1, 0))
8509     {
8510       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8511
8512       /* Evaluate powi at compile-time.  */
8513       if (TREE_CODE (arg0) == REAL_CST
8514           && !TREE_OVERFLOW (arg0))
8515         {
8516           REAL_VALUE_TYPE x;
8517           x = TREE_REAL_CST (arg0);
8518           real_powi (&x, TYPE_MODE (type), &x, c);
8519           return build_real (type, x);
8520         }
8521
8522       /* Optimize pow(x,0) = 1.0.  */
8523       if (c == 0)
8524         return omit_one_operand (type, build_real (type, dconst1),
8525                                  arg0);
8526
8527       /* Optimize pow(x,1) = x.  */
8528       if (c == 1)
8529         return arg0;
8530
8531       /* Optimize pow(x,-1) = 1.0/x.  */
8532       if (c == -1)
8533         return fold_build2 (RDIV_EXPR, type,
8534                            build_real (type, dconst1), arg0);
8535     }
8536
8537   return NULL_TREE;
8538 }
8539
8540 /* A subroutine of fold_builtin to fold the various exponent
8541    functions.  Return NULL_TREE if no simplification can be made.
8542    FUNC is the corresponding MPFR exponent function.  */
8543
8544 static tree
8545 fold_builtin_exponent (tree fndecl, tree arg,
8546                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8547 {
8548   if (validate_arg (arg, REAL_TYPE))
8549     {
8550       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8551       tree res;
8552       
8553       /* Calculate the result when the argument is a constant.  */
8554       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8555         return res;
8556
8557       /* Optimize expN(logN(x)) = x.  */
8558       if (flag_unsafe_math_optimizations)
8559         {
8560           const enum built_in_function fcode = builtin_mathfn_code (arg);
8561
8562           if ((func == mpfr_exp
8563                && (fcode == BUILT_IN_LOG
8564                    || fcode == BUILT_IN_LOGF
8565                    || fcode == BUILT_IN_LOGL))
8566               || (func == mpfr_exp2
8567                   && (fcode == BUILT_IN_LOG2
8568                       || fcode == BUILT_IN_LOG2F
8569                       || fcode == BUILT_IN_LOG2L))
8570               || (func == mpfr_exp10
8571                   && (fcode == BUILT_IN_LOG10
8572                       || fcode == BUILT_IN_LOG10F
8573                       || fcode == BUILT_IN_LOG10L)))
8574             return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8575         }
8576     }
8577
8578   return NULL_TREE;
8579 }
8580
8581 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8582
8583 static bool
8584 var_decl_component_p (tree var)
8585 {
8586   tree inner = var;
8587   while (handled_component_p (inner))
8588     inner = TREE_OPERAND (inner, 0);
8589   return SSA_VAR_P (inner);
8590 }
8591
8592 /* Fold function call to builtin memset.  Return
8593    NULL_TREE if no simplification can be made.  */
8594
8595 static tree
8596 fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
8597 {
8598   tree var, ret;
8599   unsigned HOST_WIDE_INT length, cval;
8600
8601   if (! validate_arg (dest, POINTER_TYPE)
8602       || ! validate_arg (c, INTEGER_TYPE)
8603       || ! validate_arg (len, INTEGER_TYPE))
8604     return NULL_TREE;
8605
8606   if (! host_integerp (len, 1))
8607     return NULL_TREE;
8608
8609   /* If the LEN parameter is zero, return DEST.  */
8610   if (integer_zerop (len))
8611     return omit_one_operand (type, dest, c);
8612
8613   if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8614     return NULL_TREE;
8615
8616   var = dest;
8617   STRIP_NOPS (var);
8618   if (TREE_CODE (var) != ADDR_EXPR)
8619     return NULL_TREE;
8620
8621   var = TREE_OPERAND (var, 0);
8622   if (TREE_THIS_VOLATILE (var))
8623     return NULL_TREE;
8624
8625   if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8626       && !POINTER_TYPE_P (TREE_TYPE (var)))
8627     return NULL_TREE;
8628
8629   if (! var_decl_component_p (var))
8630     return NULL_TREE;
8631
8632   length = tree_low_cst (len, 1);
8633   if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8634       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8635          < (int) length)
8636     return NULL_TREE;
8637
8638   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8639     return NULL_TREE;
8640
8641   if (integer_zerop (c))
8642     cval = 0;
8643   else
8644     {
8645       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8646         return NULL_TREE;
8647
8648       cval = tree_low_cst (c, 1);
8649       cval &= 0xff;
8650       cval |= cval << 8;
8651       cval |= cval << 16;
8652       cval |= (cval << 31) << 1;
8653     }
8654
8655   ret = build_int_cst_type (TREE_TYPE (var), cval);
8656   ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
8657   if (ignore)
8658     return ret;
8659
8660   return omit_one_operand (type, dest, ret);
8661 }
8662
8663 /* Fold function call to builtin memset.  Return
8664    NULL_TREE if no simplification can be made.  */
8665
8666 static tree
8667 fold_builtin_bzero (tree dest, tree size, bool ignore)
8668 {
8669   if (! validate_arg (dest, POINTER_TYPE)
8670       || ! validate_arg (size, INTEGER_TYPE))
8671     return NULL_TREE;
8672
8673   if (!ignore)
8674     return NULL_TREE;
8675
8676   /* New argument list transforming bzero(ptr x, int y) to
8677      memset(ptr x, int 0, size_t y).   This is done this way
8678      so that if it isn't expanded inline, we fallback to
8679      calling bzero instead of memset.  */
8680
8681   return fold_builtin_memset (dest, integer_zero_node,
8682                               fold_convert (sizetype, size),
8683                               void_type_node, ignore);
8684 }
8685
8686 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8687    NULL_TREE if no simplification can be made.
8688    If ENDP is 0, return DEST (like memcpy).
8689    If ENDP is 1, return DEST+LEN (like mempcpy).
8690    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8691    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8692    (memmove).   */
8693
8694 static tree
8695 fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
8696 {
8697   tree destvar, srcvar, expr;
8698
8699   if (! validate_arg (dest, POINTER_TYPE)
8700       || ! validate_arg (src, POINTER_TYPE)
8701       || ! validate_arg (len, INTEGER_TYPE))
8702     return NULL_TREE;
8703
8704   /* If the LEN parameter is zero, return DEST.  */
8705   if (integer_zerop (len))
8706     return omit_one_operand (type, dest, src);
8707
8708   /* If SRC and DEST are the same (and not volatile), return
8709      DEST{,+LEN,+LEN-1}.  */
8710   if (operand_equal_p (src, dest, 0))
8711     expr = len;
8712   else
8713     {
8714       tree srctype, desttype;
8715       if (endp == 3)
8716         {
8717           int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8718           int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8719
8720           /* Both DEST and SRC must be pointer types. 
8721              ??? This is what old code did.  Is the testing for pointer types
8722              really mandatory?
8723
8724              If either SRC is readonly or length is 1, we can use memcpy.  */
8725           if (dest_align && src_align
8726               && (readonly_data_expr (src)
8727                   || (host_integerp (len, 1)
8728                       && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8729                           tree_low_cst (len, 1)))))
8730             {
8731               tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8732               if (!fn)
8733                 return NULL_TREE;
8734               return build_call_expr (fn, 3, dest, src, len);
8735             }
8736           return NULL_TREE;
8737         }
8738
8739       if (!host_integerp (len, 0))
8740         return NULL_TREE;
8741       /* FIXME:
8742          This logic lose for arguments like (type *)malloc (sizeof (type)),
8743          since we strip the casts of up to VOID return value from malloc.
8744          Perhaps we ought to inherit type from non-VOID argument here?  */
8745       STRIP_NOPS (src);
8746       STRIP_NOPS (dest);
8747       srctype = TREE_TYPE (TREE_TYPE (src));
8748       desttype = TREE_TYPE (TREE_TYPE (dest));
8749       if (!srctype || !desttype
8750           || !TYPE_SIZE_UNIT (srctype)
8751           || !TYPE_SIZE_UNIT (desttype)
8752           || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8753           || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8754           || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8755           || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8756         return NULL_TREE;
8757
8758       if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT) 
8759           < (int) TYPE_ALIGN (desttype)
8760           || (get_pointer_alignment (src, BIGGEST_ALIGNMENT) 
8761               < (int) TYPE_ALIGN (srctype)))
8762         return NULL_TREE;
8763
8764       if (!ignore)
8765         dest = builtin_save_expr (dest);
8766
8767       srcvar = build_fold_indirect_ref (src);
8768       if (TREE_THIS_VOLATILE (srcvar))
8769         return NULL_TREE;
8770       if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8771         return NULL_TREE;
8772       /* With memcpy, it is possible to bypass aliasing rules, so without
8773          this check i.e. execute/20060930-2.c would be misoptimized, because
8774          it use conflicting alias set to hold argument for the memcpy call.
8775          This check is probably unnecessary with -fno-strict-aliasing.
8776          Similarly for destvar.  See also PR29286.  */
8777       if (!var_decl_component_p (srcvar)
8778           /* Accept: memcpy (*char_var, "test", 1); that simplify
8779              to char_var='t';  */
8780           || is_gimple_min_invariant (srcvar)
8781           || readonly_data_expr (src))
8782         return NULL_TREE;
8783
8784       destvar = build_fold_indirect_ref (dest);
8785       if (TREE_THIS_VOLATILE (destvar))
8786         return NULL_TREE;
8787       if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8788         return NULL_TREE;
8789       if (!var_decl_component_p (destvar))
8790         return NULL_TREE;
8791
8792       if (srctype == desttype
8793           || (gimple_in_ssa_p (cfun)
8794               && useless_type_conversion_p (desttype, srctype)))
8795         expr = srcvar;
8796       else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8797            || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8798           && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8799               || POINTER_TYPE_P (TREE_TYPE (destvar))))
8800         expr = fold_convert (TREE_TYPE (destvar), srcvar);
8801       else
8802         expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8803       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8804     }
8805
8806   if (ignore)
8807     return expr;
8808
8809   if (endp == 0 || endp == 3)
8810     return omit_one_operand (type, dest, expr);
8811
8812   if (expr == len)
8813     expr = NULL_TREE;
8814
8815   if (endp == 2)
8816     len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8817                        ssize_int (1));
8818
8819   dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8820   dest = fold_convert (type, dest);
8821   if (expr)
8822     dest = omit_one_operand (type, dest, expr);
8823   return dest;
8824 }
8825
8826 /* Fold function call to builtin strcpy with arguments DEST and SRC.
8827    If LEN is not NULL, it represents the length of the string to be
8828    copied.  Return NULL_TREE if no simplification can be made.  */
8829
8830 tree
8831 fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
8832 {
8833   tree fn;
8834
8835   if (!validate_arg (dest, POINTER_TYPE)
8836       || !validate_arg (src, POINTER_TYPE))
8837     return NULL_TREE;
8838
8839   /* If SRC and DEST are the same (and not volatile), return DEST.  */
8840   if (operand_equal_p (src, dest, 0))
8841     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8842
8843   if (optimize_size)
8844     return NULL_TREE;
8845
8846   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8847   if (!fn)
8848     return NULL_TREE;
8849
8850   if (!len)
8851     {
8852       len = c_strlen (src, 1);
8853       if (! len || TREE_SIDE_EFFECTS (len))
8854         return NULL_TREE;
8855     }
8856
8857   len = size_binop (PLUS_EXPR, len, ssize_int (1));
8858   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8859                        build_call_expr (fn, 3, dest, src, len));
8860 }
8861
8862 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8863    If SLEN is not NULL, it represents the length of the source string.
8864    Return NULL_TREE if no simplification can be made.  */
8865
8866 tree
8867 fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
8868 {
8869   tree fn;
8870
8871   if (!validate_arg (dest, POINTER_TYPE)
8872       || !validate_arg (src, POINTER_TYPE)
8873       || !validate_arg (len, INTEGER_TYPE))
8874     return NULL_TREE;
8875
8876   /* If the LEN parameter is zero, return DEST.  */
8877   if (integer_zerop (len))
8878     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8879
8880   /* We can't compare slen with len as constants below if len is not a
8881      constant.  */
8882   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8883     return NULL_TREE;
8884
8885   if (!slen)
8886     slen = c_strlen (src, 1);
8887
8888   /* Now, we must be passed a constant src ptr parameter.  */
8889   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8890     return NULL_TREE;
8891
8892   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8893
8894   /* We do not support simplification of this case, though we do
8895      support it when expanding trees into RTL.  */
8896   /* FIXME: generate a call to __builtin_memset.  */
8897   if (tree_int_cst_lt (slen, len))
8898     return NULL_TREE;
8899
8900   /* OK transform into builtin memcpy.  */
8901   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8902   if (!fn)
8903     return NULL_TREE;
8904   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8905                        build_call_expr (fn, 3, dest, src, len));
8906 }
8907
8908 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
8909    arguments to the call, and TYPE is its return type.
8910    Return NULL_TREE if no simplification can be made.  */
8911
8912 static tree
8913 fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
8914 {
8915   if (!validate_arg (arg1, POINTER_TYPE)
8916       || !validate_arg (arg2, INTEGER_TYPE)
8917       || !validate_arg (len, INTEGER_TYPE))
8918     return NULL_TREE;
8919   else
8920     {
8921       const char *p1;
8922
8923       if (TREE_CODE (arg2) != INTEGER_CST
8924           || !host_integerp (len, 1))
8925         return NULL_TREE;
8926
8927       p1 = c_getstr (arg1);
8928       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8929         {
8930           char c;
8931           const char *r;
8932           tree tem;
8933
8934           if (target_char_cast (arg2, &c))
8935             return NULL_TREE;
8936
8937           r = (char *) memchr (p1, c, tree_low_cst (len, 1));
8938
8939           if (r == NULL)
8940             return build_int_cst (TREE_TYPE (arg1), 0);
8941
8942           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
8943                              size_int (r - p1));
8944           return fold_convert (type, tem);
8945         }
8946       return NULL_TREE;
8947     }
8948 }
8949
8950 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8951    Return NULL_TREE if no simplification can be made.  */
8952
8953 static tree
8954 fold_builtin_memcmp (tree arg1, tree arg2, tree len)
8955 {
8956   const char *p1, *p2;
8957
8958   if (!validate_arg (arg1, POINTER_TYPE)
8959       || !validate_arg (arg2, POINTER_TYPE)
8960       || !validate_arg (len, INTEGER_TYPE))
8961     return NULL_TREE;
8962
8963   /* If the LEN parameter is zero, return zero.  */
8964   if (integer_zerop (len))
8965     return omit_two_operands (integer_type_node, integer_zero_node,
8966                               arg1, arg2);
8967
8968   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8969   if (operand_equal_p (arg1, arg2, 0))
8970     return omit_one_operand (integer_type_node, integer_zero_node, len);
8971
8972   p1 = c_getstr (arg1);
8973   p2 = c_getstr (arg2);
8974
8975   /* If all arguments are constant, and the value of len is not greater
8976      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8977   if (host_integerp (len, 1) && p1 && p2
8978       && compare_tree_int (len, strlen (p1) + 1) <= 0
8979       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8980     {
8981       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8982
8983       if (r > 0)
8984         return integer_one_node;
8985       else if (r < 0)
8986         return integer_minus_one_node;
8987       else
8988         return integer_zero_node;
8989     }
8990
8991   /* If len parameter is one, return an expression corresponding to
8992      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8993   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8994     {
8995       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8996       tree cst_uchar_ptr_node
8997         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8998
8999       tree ind1 = fold_convert (integer_type_node,
9000                                 build1 (INDIRECT_REF, cst_uchar_node,
9001                                         fold_convert (cst_uchar_ptr_node,
9002                                                       arg1)));
9003       tree ind2 = fold_convert (integer_type_node,
9004                                 build1 (INDIRECT_REF, cst_uchar_node,
9005                                         fold_convert (cst_uchar_ptr_node,
9006                                                       arg2)));
9007       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9008     }
9009
9010   return NULL_TREE;
9011 }
9012
9013 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9014    Return NULL_TREE if no simplification can be made.  */
9015
9016 static tree
9017 fold_builtin_strcmp (tree arg1, tree arg2)
9018 {
9019   const char *p1, *p2;
9020
9021   if (!validate_arg (arg1, POINTER_TYPE)
9022       || !validate_arg (arg2, POINTER_TYPE))
9023     return NULL_TREE;
9024
9025   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9026   if (operand_equal_p (arg1, arg2, 0))
9027     return integer_zero_node;
9028
9029   p1 = c_getstr (arg1);
9030   p2 = c_getstr (arg2);
9031
9032   if (p1 && p2)
9033     {
9034       const int i = strcmp (p1, p2);
9035       if (i < 0)
9036         return integer_minus_one_node;
9037       else if (i > 0)
9038         return integer_one_node;
9039       else
9040         return integer_zero_node;
9041     }
9042
9043   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9044   if (p2 && *p2 == '\0')
9045     {
9046       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9047       tree cst_uchar_ptr_node
9048         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9049
9050       return fold_convert (integer_type_node,
9051                            build1 (INDIRECT_REF, cst_uchar_node,
9052                                    fold_convert (cst_uchar_ptr_node,
9053                                                  arg1)));
9054     }
9055
9056   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9057   if (p1 && *p1 == '\0')
9058     {
9059       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9060       tree cst_uchar_ptr_node
9061         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9062
9063       tree temp = fold_convert (integer_type_node,
9064                                 build1 (INDIRECT_REF, cst_uchar_node,
9065                                         fold_convert (cst_uchar_ptr_node,
9066                                                       arg2)));
9067       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9068     }
9069
9070   return NULL_TREE;
9071 }
9072
9073 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9074    Return NULL_TREE if no simplification can be made.  */
9075
9076 static tree
9077 fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9078 {
9079   const char *p1, *p2;
9080
9081   if (!validate_arg (arg1, POINTER_TYPE)
9082       || !validate_arg (arg2, POINTER_TYPE)
9083       || !validate_arg (len, INTEGER_TYPE))
9084     return NULL_TREE;
9085
9086   /* If the LEN parameter is zero, return zero.  */
9087   if (integer_zerop (len))
9088     return omit_two_operands (integer_type_node, integer_zero_node,
9089                               arg1, arg2);
9090
9091   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9092   if (operand_equal_p (arg1, arg2, 0))
9093     return omit_one_operand (integer_type_node, integer_zero_node, len);
9094
9095   p1 = c_getstr (arg1);
9096   p2 = c_getstr (arg2);
9097
9098   if (host_integerp (len, 1) && p1 && p2)
9099     {
9100       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9101       if (i > 0)
9102         return integer_one_node;
9103       else if (i < 0)
9104         return integer_minus_one_node;
9105       else
9106         return integer_zero_node;
9107     }
9108
9109   /* If the second arg is "", and the length is greater than zero,
9110      return *(const unsigned char*)arg1.  */
9111   if (p2 && *p2 == '\0'
9112       && TREE_CODE (len) == INTEGER_CST
9113       && tree_int_cst_sgn (len) == 1)
9114     {
9115       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9116       tree cst_uchar_ptr_node
9117         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9118
9119       return fold_convert (integer_type_node,
9120                            build1 (INDIRECT_REF, cst_uchar_node,
9121                                    fold_convert (cst_uchar_ptr_node,
9122                                                  arg1)));
9123     }
9124
9125   /* If the first arg is "", and the length is greater than zero,
9126      return -*(const unsigned char*)arg2.  */
9127   if (p1 && *p1 == '\0'
9128       && TREE_CODE (len) == INTEGER_CST
9129       && tree_int_cst_sgn (len) == 1)
9130     {
9131       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9132       tree cst_uchar_ptr_node
9133         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9134
9135       tree temp = fold_convert (integer_type_node,
9136                                 build1 (INDIRECT_REF, cst_uchar_node,
9137                                         fold_convert (cst_uchar_ptr_node,
9138                                                       arg2)));
9139       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9140     }
9141
9142   /* If len parameter is one, return an expression corresponding to
9143      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9144   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9145     {
9146       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9147       tree cst_uchar_ptr_node
9148         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9149
9150       tree ind1 = fold_convert (integer_type_node,
9151                                 build1 (INDIRECT_REF, cst_uchar_node,
9152                                         fold_convert (cst_uchar_ptr_node,
9153                                                       arg1)));
9154       tree ind2 = fold_convert (integer_type_node,
9155                                 build1 (INDIRECT_REF, cst_uchar_node,
9156                                         fold_convert (cst_uchar_ptr_node,
9157                                                       arg2)));
9158       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9159     }
9160
9161   return NULL_TREE;
9162 }
9163
9164 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9165    ARG.  Return NULL_TREE if no simplification can be made.  */
9166
9167 static tree
9168 fold_builtin_signbit (tree arg, tree type)
9169 {
9170   tree temp;
9171
9172   if (!validate_arg (arg, REAL_TYPE))
9173     return NULL_TREE;
9174
9175   /* If ARG is a compile-time constant, determine the result.  */
9176   if (TREE_CODE (arg) == REAL_CST
9177       && !TREE_OVERFLOW (arg))
9178     {
9179       REAL_VALUE_TYPE c;
9180
9181       c = TREE_REAL_CST (arg);
9182       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
9183       return fold_convert (type, temp);
9184     }
9185
9186   /* If ARG is non-negative, the result is always zero.  */
9187   if (tree_expr_nonnegative_p (arg))
9188     return omit_one_operand (type, integer_zero_node, arg);
9189
9190   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9191   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9192     return fold_build2 (LT_EXPR, type, arg,
9193                         build_real (TREE_TYPE (arg), dconst0));
9194
9195   return NULL_TREE;
9196 }
9197
9198 /* Fold function call to builtin copysign, copysignf or copysignl with
9199    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9200    be made.  */
9201
9202 static tree
9203 fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
9204 {
9205   tree tem;
9206
9207   if (!validate_arg (arg1, REAL_TYPE)
9208       || !validate_arg (arg2, REAL_TYPE))
9209     return NULL_TREE;
9210
9211   /* copysign(X,X) is X.  */
9212   if (operand_equal_p (arg1, arg2, 0))
9213     return fold_convert (type, arg1);
9214
9215   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9216   if (TREE_CODE (arg1) == REAL_CST
9217       && TREE_CODE (arg2) == REAL_CST
9218       && !TREE_OVERFLOW (arg1)
9219       && !TREE_OVERFLOW (arg2))
9220     {
9221       REAL_VALUE_TYPE c1, c2;
9222
9223       c1 = TREE_REAL_CST (arg1);
9224       c2 = TREE_REAL_CST (arg2);
9225       /* c1.sign := c2.sign.  */
9226       real_copysign (&c1, &c2);
9227       return build_real (type, c1);
9228     }
9229
9230   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9231      Remember to evaluate Y for side-effects.  */
9232   if (tree_expr_nonnegative_p (arg2))
9233     return omit_one_operand (type,
9234                              fold_build1 (ABS_EXPR, type, arg1),
9235                              arg2);
9236
9237   /* Strip sign changing operations for the first argument.  */
9238   tem = fold_strip_sign_ops (arg1);
9239   if (tem)
9240     return build_call_expr (fndecl, 2, tem, arg2);
9241
9242   return NULL_TREE;
9243 }
9244
9245 /* Fold a call to builtin isascii with argument ARG.  */
9246
9247 static tree
9248 fold_builtin_isascii (tree arg)
9249 {
9250   if (!validate_arg (arg, INTEGER_TYPE))
9251     return NULL_TREE;
9252   else
9253     {
9254       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9255       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9256                     build_int_cst (NULL_TREE,
9257                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
9258       return fold_build2 (EQ_EXPR, integer_type_node,
9259                           arg, integer_zero_node);
9260     }
9261 }
9262
9263 /* Fold a call to builtin toascii with argument ARG.  */
9264
9265 static tree
9266 fold_builtin_toascii (tree arg)
9267 {
9268   if (!validate_arg (arg, INTEGER_TYPE))
9269     return NULL_TREE;
9270       
9271   /* Transform toascii(c) -> (c & 0x7f).  */
9272   return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9273                       build_int_cst (NULL_TREE, 0x7f));
9274 }
9275
9276 /* Fold a call to builtin isdigit with argument ARG.  */
9277
9278 static tree
9279 fold_builtin_isdigit (tree arg)
9280 {
9281   if (!validate_arg (arg, INTEGER_TYPE))
9282     return NULL_TREE;
9283   else
9284     {
9285       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9286       /* According to the C standard, isdigit is unaffected by locale.
9287          However, it definitely is affected by the target character set.  */
9288       unsigned HOST_WIDE_INT target_digit0
9289         = lang_hooks.to_target_charset ('0');
9290
9291       if (target_digit0 == 0)
9292         return NULL_TREE;
9293
9294       arg = fold_convert (unsigned_type_node, arg);
9295       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
9296                     build_int_cst (unsigned_type_node, target_digit0));
9297       return fold_build2 (LE_EXPR, integer_type_node, arg,
9298                           build_int_cst (unsigned_type_node, 9));
9299     }
9300 }
9301
9302 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9303
9304 static tree
9305 fold_builtin_fabs (tree arg, tree type)
9306 {
9307   if (!validate_arg (arg, REAL_TYPE))
9308     return NULL_TREE;
9309
9310   arg = fold_convert (type, arg);
9311   if (TREE_CODE (arg) == REAL_CST)
9312     return fold_abs_const (arg, type);
9313   return fold_build1 (ABS_EXPR, type, arg);
9314 }
9315
9316 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9317
9318 static tree
9319 fold_builtin_abs (tree arg, tree type)
9320 {
9321   if (!validate_arg (arg, INTEGER_TYPE))
9322     return NULL_TREE;
9323
9324   arg = fold_convert (type, arg);
9325   if (TREE_CODE (arg) == INTEGER_CST)
9326     return fold_abs_const (arg, type);
9327   return fold_build1 (ABS_EXPR, type, arg);
9328 }
9329
9330 /* Fold a call to builtin fmin or fmax.  */
9331
9332 static tree
9333 fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
9334 {
9335   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9336     {
9337       /* Calculate the result when the argument is a constant.  */
9338       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9339
9340       if (res)
9341         return res;
9342
9343       /* If either argument is NaN, return the other one.  Avoid the
9344          transformation if we get (and honor) a signalling NaN.  Using
9345          omit_one_operand() ensures we create a non-lvalue.  */
9346       if (TREE_CODE (arg0) == REAL_CST
9347           && real_isnan (&TREE_REAL_CST (arg0))
9348           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9349               || ! TREE_REAL_CST (arg0).signalling))
9350         return omit_one_operand (type, arg1, arg0);
9351       if (TREE_CODE (arg1) == REAL_CST
9352           && real_isnan (&TREE_REAL_CST (arg1))
9353           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9354               || ! TREE_REAL_CST (arg1).signalling))
9355         return omit_one_operand (type, arg0, arg1);
9356
9357       /* Transform fmin/fmax(x,x) -> x.  */
9358       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9359         return omit_one_operand (type, arg0, arg1);
9360       
9361       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9362          functions to return the numeric arg if the other one is NaN.
9363          These tree codes don't honor that, so only transform if
9364          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9365          handled, so we don't have to worry about it either.  */
9366       if (flag_finite_math_only)
9367         return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9368                             fold_convert (type, arg0),
9369                             fold_convert (type, arg1));
9370     }
9371   return NULL_TREE;
9372 }
9373
9374 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9375
9376 static tree
9377 fold_builtin_carg (tree arg, tree type)
9378 {
9379   if (validate_arg (arg, COMPLEX_TYPE))
9380     {
9381       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9382       
9383       if (atan2_fn)
9384         {
9385           tree new_arg = builtin_save_expr (arg);
9386           tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9387           tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9388           return build_call_expr (atan2_fn, 2, i_arg, r_arg);
9389         }
9390     }
9391   
9392   return NULL_TREE;
9393 }
9394
9395 /* Fold a call to builtin logb/ilogb.  */
9396
9397 static tree
9398 fold_builtin_logb (tree arg, tree rettype)
9399 {
9400   if (! validate_arg (arg, REAL_TYPE))
9401     return NULL_TREE;
9402   
9403   STRIP_NOPS (arg);
9404       
9405   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9406     {
9407       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9408           
9409       switch (value->cl)
9410       {
9411       case rvc_nan:
9412       case rvc_inf:
9413         /* If arg is Inf or NaN and we're logb, return it.  */
9414         if (TREE_CODE (rettype) == REAL_TYPE)
9415           return fold_convert (rettype, arg);
9416         /* Fall through... */
9417       case rvc_zero:
9418         /* Zero may set errno and/or raise an exception for logb, also
9419            for ilogb we don't know FP_ILOGB0.  */
9420         return NULL_TREE;
9421       case rvc_normal:
9422         /* For normal numbers, proceed iff radix == 2.  In GCC,
9423            normalized significands are in the range [0.5, 1.0).  We
9424            want the exponent as if they were [1.0, 2.0) so get the
9425            exponent and subtract 1.  */
9426         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9427           return fold_convert (rettype, build_int_cst (NULL_TREE,
9428                                                        REAL_EXP (value)-1));
9429         break;
9430       }
9431     }
9432   
9433   return NULL_TREE;
9434 }
9435
9436 /* Fold a call to builtin significand, if radix == 2.  */
9437
9438 static tree
9439 fold_builtin_significand (tree arg, tree rettype)
9440 {
9441   if (! validate_arg (arg, REAL_TYPE))
9442     return NULL_TREE;
9443   
9444   STRIP_NOPS (arg);
9445       
9446   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9447     {
9448       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9449           
9450       switch (value->cl)
9451       {
9452       case rvc_zero:
9453       case rvc_nan:
9454       case rvc_inf:
9455         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9456         return fold_convert (rettype, arg);
9457       case rvc_normal:
9458         /* For normal numbers, proceed iff radix == 2.  */
9459         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9460           {
9461             REAL_VALUE_TYPE result = *value;
9462             /* In GCC, normalized significands are in the range [0.5,
9463                1.0).  We want them to be [1.0, 2.0) so set the
9464                exponent to 1.  */
9465             SET_REAL_EXP (&result, 1);
9466             return build_real (rettype, result);
9467           }
9468         break;
9469       }
9470     }
9471   
9472   return NULL_TREE;
9473 }
9474
9475 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9476
9477 static tree
9478 fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9479 {
9480   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9481     return NULL_TREE;
9482   
9483   STRIP_NOPS (arg0);
9484       
9485   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9486     return NULL_TREE;
9487   
9488   arg1 = build_fold_indirect_ref (arg1);
9489
9490   /* Proceed if a valid pointer type was passed in.  */
9491   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9492     {
9493       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9494       tree frac, exp;
9495           
9496       switch (value->cl)
9497       {
9498       case rvc_zero:
9499         /* For +-0, return (*exp = 0, +-0).  */
9500         exp = integer_zero_node;
9501         frac = arg0;
9502         break;
9503       case rvc_nan:
9504       case rvc_inf:
9505         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9506         return omit_one_operand (rettype, arg0, arg1);
9507       case rvc_normal:
9508         {
9509           /* Since the frexp function always expects base 2, and in
9510              GCC normalized significands are already in the range
9511              [0.5, 1.0), we have exactly what frexp wants.  */
9512           REAL_VALUE_TYPE frac_rvt = *value;
9513           SET_REAL_EXP (&frac_rvt, 0);
9514           frac = build_real (rettype, frac_rvt);
9515           exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9516         }
9517         break;
9518       default:
9519         gcc_unreachable ();
9520       }
9521                 
9522       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9523       arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9524       TREE_SIDE_EFFECTS (arg1) = 1;
9525       return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9526     }
9527
9528   return NULL_TREE;
9529 }
9530
9531 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9532    then we can assume the base is two.  If it's false, then we have to
9533    check the mode of the TYPE parameter in certain cases.  */
9534
9535 static tree
9536 fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9537 {
9538   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9539     {
9540       STRIP_NOPS (arg0);
9541       STRIP_NOPS (arg1);
9542
9543       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9544       if (real_zerop (arg0) || integer_zerop (arg1)
9545           || (TREE_CODE (arg0) == REAL_CST
9546               && !real_isfinite (&TREE_REAL_CST (arg0))))
9547         return omit_one_operand (type, arg0, arg1);
9548       
9549       /* If both arguments are constant, then try to evaluate it.  */
9550       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9551           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9552           && host_integerp (arg1, 0))
9553         {
9554           /* Bound the maximum adjustment to twice the range of the
9555              mode's valid exponents.  Use abs to ensure the range is
9556              positive as a sanity check.  */
9557           const long max_exp_adj = 2 * 
9558             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9559                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9560
9561           /* Get the user-requested adjustment.  */
9562           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9563           
9564           /* The requested adjustment must be inside this range.  This
9565              is a preliminary cap to avoid things like overflow, we
9566              may still fail to compute the result for other reasons.  */
9567           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9568             {
9569               REAL_VALUE_TYPE initial_result;
9570               
9571               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9572
9573               /* Ensure we didn't overflow.  */
9574               if (! real_isinf (&initial_result))
9575                 {
9576                   const REAL_VALUE_TYPE trunc_result
9577                     = real_value_truncate (TYPE_MODE (type), initial_result);
9578                   
9579                   /* Only proceed if the target mode can hold the
9580                      resulting value.  */
9581                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9582                     return build_real (type, trunc_result);
9583                 }
9584             }
9585         }
9586     }
9587
9588   return NULL_TREE;
9589 }
9590
9591 /* Fold a call to builtin modf.  */
9592
9593 static tree
9594 fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9595 {
9596   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9597     return NULL_TREE;
9598   
9599   STRIP_NOPS (arg0);
9600       
9601   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9602     return NULL_TREE;
9603   
9604   arg1 = build_fold_indirect_ref (arg1);
9605
9606   /* Proceed if a valid pointer type was passed in.  */
9607   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9608     {
9609       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9610       REAL_VALUE_TYPE trunc, frac;
9611
9612       switch (value->cl)
9613       {
9614       case rvc_nan:
9615       case rvc_zero:
9616         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9617         trunc = frac = *value;
9618         break;
9619       case rvc_inf:
9620         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9621         frac = dconst0;
9622         frac.sign = value->sign;
9623         trunc = *value;
9624         break;
9625       case rvc_normal:
9626         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9627         real_trunc (&trunc, VOIDmode, value);
9628         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9629         /* If the original number was negative and already
9630            integral, then the fractional part is -0.0.  */
9631         if (value->sign && frac.cl == rvc_zero)
9632           frac.sign = value->sign;
9633         break;
9634       }
9635               
9636       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9637       arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
9638                           build_real (rettype, trunc));
9639       TREE_SIDE_EFFECTS (arg1) = 1;
9640       return fold_build2 (COMPOUND_EXPR, rettype, arg1,
9641                           build_real (rettype, frac));
9642     }
9643   
9644   return NULL_TREE;
9645 }
9646
9647 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9648    ARG is the argument for the call.  */
9649
9650 static tree
9651 fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
9652 {
9653   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9654   REAL_VALUE_TYPE r;
9655
9656   if (!validate_arg (arg, REAL_TYPE))
9657     return NULL_TREE;
9658
9659   switch (builtin_index)
9660     {
9661     case BUILT_IN_ISINF:
9662       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9663         return omit_one_operand (type, integer_zero_node, arg);
9664
9665       if (TREE_CODE (arg) == REAL_CST)
9666         {
9667           r = TREE_REAL_CST (arg);
9668           if (real_isinf (&r))
9669             return real_compare (GT_EXPR, &r, &dconst0)
9670                    ? integer_one_node : integer_minus_one_node;
9671           else
9672             return integer_zero_node;
9673         }
9674
9675       return NULL_TREE;
9676
9677     case BUILT_IN_ISINF_SIGN:
9678       {
9679         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9680         /* In a boolean context, GCC will fold the inner COND_EXPR to
9681            1.  So e.g. "if (isinf_sign(x))" would be folded to just
9682            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9683         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9684         tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9685         tree tmp = NULL_TREE;
9686
9687         arg = builtin_save_expr (arg);
9688
9689         if (signbit_fn && isinf_fn)
9690           {
9691             tree signbit_call = build_call_expr (signbit_fn, 1, arg);
9692             tree isinf_call = build_call_expr (isinf_fn, 1, arg);
9693
9694             signbit_call = fold_build2 (NE_EXPR, integer_type_node,
9695                                         signbit_call, integer_zero_node);
9696             isinf_call = fold_build2 (NE_EXPR, integer_type_node,
9697                                       isinf_call, integer_zero_node);
9698             
9699             tmp = fold_build3 (COND_EXPR, integer_type_node, signbit_call,
9700                                integer_minus_one_node, integer_one_node);
9701             tmp = fold_build3 (COND_EXPR, integer_type_node, isinf_call, tmp,
9702                                integer_zero_node);
9703           }
9704
9705         return tmp;
9706       }
9707
9708     case BUILT_IN_ISFINITE:
9709       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9710           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9711         return omit_one_operand (type, integer_one_node, arg);
9712
9713       if (TREE_CODE (arg) == REAL_CST)
9714         {
9715           r = TREE_REAL_CST (arg);
9716           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
9717         }
9718
9719       return NULL_TREE;
9720
9721     case BUILT_IN_ISNAN:
9722       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9723         return omit_one_operand (type, integer_zero_node, arg);
9724
9725       if (TREE_CODE (arg) == REAL_CST)
9726         {
9727           r = TREE_REAL_CST (arg);
9728           return real_isnan (&r) ? integer_one_node : integer_zero_node;
9729         }
9730
9731       arg = builtin_save_expr (arg);
9732       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9733
9734     default:
9735       gcc_unreachable ();
9736     }
9737 }
9738
9739 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9740    This builtin will generate code to return the appropriate floating
9741    point classification depending on the value of the floating point
9742    number passed in.  The possible return values must be supplied as
9743    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
9744    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
9745    one floating point argument which is "type generic".  */
9746
9747 static tree
9748 fold_builtin_fpclassify (tree exp)
9749 {
9750   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9751     arg, type, res, tmp;
9752   enum machine_mode mode;
9753   REAL_VALUE_TYPE r;
9754   char buf[128];
9755   
9756   /* Verify the required arguments in the original call.  */
9757   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9758                          INTEGER_TYPE, INTEGER_TYPE,
9759                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9760     return NULL_TREE;
9761   
9762   fp_nan = CALL_EXPR_ARG (exp, 0);
9763   fp_infinite = CALL_EXPR_ARG (exp, 1);
9764   fp_normal = CALL_EXPR_ARG (exp, 2);
9765   fp_subnormal = CALL_EXPR_ARG (exp, 3);
9766   fp_zero = CALL_EXPR_ARG (exp, 4);
9767   arg = CALL_EXPR_ARG (exp, 5);
9768   type = TREE_TYPE (arg);
9769   mode = TYPE_MODE (type);
9770   arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
9771
9772   /* fpclassify(x) -> 
9773        isnan(x) ? FP_NAN :
9774          (fabs(x) == Inf ? FP_INFINITE :
9775            (fabs(x) >= DBL_MIN ? FP_NORMAL :
9776              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
9777   
9778   tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9779                      build_real (type, dconst0));
9780   res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
9781
9782   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9783   real_from_string (&r, buf);
9784   tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
9785   res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
9786   
9787   if (HONOR_INFINITIES (mode))
9788     {
9789       real_inf (&r);
9790       tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9791                          build_real (type, r));
9792       res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_infinite, res);
9793     }
9794
9795   if (HONOR_NANS (mode))
9796     {
9797       tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
9798       res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
9799     }
9800   
9801   return res;
9802 }
9803
9804 /* Fold a call to an unordered comparison function such as
9805    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
9806    being called and ARG0 and ARG1 are the arguments for the call.
9807    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9808    the opposite of the desired result.  UNORDERED_CODE is used
9809    for modes that can hold NaNs and ORDERED_CODE is used for
9810    the rest.  */
9811
9812 static tree
9813 fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
9814                             enum tree_code unordered_code,
9815                             enum tree_code ordered_code)
9816 {
9817   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9818   enum tree_code code;
9819   tree type0, type1;
9820   enum tree_code code0, code1;
9821   tree cmp_type = NULL_TREE;
9822
9823   type0 = TREE_TYPE (arg0);
9824   type1 = TREE_TYPE (arg1);
9825
9826   code0 = TREE_CODE (type0);
9827   code1 = TREE_CODE (type1);
9828
9829   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9830     /* Choose the wider of two real types.  */
9831     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9832       ? type0 : type1;
9833   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9834     cmp_type = type0;
9835   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9836     cmp_type = type1;
9837
9838   arg0 = fold_convert (cmp_type, arg0);
9839   arg1 = fold_convert (cmp_type, arg1);
9840
9841   if (unordered_code == UNORDERED_EXPR)
9842     {
9843       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9844         return omit_two_operands (type, integer_zero_node, arg0, arg1);
9845       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9846     }
9847
9848   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9849                                                    : ordered_code;
9850   return fold_build1 (TRUTH_NOT_EXPR, type,
9851                       fold_build2 (code, type, arg0, arg1));
9852 }
9853
9854 /* Fold a call to built-in function FNDECL with 0 arguments.
9855    IGNORE is true if the result of the function call is ignored.  This
9856    function returns NULL_TREE if no simplification was possible.  */
9857
9858 static tree
9859 fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
9860 {
9861   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9862   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9863   switch (fcode)
9864     {
9865     CASE_FLT_FN (BUILT_IN_INF):
9866     case BUILT_IN_INFD32:
9867     case BUILT_IN_INFD64:
9868     case BUILT_IN_INFD128:
9869       return fold_builtin_inf (type, true);
9870
9871     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9872       return fold_builtin_inf (type, false);
9873
9874     case BUILT_IN_CLASSIFY_TYPE:
9875       return fold_builtin_classify_type (NULL_TREE);
9876
9877     default:
9878       break;
9879     }
9880   return NULL_TREE;
9881 }
9882
9883 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9884    IGNORE is true if the result of the function call is ignored.  This
9885    function returns NULL_TREE if no simplification was possible.  */
9886
9887 static tree
9888 fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
9889 {
9890   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9891   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9892   switch (fcode)
9893     {
9894
9895     case BUILT_IN_CONSTANT_P:
9896       {
9897         tree val = fold_builtin_constant_p (arg0);
9898
9899         /* Gimplification will pull the CALL_EXPR for the builtin out of
9900            an if condition.  When not optimizing, we'll not CSE it back.
9901            To avoid link error types of regressions, return false now.  */
9902         if (!val && !optimize)
9903           val = integer_zero_node;
9904
9905         return val;
9906       }
9907
9908     case BUILT_IN_CLASSIFY_TYPE:
9909       return fold_builtin_classify_type (arg0);
9910
9911     case BUILT_IN_STRLEN:
9912       return fold_builtin_strlen (arg0);
9913
9914     CASE_FLT_FN (BUILT_IN_FABS):
9915       return fold_builtin_fabs (arg0, type);
9916
9917     case BUILT_IN_ABS:
9918     case BUILT_IN_LABS:
9919     case BUILT_IN_LLABS:
9920     case BUILT_IN_IMAXABS:
9921       return fold_builtin_abs (arg0, type);
9922
9923     CASE_FLT_FN (BUILT_IN_CONJ):
9924       if (validate_arg (arg0, COMPLEX_TYPE))
9925         return fold_build1 (CONJ_EXPR, type, arg0);
9926     break;
9927
9928     CASE_FLT_FN (BUILT_IN_CREAL):
9929       if (validate_arg (arg0, COMPLEX_TYPE))
9930         return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
9931     break;
9932
9933     CASE_FLT_FN (BUILT_IN_CIMAG):
9934       if (validate_arg (arg0, COMPLEX_TYPE))
9935         return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
9936     break;
9937
9938     CASE_FLT_FN (BUILT_IN_CCOS):
9939     CASE_FLT_FN (BUILT_IN_CCOSH):
9940       /* These functions are "even", i.e. f(x) == f(-x).  */
9941       if (validate_arg (arg0, COMPLEX_TYPE))
9942         {
9943           tree narg = fold_strip_sign_ops (arg0);
9944           if (narg)
9945             return build_call_expr (fndecl, 1, narg);
9946         }
9947     break;
9948
9949     CASE_FLT_FN (BUILT_IN_CABS):
9950       return fold_builtin_cabs (arg0, type, fndecl);
9951
9952     CASE_FLT_FN (BUILT_IN_CARG):
9953       return fold_builtin_carg (arg0, type);
9954
9955     CASE_FLT_FN (BUILT_IN_SQRT):
9956       return fold_builtin_sqrt (arg0, type);
9957
9958     CASE_FLT_FN (BUILT_IN_CBRT):
9959       return fold_builtin_cbrt (arg0, type);
9960
9961     CASE_FLT_FN (BUILT_IN_ASIN):
9962       if (validate_arg (arg0, REAL_TYPE))
9963         return do_mpfr_arg1 (arg0, type, mpfr_asin,
9964                              &dconstm1, &dconst1, true);
9965     break;
9966
9967     CASE_FLT_FN (BUILT_IN_ACOS):
9968       if (validate_arg (arg0, REAL_TYPE))
9969         return do_mpfr_arg1 (arg0, type, mpfr_acos,
9970                              &dconstm1, &dconst1, true);
9971     break;
9972
9973     CASE_FLT_FN (BUILT_IN_ATAN):
9974       if (validate_arg (arg0, REAL_TYPE))
9975         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
9976     break;
9977
9978     CASE_FLT_FN (BUILT_IN_ASINH):
9979       if (validate_arg (arg0, REAL_TYPE))
9980         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
9981     break;
9982
9983     CASE_FLT_FN (BUILT_IN_ACOSH):
9984       if (validate_arg (arg0, REAL_TYPE))
9985         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
9986                              &dconst1, NULL, true);
9987     break;
9988
9989     CASE_FLT_FN (BUILT_IN_ATANH):
9990       if (validate_arg (arg0, REAL_TYPE))
9991         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
9992                              &dconstm1, &dconst1, false);
9993     break;
9994
9995     CASE_FLT_FN (BUILT_IN_SIN):
9996       if (validate_arg (arg0, REAL_TYPE))
9997         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
9998     break;
9999
10000     CASE_FLT_FN (BUILT_IN_COS):
10001       return fold_builtin_cos (arg0, type, fndecl);
10002     break;
10003
10004     CASE_FLT_FN (BUILT_IN_TAN):
10005       return fold_builtin_tan (arg0, type);
10006
10007     CASE_FLT_FN (BUILT_IN_CEXP):
10008       return fold_builtin_cexp (arg0, type);
10009
10010     CASE_FLT_FN (BUILT_IN_CEXPI):
10011       if (validate_arg (arg0, REAL_TYPE))
10012         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10013     break;
10014
10015     CASE_FLT_FN (BUILT_IN_SINH):
10016       if (validate_arg (arg0, REAL_TYPE))
10017         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10018     break;
10019
10020     CASE_FLT_FN (BUILT_IN_COSH):
10021       return fold_builtin_cosh (arg0, type, fndecl);
10022
10023     CASE_FLT_FN (BUILT_IN_TANH):
10024       if (validate_arg (arg0, REAL_TYPE))
10025         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10026     break;
10027
10028     CASE_FLT_FN (BUILT_IN_ERF):
10029       if (validate_arg (arg0, REAL_TYPE))
10030         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10031     break;
10032
10033     CASE_FLT_FN (BUILT_IN_ERFC):
10034       if (validate_arg (arg0, REAL_TYPE))
10035         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10036     break;
10037
10038     CASE_FLT_FN (BUILT_IN_TGAMMA):
10039       if (validate_arg (arg0, REAL_TYPE))
10040         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10041     break;
10042  
10043     CASE_FLT_FN (BUILT_IN_EXP):
10044       return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
10045
10046     CASE_FLT_FN (BUILT_IN_EXP2):
10047       return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
10048
10049     CASE_FLT_FN (BUILT_IN_EXP10):
10050     CASE_FLT_FN (BUILT_IN_POW10):
10051       return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
10052
10053     CASE_FLT_FN (BUILT_IN_EXPM1):
10054       if (validate_arg (arg0, REAL_TYPE))
10055         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10056     break;
10057  
10058     CASE_FLT_FN (BUILT_IN_LOG):
10059       return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
10060
10061     CASE_FLT_FN (BUILT_IN_LOG2):
10062       return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
10063
10064     CASE_FLT_FN (BUILT_IN_LOG10):
10065       return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
10066
10067     CASE_FLT_FN (BUILT_IN_LOG1P):
10068       if (validate_arg (arg0, REAL_TYPE))
10069         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10070                              &dconstm1, NULL, false);
10071     break;
10072
10073 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10074     CASE_FLT_FN (BUILT_IN_J0):
10075       if (validate_arg (arg0, REAL_TYPE))
10076         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10077                              NULL, NULL, 0);
10078     break;
10079
10080     CASE_FLT_FN (BUILT_IN_J1):
10081       if (validate_arg (arg0, REAL_TYPE))
10082         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10083                              NULL, NULL, 0);
10084     break;
10085
10086     CASE_FLT_FN (BUILT_IN_Y0):
10087       if (validate_arg (arg0, REAL_TYPE))
10088         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10089                              &dconst0, NULL, false);
10090     break;
10091
10092     CASE_FLT_FN (BUILT_IN_Y1):
10093       if (validate_arg (arg0, REAL_TYPE))
10094         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10095                              &dconst0, NULL, false);
10096     break;
10097 #endif
10098
10099     CASE_FLT_FN (BUILT_IN_NAN):
10100     case BUILT_IN_NAND32:
10101     case BUILT_IN_NAND64:
10102     case BUILT_IN_NAND128:
10103       return fold_builtin_nan (arg0, type, true);
10104
10105     CASE_FLT_FN (BUILT_IN_NANS):
10106       return fold_builtin_nan (arg0, type, false);
10107
10108     CASE_FLT_FN (BUILT_IN_FLOOR):
10109       return fold_builtin_floor (fndecl, arg0);
10110
10111     CASE_FLT_FN (BUILT_IN_CEIL):
10112       return fold_builtin_ceil (fndecl, arg0);
10113
10114     CASE_FLT_FN (BUILT_IN_TRUNC):
10115       return fold_builtin_trunc (fndecl, arg0);
10116
10117     CASE_FLT_FN (BUILT_IN_ROUND):
10118       return fold_builtin_round (fndecl, arg0);
10119
10120     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10121     CASE_FLT_FN (BUILT_IN_RINT):
10122       return fold_trunc_transparent_mathfn (fndecl, arg0);
10123
10124     CASE_FLT_FN (BUILT_IN_LCEIL):
10125     CASE_FLT_FN (BUILT_IN_LLCEIL):
10126     CASE_FLT_FN (BUILT_IN_LFLOOR):
10127     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10128     CASE_FLT_FN (BUILT_IN_LROUND):
10129     CASE_FLT_FN (BUILT_IN_LLROUND):
10130       return fold_builtin_int_roundingfn (fndecl, arg0);
10131
10132     CASE_FLT_FN (BUILT_IN_LRINT):
10133     CASE_FLT_FN (BUILT_IN_LLRINT):
10134       return fold_fixed_mathfn (fndecl, arg0);
10135
10136     case BUILT_IN_BSWAP32:
10137     case BUILT_IN_BSWAP64:
10138       return fold_builtin_bswap (fndecl, arg0);
10139
10140     CASE_INT_FN (BUILT_IN_FFS):
10141     CASE_INT_FN (BUILT_IN_CLZ):
10142     CASE_INT_FN (BUILT_IN_CTZ):
10143     CASE_INT_FN (BUILT_IN_POPCOUNT):
10144     CASE_INT_FN (BUILT_IN_PARITY):
10145       return fold_builtin_bitop (fndecl, arg0);
10146
10147     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10148       return fold_builtin_signbit (arg0, type);
10149
10150     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10151       return fold_builtin_significand (arg0, type);
10152
10153     CASE_FLT_FN (BUILT_IN_ILOGB):
10154     CASE_FLT_FN (BUILT_IN_LOGB):
10155       return fold_builtin_logb (arg0, type);
10156
10157     case BUILT_IN_ISASCII:
10158       return fold_builtin_isascii (arg0);
10159
10160     case BUILT_IN_TOASCII:
10161       return fold_builtin_toascii (arg0);
10162
10163     case BUILT_IN_ISDIGIT:
10164       return fold_builtin_isdigit (arg0);
10165
10166     CASE_FLT_FN (BUILT_IN_FINITE):
10167     case BUILT_IN_FINITED32:
10168     case BUILT_IN_FINITED64:
10169     case BUILT_IN_FINITED128:
10170     case BUILT_IN_ISFINITE:
10171       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
10172
10173     CASE_FLT_FN (BUILT_IN_ISINF):
10174     case BUILT_IN_ISINFD32:
10175     case BUILT_IN_ISINFD64:
10176     case BUILT_IN_ISINFD128:
10177       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
10178
10179     case BUILT_IN_ISINF_SIGN:
10180       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF_SIGN);
10181
10182     CASE_FLT_FN (BUILT_IN_ISNAN):
10183     case BUILT_IN_ISNAND32:
10184     case BUILT_IN_ISNAND64:
10185     case BUILT_IN_ISNAND128:
10186       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10187
10188     case BUILT_IN_PRINTF:
10189     case BUILT_IN_PRINTF_UNLOCKED:
10190     case BUILT_IN_VPRINTF:
10191       return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10192
10193     default:
10194       break;
10195     }
10196
10197   return NULL_TREE;
10198
10199 }
10200
10201 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10202    IGNORE is true if the result of the function call is ignored.  This
10203    function returns NULL_TREE if no simplification was possible.  */
10204
10205 static tree
10206 fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10207 {
10208   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10209   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10210
10211   switch (fcode)
10212     {
10213 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10214     CASE_FLT_FN (BUILT_IN_JN):
10215       if (validate_arg (arg0, INTEGER_TYPE)
10216           && validate_arg (arg1, REAL_TYPE))
10217         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10218     break;
10219
10220     CASE_FLT_FN (BUILT_IN_YN):
10221       if (validate_arg (arg0, INTEGER_TYPE)
10222           && validate_arg (arg1, REAL_TYPE))
10223         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10224                                  &dconst0, false);
10225     break;
10226
10227     CASE_FLT_FN (BUILT_IN_DREM):
10228     CASE_FLT_FN (BUILT_IN_REMAINDER):
10229       if (validate_arg (arg0, REAL_TYPE)
10230           && validate_arg(arg1, REAL_TYPE))
10231         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10232     break;
10233
10234     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10235     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10236       if (validate_arg (arg0, REAL_TYPE)
10237           && validate_arg(arg1, POINTER_TYPE))
10238         return do_mpfr_lgamma_r (arg0, arg1, type);
10239     break;
10240 #endif
10241
10242     CASE_FLT_FN (BUILT_IN_ATAN2):
10243       if (validate_arg (arg0, REAL_TYPE)
10244           && validate_arg(arg1, REAL_TYPE))
10245         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10246     break;
10247
10248     CASE_FLT_FN (BUILT_IN_FDIM):
10249       if (validate_arg (arg0, REAL_TYPE)
10250           && validate_arg(arg1, REAL_TYPE))
10251         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10252     break;
10253
10254     CASE_FLT_FN (BUILT_IN_HYPOT):
10255       return fold_builtin_hypot (fndecl, arg0, arg1, type);
10256
10257     CASE_FLT_FN (BUILT_IN_LDEXP):
10258       return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10259     CASE_FLT_FN (BUILT_IN_SCALBN):
10260     CASE_FLT_FN (BUILT_IN_SCALBLN):
10261       return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10262
10263     CASE_FLT_FN (BUILT_IN_FREXP):
10264       return fold_builtin_frexp (arg0, arg1, type);
10265
10266     CASE_FLT_FN (BUILT_IN_MODF):
10267       return fold_builtin_modf (arg0, arg1, type);
10268
10269     case BUILT_IN_BZERO:
10270       return fold_builtin_bzero (arg0, arg1, ignore);
10271
10272     case BUILT_IN_FPUTS:
10273       return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10274
10275     case BUILT_IN_FPUTS_UNLOCKED:
10276       return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10277
10278     case BUILT_IN_STRSTR:
10279       return fold_builtin_strstr (arg0, arg1, type);
10280
10281     case BUILT_IN_STRCAT:
10282       return fold_builtin_strcat (arg0, arg1);
10283
10284     case BUILT_IN_STRSPN:
10285       return fold_builtin_strspn (arg0, arg1);
10286
10287     case BUILT_IN_STRCSPN:
10288       return fold_builtin_strcspn (arg0, arg1);
10289
10290     case BUILT_IN_STRCHR:
10291     case BUILT_IN_INDEX:
10292       return fold_builtin_strchr (arg0, arg1, type);
10293
10294     case BUILT_IN_STRRCHR:
10295     case BUILT_IN_RINDEX:
10296       return fold_builtin_strrchr (arg0, arg1, type);
10297
10298     case BUILT_IN_STRCPY:
10299       return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10300
10301     case BUILT_IN_STRCMP:
10302       return fold_builtin_strcmp (arg0, arg1);
10303
10304     case BUILT_IN_STRPBRK:
10305       return fold_builtin_strpbrk (arg0, arg1, type);
10306
10307     case BUILT_IN_EXPECT:
10308       return fold_builtin_expect (arg0, arg1);
10309
10310     CASE_FLT_FN (BUILT_IN_POW):
10311       return fold_builtin_pow (fndecl, arg0, arg1, type);
10312
10313     CASE_FLT_FN (BUILT_IN_POWI):
10314       return fold_builtin_powi (fndecl, arg0, arg1, type);
10315
10316     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10317       return fold_builtin_copysign (fndecl, arg0, arg1, type);
10318
10319     CASE_FLT_FN (BUILT_IN_FMIN):
10320       return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10321
10322     CASE_FLT_FN (BUILT_IN_FMAX):
10323       return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
10324
10325     case BUILT_IN_ISGREATER:
10326       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
10327     case BUILT_IN_ISGREATEREQUAL:
10328       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
10329     case BUILT_IN_ISLESS:
10330       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
10331     case BUILT_IN_ISLESSEQUAL:
10332       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
10333     case BUILT_IN_ISLESSGREATER:
10334       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10335     case BUILT_IN_ISUNORDERED:
10336       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
10337                                          NOP_EXPR);
10338
10339       /* We do the folding for va_start in the expander.  */
10340     case BUILT_IN_VA_START:
10341       break;
10342
10343     case BUILT_IN_SPRINTF:
10344       return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10345
10346     case BUILT_IN_OBJECT_SIZE:
10347       return fold_builtin_object_size (arg0, arg1);
10348
10349     case BUILT_IN_PRINTF:
10350     case BUILT_IN_PRINTF_UNLOCKED:
10351     case BUILT_IN_VPRINTF:
10352       return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10353
10354     case BUILT_IN_PRINTF_CHK:
10355     case BUILT_IN_VPRINTF_CHK:
10356       if (!validate_arg (arg0, INTEGER_TYPE)
10357           || TREE_SIDE_EFFECTS (arg0))
10358         return NULL_TREE;
10359       else
10360         return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10361     break;
10362
10363     case BUILT_IN_FPRINTF:
10364     case BUILT_IN_FPRINTF_UNLOCKED:
10365     case BUILT_IN_VFPRINTF:
10366       return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10367                                    ignore, fcode);
10368
10369     default:
10370       break;
10371     }
10372   return NULL_TREE;
10373 }
10374
10375 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10376    and ARG2.  IGNORE is true if the result of the function call is ignored.
10377    This function returns NULL_TREE if no simplification was possible.  */
10378
10379 static tree
10380 fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10381 {
10382   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10383   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10384   switch (fcode)
10385     {
10386
10387     CASE_FLT_FN (BUILT_IN_SINCOS):
10388       return fold_builtin_sincos (arg0, arg1, arg2);
10389
10390     CASE_FLT_FN (BUILT_IN_FMA):
10391       if (validate_arg (arg0, REAL_TYPE)
10392           && validate_arg(arg1, REAL_TYPE)
10393           && validate_arg(arg2, REAL_TYPE))
10394         return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10395     break;
10396
10397 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
10398     CASE_FLT_FN (BUILT_IN_REMQUO):
10399       if (validate_arg (arg0, REAL_TYPE)
10400           && validate_arg(arg1, REAL_TYPE)
10401           && validate_arg(arg2, POINTER_TYPE))
10402         return do_mpfr_remquo (arg0, arg1, arg2);
10403     break;
10404 #endif
10405
10406     case BUILT_IN_MEMSET:
10407       return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10408
10409     case BUILT_IN_BCOPY:
10410         return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10411
10412     case BUILT_IN_MEMCPY:
10413       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10414
10415     case BUILT_IN_MEMPCPY:
10416       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10417
10418     case BUILT_IN_MEMMOVE:
10419       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10420
10421     case BUILT_IN_STRNCAT:
10422       return fold_builtin_strncat (arg0, arg1, arg2);
10423
10424     case BUILT_IN_STRNCPY:
10425       return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10426
10427     case BUILT_IN_STRNCMP:
10428       return fold_builtin_strncmp (arg0, arg1, arg2);
10429
10430     case BUILT_IN_MEMCHR:
10431       return fold_builtin_memchr (arg0, arg1, arg2, type);
10432
10433     case BUILT_IN_BCMP:
10434     case BUILT_IN_MEMCMP:
10435       return fold_builtin_memcmp (arg0, arg1, arg2);;
10436
10437     case BUILT_IN_SPRINTF:
10438       return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10439
10440     case BUILT_IN_STRCPY_CHK:
10441     case BUILT_IN_STPCPY_CHK:
10442       return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10443                                       ignore, fcode);
10444
10445     case BUILT_IN_STRCAT_CHK:
10446       return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10447
10448     case BUILT_IN_PRINTF_CHK:
10449     case BUILT_IN_VPRINTF_CHK:
10450       if (!validate_arg (arg0, INTEGER_TYPE)
10451           || TREE_SIDE_EFFECTS (arg0))
10452         return NULL_TREE;
10453       else
10454         return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10455     break;
10456
10457     case BUILT_IN_FPRINTF:
10458     case BUILT_IN_FPRINTF_UNLOCKED:
10459     case BUILT_IN_VFPRINTF:
10460       return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10461
10462     case BUILT_IN_FPRINTF_CHK:
10463     case BUILT_IN_VFPRINTF_CHK:
10464       if (!validate_arg (arg1, INTEGER_TYPE)
10465           || TREE_SIDE_EFFECTS (arg1))
10466         return NULL_TREE;
10467       else
10468         return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10469                                      ignore, fcode);
10470
10471     default:
10472       break;
10473     }
10474   return NULL_TREE;
10475 }
10476
10477 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10478    ARG2, and ARG3.  IGNORE is true if the result of the function call is
10479    ignored.  This function returns NULL_TREE if no simplification was
10480    possible.  */
10481  
10482 static tree
10483 fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10484                 bool ignore)
10485 {
10486   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10487
10488   switch (fcode)
10489     {
10490     case BUILT_IN_MEMCPY_CHK:
10491     case BUILT_IN_MEMPCPY_CHK:
10492     case BUILT_IN_MEMMOVE_CHK:
10493     case BUILT_IN_MEMSET_CHK:
10494       return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10495                                       NULL_TREE, ignore,
10496                                       DECL_FUNCTION_CODE (fndecl));
10497
10498     case BUILT_IN_STRNCPY_CHK:
10499       return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10500
10501     case BUILT_IN_STRNCAT_CHK:
10502       return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10503
10504     case BUILT_IN_FPRINTF_CHK:
10505     case BUILT_IN_VFPRINTF_CHK:
10506       if (!validate_arg (arg1, INTEGER_TYPE)
10507           || TREE_SIDE_EFFECTS (arg1))
10508         return NULL_TREE;
10509       else
10510         return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10511                                      ignore, fcode);
10512     break;
10513
10514     default:
10515       break;
10516     }
10517   return NULL_TREE;
10518 }
10519
10520 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
10521     arguments, where NARGS <= 4.  IGNORE is true if the result of the
10522     function call is ignored.  This function returns NULL_TREE if no
10523     simplification was possible.  Note that this only folds builtins with
10524     fixed argument patterns.  Foldings that do varargs-to-varargs
10525     transformations, or that match calls with more than 4 arguments,
10526     need to be handled with fold_builtin_varargs instead.  */
10527  
10528 #define MAX_ARGS_TO_FOLD_BUILTIN 4
10529  
10530 static tree
10531 fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10532 {
10533   tree ret = NULL_TREE;
10534
10535   switch (nargs)
10536     {
10537     case 0:
10538       ret = fold_builtin_0 (fndecl, ignore);
10539       break;
10540     case 1:
10541       ret = fold_builtin_1 (fndecl, args[0], ignore);
10542       break;
10543     case 2:
10544       ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10545       break;
10546     case 3:
10547       ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10548       break;
10549     case 4:
10550       ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10551                             ignore);
10552       break;
10553     default:
10554       break;
10555     }
10556   if (ret)
10557     {
10558       ret = build1 (NOP_EXPR, GENERIC_TREE_TYPE (ret), ret);
10559       TREE_NO_WARNING (ret) = 1;
10560       return ret;
10561     }
10562   return NULL_TREE;
10563 }
10564
10565 /* Builtins with folding operations that operate on "..." arguments
10566    need special handling; we need to store the arguments in a convenient
10567    data structure before attempting any folding.  Fortunately there are
10568    only a few builtins that fall into this category.  FNDECL is the
10569    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10570    result of the function call is ignored.  */
10571
10572 static tree
10573 fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10574 {
10575   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10576   tree ret = NULL_TREE;
10577
10578   switch (fcode)
10579     {
10580     case BUILT_IN_SPRINTF_CHK:
10581     case BUILT_IN_VSPRINTF_CHK:
10582       ret = fold_builtin_sprintf_chk (exp, fcode);
10583       break;
10584
10585     case BUILT_IN_SNPRINTF_CHK:
10586     case BUILT_IN_VSNPRINTF_CHK:
10587       ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
10588       break;
10589
10590     case BUILT_IN_FPCLASSIFY:
10591       ret = fold_builtin_fpclassify (exp);
10592       break;
10593
10594     default:
10595       break;
10596     }
10597   if (ret)
10598     {
10599       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10600       TREE_NO_WARNING (ret) = 1;
10601       return ret;
10602     }
10603   return NULL_TREE;
10604 }
10605
10606 /* A wrapper function for builtin folding that prevents warnings for
10607    "statement without effect" and the like, caused by removing the
10608    call node earlier than the warning is generated.  */
10609
10610 tree
10611 fold_call_expr (tree exp, bool ignore)
10612 {
10613   tree ret = NULL_TREE;
10614   tree fndecl = get_callee_fndecl (exp);
10615   if (fndecl
10616       && TREE_CODE (fndecl) == FUNCTION_DECL
10617       && DECL_BUILT_IN (fndecl)
10618       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10619          yet.  Defer folding until we see all the arguments
10620          (after inlining).  */
10621       && !CALL_EXPR_VA_ARG_PACK (exp))
10622     {
10623       int nargs = call_expr_nargs (exp);
10624
10625       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10626          instead last argument is __builtin_va_arg_pack ().  Defer folding
10627          even in that case, until arguments are finalized.  */
10628       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10629         {
10630           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10631           if (fndecl2
10632               && TREE_CODE (fndecl2) == FUNCTION_DECL
10633               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10634               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10635             return NULL_TREE;
10636         }
10637
10638       /* FIXME: Don't use a list in this interface.  */
10639       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10640           return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10641       else
10642         {
10643           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10644             {
10645               tree *args = CALL_EXPR_ARGP (exp);
10646               ret = fold_builtin_n (fndecl, args, nargs, ignore);
10647             }
10648           if (!ret)
10649             ret = fold_builtin_varargs (fndecl, exp, ignore);
10650           if (ret)
10651             {
10652               /* Propagate location information from original call to
10653                  expansion of builtin.  Otherwise things like
10654                  maybe_emit_chk_warning, that operate on the expansion
10655                  of a builtin, will use the wrong location information.  */
10656               if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
10657                 {
10658                   tree realret = ret;
10659                   if (TREE_CODE (ret) == NOP_EXPR)
10660                     realret = TREE_OPERAND (ret, 0);
10661                   if (CAN_HAVE_LOCATION_P (realret)
10662                       && !EXPR_HAS_LOCATION (realret))
10663                     SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
10664                   return realret;
10665                 }
10666               return ret;
10667             }
10668         }
10669     }
10670   return NULL_TREE;
10671 }
10672  
10673 /* Conveniently construct a function call expression.  FNDECL names the
10674     function to be called and ARGLIST is a TREE_LIST of arguments.  */
10675  
10676 tree
10677 build_function_call_expr (tree fndecl, tree arglist)
10678 {
10679   tree fntype = TREE_TYPE (fndecl);
10680   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10681   int n = list_length (arglist);
10682   tree *argarray = (tree *) alloca (n * sizeof (tree));
10683   int i;
10684   
10685   for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10686     argarray[i] = TREE_VALUE (arglist);
10687   return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10688 }
10689
10690 /* Conveniently construct a function call expression.  FNDECL names the
10691    function to be called, N is the number of arguments, and the "..."
10692    parameters are the argument expressions.  */
10693  
10694 tree
10695 build_call_expr (tree fndecl, int n, ...)
10696 {
10697   va_list ap;
10698   tree fntype = TREE_TYPE (fndecl);
10699   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10700   tree *argarray = (tree *) alloca (n * sizeof (tree));
10701   int i;
10702
10703   va_start (ap, n);
10704   for (i = 0; i < n; i++)
10705     argarray[i] = va_arg (ap, tree);
10706   va_end (ap);
10707   return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10708 }
10709
10710 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
10711    N arguments are passed in the array ARGARRAY.  */
10712
10713 tree
10714 fold_builtin_call_array (tree type,
10715                          tree fn,
10716                          int n,
10717                          tree *argarray)
10718 {
10719   tree ret = NULL_TREE;
10720   int i;
10721    tree exp;
10722
10723   if (TREE_CODE (fn) == ADDR_EXPR)
10724   {
10725     tree fndecl = TREE_OPERAND (fn, 0);
10726     if (TREE_CODE (fndecl) == FUNCTION_DECL
10727         && DECL_BUILT_IN (fndecl))
10728       {
10729         /* If last argument is __builtin_va_arg_pack (), arguments to this
10730            function are not finalized yet.  Defer folding until they are.  */
10731         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10732           {
10733             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10734             if (fndecl2
10735                 && TREE_CODE (fndecl2) == FUNCTION_DECL
10736                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10737                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10738               return build_call_array (type, fn, n, argarray);
10739           }
10740         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10741           {
10742             tree arglist = NULL_TREE;
10743             for (i = n - 1; i >= 0; i--)
10744               arglist = tree_cons (NULL_TREE, argarray[i], arglist);
10745             ret = targetm.fold_builtin (fndecl, arglist, false);
10746             if (ret)
10747               return ret;
10748           }
10749         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10750           {
10751             /* First try the transformations that don't require consing up
10752                an exp.  */
10753             ret = fold_builtin_n (fndecl, argarray, n, false);
10754             if (ret)
10755               return ret;
10756           }
10757
10758         /* If we got this far, we need to build an exp.  */
10759         exp = build_call_array (type, fn, n, argarray);
10760         ret = fold_builtin_varargs (fndecl, exp, false);
10761         return ret ? ret : exp;
10762       }
10763   }
10764
10765   return build_call_array (type, fn, n, argarray);
10766 }
10767
10768 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
10769    along with N new arguments specified as the "..." parameters.  SKIP
10770    is the number of arguments in EXP to be omitted.  This function is used
10771    to do varargs-to-varargs transformations.  */
10772
10773 static tree
10774 rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
10775 {
10776   int oldnargs = call_expr_nargs (exp);
10777   int nargs = oldnargs - skip + n;
10778   tree fntype = TREE_TYPE (fndecl);
10779   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10780   tree *buffer;
10781
10782   if (n > 0)
10783     {
10784       int i, j;
10785       va_list ap;
10786
10787       buffer = XALLOCAVEC (tree, nargs);
10788       va_start (ap, n);
10789       for (i = 0; i < n; i++)
10790         buffer[i] = va_arg (ap, tree);
10791       va_end (ap);
10792       for (j = skip; j < oldnargs; j++, i++)
10793         buffer[i] = CALL_EXPR_ARG (exp, j);
10794     }
10795   else 
10796     buffer = CALL_EXPR_ARGP (exp) + skip;
10797
10798   return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
10799 }
10800
10801 /* Validate a single argument ARG against a tree code CODE representing
10802    a type.  */
10803   
10804 static bool
10805 validate_arg (const_tree arg, enum tree_code code)
10806 {
10807   if (!arg)
10808     return false;
10809   else if (code == POINTER_TYPE)
10810     return POINTER_TYPE_P (TREE_TYPE (arg));
10811   else if (code == INTEGER_TYPE)
10812     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
10813   return code == TREE_CODE (TREE_TYPE (arg));
10814 }
10815
10816 /* This function validates the types of a function call argument list
10817    against a specified list of tree_codes.  If the last specifier is a 0,
10818    that represents an ellipses, otherwise the last specifier must be a
10819    VOID_TYPE.  */
10820
10821 bool
10822 validate_arglist (const_tree callexpr, ...)
10823 {
10824   enum tree_code code;
10825   bool res = 0;
10826   va_list ap;
10827   const_call_expr_arg_iterator iter;
10828   const_tree arg;
10829
10830   va_start (ap, callexpr);
10831   init_const_call_expr_arg_iterator (callexpr, &iter);
10832
10833   do
10834     {
10835       code = va_arg (ap, enum tree_code);
10836       switch (code)
10837         {
10838         case 0:
10839           /* This signifies an ellipses, any further arguments are all ok.  */
10840           res = true;
10841           goto end;
10842         case VOID_TYPE:
10843           /* This signifies an endlink, if no arguments remain, return
10844              true, otherwise return false.  */
10845           res = !more_const_call_expr_args_p (&iter);
10846           goto end;
10847         default:
10848           /* If no parameters remain or the parameter's code does not
10849              match the specified code, return false.  Otherwise continue
10850              checking any remaining arguments.  */
10851           arg = next_const_call_expr_arg (&iter);
10852           if (!validate_arg (arg, code))
10853             goto end;
10854           break;
10855         }
10856     }
10857   while (1);
10858
10859   /* We need gotos here since we can only have one VA_CLOSE in a
10860      function.  */
10861  end: ;
10862   va_end (ap);
10863
10864   return res;
10865 }
10866
10867 /* Default target-specific builtin expander that does nothing.  */
10868
10869 rtx
10870 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
10871                         rtx target ATTRIBUTE_UNUSED,
10872                         rtx subtarget ATTRIBUTE_UNUSED,
10873                         enum machine_mode mode ATTRIBUTE_UNUSED,
10874                         int ignore ATTRIBUTE_UNUSED)
10875 {
10876   return NULL_RTX;
10877 }
10878
10879 /* Returns true is EXP represents data that would potentially reside
10880    in a readonly section.  */
10881
10882 static bool
10883 readonly_data_expr (tree exp)
10884 {
10885   STRIP_NOPS (exp);
10886
10887   if (TREE_CODE (exp) != ADDR_EXPR)
10888     return false;
10889
10890   exp = get_base_address (TREE_OPERAND (exp, 0));
10891   if (!exp)
10892     return false;
10893
10894   /* Make sure we call decl_readonly_section only for trees it
10895      can handle (since it returns true for everything it doesn't
10896      understand).  */
10897   if (TREE_CODE (exp) == STRING_CST
10898       || TREE_CODE (exp) == CONSTRUCTOR
10899       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
10900     return decl_readonly_section (exp, 0);
10901   else
10902     return false;
10903 }
10904
10905 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
10906    to the call, and TYPE is its return type.
10907
10908    Return NULL_TREE if no simplification was possible, otherwise return the
10909    simplified form of the call as a tree.
10910
10911    The simplified form may be a constant or other expression which
10912    computes the same value, but in a more efficient manner (including
10913    calls to other builtin functions).
10914
10915    The call may contain arguments which need to be evaluated, but
10916    which are not useful to determine the result of the call.  In
10917    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10918    COMPOUND_EXPR will be an argument which must be evaluated.
10919    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10920    COMPOUND_EXPR in the chain will contain the tree for the simplified
10921    form of the builtin function call.  */
10922
10923 static tree
10924 fold_builtin_strstr (tree s1, tree s2, tree type)
10925 {
10926   if (!validate_arg (s1, POINTER_TYPE)
10927       || !validate_arg (s2, POINTER_TYPE))
10928     return NULL_TREE;
10929   else
10930     {
10931       tree fn;
10932       const char *p1, *p2;
10933
10934       p2 = c_getstr (s2);
10935       if (p2 == NULL)
10936         return NULL_TREE;
10937
10938       p1 = c_getstr (s1);
10939       if (p1 != NULL)
10940         {
10941           const char *r = strstr (p1, p2);
10942           tree tem;
10943
10944           if (r == NULL)
10945             return build_int_cst (TREE_TYPE (s1), 0);
10946
10947           /* Return an offset into the constant string argument.  */
10948           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
10949                              s1, size_int (r - p1));
10950           return fold_convert (type, tem);
10951         }
10952
10953       /* The argument is const char *, and the result is char *, so we need
10954          a type conversion here to avoid a warning.  */
10955       if (p2[0] == '\0')
10956         return fold_convert (type, s1);
10957
10958       if (p2[1] != '\0')
10959         return NULL_TREE;
10960
10961       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10962       if (!fn)
10963         return NULL_TREE;
10964
10965       /* New argument list transforming strstr(s1, s2) to
10966          strchr(s1, s2[0]).  */
10967       return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
10968     }
10969 }
10970
10971 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
10972    the call, and TYPE is its return type.
10973
10974    Return NULL_TREE if no simplification was possible, otherwise return the
10975    simplified form of the call as a tree.
10976
10977    The simplified form may be a constant or other expression which
10978    computes the same value, but in a more efficient manner (including
10979    calls to other builtin functions).
10980
10981    The call may contain arguments which need to be evaluated, but
10982    which are not useful to determine the result of the call.  In
10983    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10984    COMPOUND_EXPR will be an argument which must be evaluated.
10985    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10986    COMPOUND_EXPR in the chain will contain the tree for the simplified
10987    form of the builtin function call.  */
10988
10989 static tree
10990 fold_builtin_strchr (tree s1, tree s2, tree type)
10991 {
10992   if (!validate_arg (s1, POINTER_TYPE)
10993       || !validate_arg (s2, INTEGER_TYPE))
10994     return NULL_TREE;
10995   else
10996     {
10997       const char *p1;
10998
10999       if (TREE_CODE (s2) != INTEGER_CST)
11000         return NULL_TREE;
11001
11002       p1 = c_getstr (s1);
11003       if (p1 != NULL)
11004         {
11005           char c;
11006           const char *r;
11007           tree tem;
11008
11009           if (target_char_cast (s2, &c))
11010             return NULL_TREE;
11011
11012           r = strchr (p1, c);
11013
11014           if (r == NULL)
11015             return build_int_cst (TREE_TYPE (s1), 0);
11016
11017           /* Return an offset into the constant string argument.  */
11018           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11019                              s1, size_int (r - p1));
11020           return fold_convert (type, tem);
11021         }
11022       return NULL_TREE;
11023     }
11024 }
11025
11026 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11027    the call, and TYPE is its return type.
11028
11029    Return NULL_TREE if no simplification was possible, otherwise return the
11030    simplified form of the call as a tree.
11031
11032    The simplified form may be a constant or other expression which
11033    computes the same value, but in a more efficient manner (including
11034    calls to other builtin functions).
11035
11036    The call may contain arguments which need to be evaluated, but
11037    which are not useful to determine the result of the call.  In
11038    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11039    COMPOUND_EXPR will be an argument which must be evaluated.
11040    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11041    COMPOUND_EXPR in the chain will contain the tree for the simplified
11042    form of the builtin function call.  */
11043
11044 static tree
11045 fold_builtin_strrchr (tree s1, tree s2, tree type)
11046 {
11047   if (!validate_arg (s1, POINTER_TYPE)
11048       || !validate_arg (s2, INTEGER_TYPE))
11049     return NULL_TREE;
11050   else
11051     {
11052       tree fn;
11053       const char *p1;
11054
11055       if (TREE_CODE (s2) != INTEGER_CST)
11056         return NULL_TREE;
11057
11058       p1 = c_getstr (s1);
11059       if (p1 != NULL)
11060         {
11061           char c;
11062           const char *r;
11063           tree tem;
11064
11065           if (target_char_cast (s2, &c))
11066             return NULL_TREE;
11067
11068           r = strrchr (p1, c);
11069
11070           if (r == NULL)
11071             return build_int_cst (TREE_TYPE (s1), 0);
11072
11073           /* Return an offset into the constant string argument.  */
11074           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11075                              s1, size_int (r - p1));
11076           return fold_convert (type, tem);
11077         }
11078
11079       if (! integer_zerop (s2))
11080         return NULL_TREE;
11081
11082       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11083       if (!fn)
11084         return NULL_TREE;
11085
11086       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11087       return build_call_expr (fn, 2, s1, s2);
11088     }
11089 }
11090
11091 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11092    to the call, and TYPE is its return type.
11093
11094    Return NULL_TREE if no simplification was possible, otherwise return the
11095    simplified form of the call as a tree.
11096
11097    The simplified form may be a constant or other expression which
11098    computes the same value, but in a more efficient manner (including
11099    calls to other builtin functions).
11100
11101    The call may contain arguments which need to be evaluated, but
11102    which are not useful to determine the result of the call.  In
11103    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11104    COMPOUND_EXPR will be an argument which must be evaluated.
11105    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11106    COMPOUND_EXPR in the chain will contain the tree for the simplified
11107    form of the builtin function call.  */
11108
11109 static tree
11110 fold_builtin_strpbrk (tree s1, tree s2, tree type)
11111 {
11112   if (!validate_arg (s1, POINTER_TYPE)
11113       || !validate_arg (s2, POINTER_TYPE))
11114     return NULL_TREE;
11115   else
11116     {
11117       tree fn;
11118       const char *p1, *p2;
11119
11120       p2 = c_getstr (s2);
11121       if (p2 == NULL)
11122         return NULL_TREE;
11123
11124       p1 = c_getstr (s1);
11125       if (p1 != NULL)
11126         {
11127           const char *r = strpbrk (p1, p2);
11128           tree tem;
11129
11130           if (r == NULL)
11131             return build_int_cst (TREE_TYPE (s1), 0);
11132
11133           /* Return an offset into the constant string argument.  */
11134           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11135                              s1, size_int (r - p1));
11136           return fold_convert (type, tem);
11137         }
11138
11139       if (p2[0] == '\0')
11140         /* strpbrk(x, "") == NULL.
11141            Evaluate and ignore s1 in case it had side-effects.  */
11142         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
11143
11144       if (p2[1] != '\0')
11145         return NULL_TREE;  /* Really call strpbrk.  */
11146
11147       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11148       if (!fn)
11149         return NULL_TREE;
11150
11151       /* New argument list transforming strpbrk(s1, s2) to
11152          strchr(s1, s2[0]).  */
11153       return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11154     }
11155 }
11156
11157 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11158    to the call.
11159
11160    Return NULL_TREE if no simplification was possible, otherwise return the
11161    simplified form of the call as a tree.
11162
11163    The simplified form may be a constant or other expression which
11164    computes the same value, but in a more efficient manner (including
11165    calls to other builtin functions).
11166
11167    The call may contain arguments which need to be evaluated, but
11168    which are not useful to determine the result of the call.  In
11169    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11170    COMPOUND_EXPR will be an argument which must be evaluated.
11171    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11172    COMPOUND_EXPR in the chain will contain the tree for the simplified
11173    form of the builtin function call.  */
11174
11175 static tree
11176 fold_builtin_strcat (tree dst, tree src)
11177 {
11178   if (!validate_arg (dst, POINTER_TYPE)
11179       || !validate_arg (src, POINTER_TYPE))
11180     return NULL_TREE;
11181   else
11182     {
11183       const char *p = c_getstr (src);
11184
11185       /* If the string length is zero, return the dst parameter.  */
11186       if (p && *p == '\0')
11187         return dst;
11188
11189       return NULL_TREE;
11190     }
11191 }
11192
11193 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11194    arguments to the call.
11195
11196    Return NULL_TREE if no simplification was possible, otherwise return the
11197    simplified form of the call as a tree.
11198
11199    The simplified form may be a constant or other expression which
11200    computes the same value, but in a more efficient manner (including
11201    calls to other builtin functions).
11202
11203    The call may contain arguments which need to be evaluated, but
11204    which are not useful to determine the result of the call.  In
11205    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11206    COMPOUND_EXPR will be an argument which must be evaluated.
11207    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11208    COMPOUND_EXPR in the chain will contain the tree for the simplified
11209    form of the builtin function call.  */
11210
11211 static tree
11212 fold_builtin_strncat (tree dst, tree src, tree len)
11213 {
11214   if (!validate_arg (dst, POINTER_TYPE)
11215       || !validate_arg (src, POINTER_TYPE)
11216       || !validate_arg (len, INTEGER_TYPE))
11217     return NULL_TREE;
11218   else
11219     {
11220       const char *p = c_getstr (src);
11221
11222       /* If the requested length is zero, or the src parameter string
11223          length is zero, return the dst parameter.  */
11224       if (integer_zerop (len) || (p && *p == '\0'))
11225         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
11226
11227       /* If the requested len is greater than or equal to the string
11228          length, call strcat.  */
11229       if (TREE_CODE (len) == INTEGER_CST && p
11230           && compare_tree_int (len, strlen (p)) >= 0)
11231         {
11232           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11233
11234           /* If the replacement _DECL isn't initialized, don't do the
11235              transformation.  */
11236           if (!fn)
11237             return NULL_TREE;
11238
11239           return build_call_expr (fn, 2, dst, src);
11240         }
11241       return NULL_TREE;
11242     }
11243 }
11244
11245 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11246    to the call.
11247
11248    Return NULL_TREE if no simplification was possible, otherwise return the
11249    simplified form of the call as a tree.
11250
11251    The simplified form may be a constant or other expression which
11252    computes the same value, but in a more efficient manner (including
11253    calls to other builtin functions).
11254
11255    The call may contain arguments which need to be evaluated, but
11256    which are not useful to determine the result of the call.  In
11257    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11258    COMPOUND_EXPR will be an argument which must be evaluated.
11259    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11260    COMPOUND_EXPR in the chain will contain the tree for the simplified
11261    form of the builtin function call.  */
11262
11263 static tree
11264 fold_builtin_strspn (tree s1, tree s2)
11265 {
11266   if (!validate_arg (s1, POINTER_TYPE)
11267       || !validate_arg (s2, POINTER_TYPE))
11268     return NULL_TREE;
11269   else
11270     {
11271       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11272
11273       /* If both arguments are constants, evaluate at compile-time.  */
11274       if (p1 && p2)
11275         {
11276           const size_t r = strspn (p1, p2);
11277           return size_int (r);
11278         }
11279
11280       /* If either argument is "", return NULL_TREE.  */
11281       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11282         /* Evaluate and ignore both arguments in case either one has
11283            side-effects.  */
11284         return omit_two_operands (integer_type_node, integer_zero_node,
11285                                   s1, s2);
11286       return NULL_TREE;
11287     }
11288 }
11289
11290 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11291    to the call.
11292
11293    Return NULL_TREE if no simplification was possible, otherwise return the
11294    simplified form of the call as a tree.
11295
11296    The simplified form may be a constant or other expression which
11297    computes the same value, but in a more efficient manner (including
11298    calls to other builtin functions).
11299
11300    The call may contain arguments which need to be evaluated, but
11301    which are not useful to determine the result of the call.  In
11302    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11303    COMPOUND_EXPR will be an argument which must be evaluated.
11304    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11305    COMPOUND_EXPR in the chain will contain the tree for the simplified
11306    form of the builtin function call.  */
11307
11308 static tree
11309 fold_builtin_strcspn (tree s1, tree s2)
11310 {
11311   if (!validate_arg (s1, POINTER_TYPE)
11312       || !validate_arg (s2, POINTER_TYPE))
11313     return NULL_TREE;
11314   else
11315     {
11316       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11317
11318       /* If both arguments are constants, evaluate at compile-time.  */
11319       if (p1 && p2)
11320         {
11321           const size_t r = strcspn (p1, p2);
11322           return size_int (r);
11323         }
11324
11325       /* If the first argument is "", return NULL_TREE.  */
11326       if (p1 && *p1 == '\0')
11327         {
11328           /* Evaluate and ignore argument s2 in case it has
11329              side-effects.  */
11330           return omit_one_operand (integer_type_node,
11331                                    integer_zero_node, s2);
11332         }
11333
11334       /* If the second argument is "", return __builtin_strlen(s1).  */
11335       if (p2 && *p2 == '\0')
11336         {
11337           tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11338
11339           /* If the replacement _DECL isn't initialized, don't do the
11340              transformation.  */
11341           if (!fn)
11342             return NULL_TREE;
11343
11344           return build_call_expr (fn, 1, s1);
11345         }
11346       return NULL_TREE;
11347     }
11348 }
11349
11350 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
11351    to the call.  IGNORE is true if the value returned
11352    by the builtin will be ignored.  UNLOCKED is true is true if this
11353    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
11354    the known length of the string.  Return NULL_TREE if no simplification
11355    was possible.  */
11356
11357 tree
11358 fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
11359 {
11360   /* If we're using an unlocked function, assume the other unlocked
11361      functions exist explicitly.  */
11362   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
11363     : implicit_built_in_decls[BUILT_IN_FPUTC];
11364   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
11365     : implicit_built_in_decls[BUILT_IN_FWRITE];
11366
11367   /* If the return value is used, don't do the transformation.  */
11368   if (!ignore)
11369     return NULL_TREE;
11370
11371   /* Verify the arguments in the original call.  */
11372   if (!validate_arg (arg0, POINTER_TYPE)
11373       || !validate_arg (arg1, POINTER_TYPE))
11374     return NULL_TREE;
11375
11376   if (! len)
11377     len = c_strlen (arg0, 0);
11378
11379   /* Get the length of the string passed to fputs.  If the length
11380      can't be determined, punt.  */
11381   if (!len
11382       || TREE_CODE (len) != INTEGER_CST)
11383     return NULL_TREE;
11384
11385   switch (compare_tree_int (len, 1))
11386     {
11387     case -1: /* length is 0, delete the call entirely .  */
11388       return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
11389
11390     case 0: /* length is 1, call fputc.  */
11391       {
11392         const char *p = c_getstr (arg0);
11393
11394         if (p != NULL)
11395           {
11396             if (fn_fputc)
11397               return build_call_expr (fn_fputc, 2,
11398                                       build_int_cst (NULL_TREE, p[0]), arg1);
11399             else
11400               return NULL_TREE;
11401           }
11402       }
11403       /* FALLTHROUGH */
11404     case 1: /* length is greater than 1, call fwrite.  */
11405       {
11406         /* If optimizing for size keep fputs.  */
11407         if (optimize_size)
11408           return NULL_TREE;
11409         /* New argument list transforming fputs(string, stream) to
11410            fwrite(string, 1, len, stream).  */
11411         if (fn_fwrite)
11412           return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11413         else
11414           return NULL_TREE;
11415       }
11416     default:
11417       gcc_unreachable ();
11418     }
11419   return NULL_TREE;
11420 }
11421
11422 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
11423    produced.  False otherwise.  This is done so that we don't output the error
11424    or warning twice or three times.  */
11425 bool
11426 fold_builtin_next_arg (tree exp, bool va_start_p)
11427 {
11428   tree fntype = TREE_TYPE (current_function_decl);
11429   int nargs = call_expr_nargs (exp);
11430   tree arg;
11431
11432   if (TYPE_ARG_TYPES (fntype) == 0
11433       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11434           == void_type_node))
11435     {
11436       error ("%<va_start%> used in function with fixed args");
11437       return true;
11438     }
11439
11440   if (va_start_p)
11441     {
11442       if (va_start_p && (nargs != 2))
11443         {
11444           error ("wrong number of arguments to function %<va_start%>");
11445           return true;
11446         }
11447       arg = CALL_EXPR_ARG (exp, 1);
11448     }
11449   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11450      when we checked the arguments and if needed issued a warning.  */
11451   else
11452     {
11453       if (nargs == 0)
11454         {
11455           /* Evidently an out of date version of <stdarg.h>; can't validate
11456              va_start's second argument, but can still work as intended.  */
11457           warning (0, "%<__builtin_next_arg%> called without an argument");
11458           return true;
11459         }
11460       else if (nargs > 1)
11461         {
11462           error ("wrong number of arguments to function %<__builtin_next_arg%>");
11463           return true;
11464         }
11465       arg = CALL_EXPR_ARG (exp, 0);
11466     }
11467
11468   /* We destructively modify the call to be __builtin_va_start (ap, 0)
11469      or __builtin_next_arg (0) the first time we see it, after checking 
11470      the arguments and if needed issuing a warning.  */
11471   if (!integer_zerop (arg))
11472     {
11473       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
11474
11475       /* Strip off all nops for the sake of the comparison.  This
11476          is not quite the same as STRIP_NOPS.  It does more.
11477          We must also strip off INDIRECT_EXPR for C++ reference
11478          parameters.  */
11479       while (CONVERT_EXPR_P (arg)
11480              || TREE_CODE (arg) == INDIRECT_REF)
11481         arg = TREE_OPERAND (arg, 0);
11482       if (arg != last_parm)
11483         {
11484           /* FIXME: Sometimes with the tree optimizers we can get the
11485              not the last argument even though the user used the last
11486              argument.  We just warn and set the arg to be the last
11487              argument so that we will get wrong-code because of
11488              it.  */
11489           warning (0, "second parameter of %<va_start%> not last named argument");
11490         }
11491       /* We want to verify the second parameter just once before the tree
11492          optimizers are run and then avoid keeping it in the tree,
11493          as otherwise we could warn even for correct code like:
11494          void foo (int i, ...)
11495          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
11496       if (va_start_p)
11497         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11498       else
11499         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
11500     }
11501   return false;
11502 }
11503
11504
11505 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11506    ORIG may be null if this is a 2-argument call.  We don't attempt to
11507    simplify calls with more than 3 arguments.
11508
11509    Return NULL_TREE if no simplification was possible, otherwise return the
11510    simplified form of the call as a tree.  If IGNORED is true, it means that
11511    the caller does not use the returned value of the function.  */
11512
11513 static tree
11514 fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
11515 {
11516   tree call, retval;
11517   const char *fmt_str = NULL;
11518
11519   /* Verify the required arguments in the original call.  We deal with two
11520      types of sprintf() calls: 'sprintf (str, fmt)' and
11521      'sprintf (dest, "%s", orig)'.  */
11522   if (!validate_arg (dest, POINTER_TYPE)
11523       || !validate_arg (fmt, POINTER_TYPE))
11524     return NULL_TREE;
11525   if (orig && !validate_arg (orig, POINTER_TYPE))
11526     return NULL_TREE;
11527
11528   /* Check whether the format is a literal string constant.  */
11529   fmt_str = c_getstr (fmt);
11530   if (fmt_str == NULL)
11531     return NULL_TREE;
11532
11533   call = NULL_TREE;
11534   retval = NULL_TREE;
11535
11536   if (!init_target_chars ())
11537     return NULL_TREE;
11538
11539   /* If the format doesn't contain % args or %%, use strcpy.  */
11540   if (strchr (fmt_str, target_percent) == NULL)
11541     {
11542       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11543
11544       if (!fn)
11545         return NULL_TREE;
11546
11547       /* Don't optimize sprintf (buf, "abc", ptr++).  */
11548       if (orig)
11549         return NULL_TREE;
11550
11551       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11552          'format' is known to contain no % formats.  */
11553       call = build_call_expr (fn, 2, dest, fmt);
11554       if (!ignored)
11555         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
11556     }
11557
11558   /* If the format is "%s", use strcpy if the result isn't used.  */
11559   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
11560     {
11561       tree fn;
11562       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11563
11564       if (!fn)
11565         return NULL_TREE;
11566
11567       /* Don't crash on sprintf (str1, "%s").  */
11568       if (!orig)
11569         return NULL_TREE;
11570
11571       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
11572       if (!ignored)
11573         {
11574           retval = c_strlen (orig, 1);
11575           if (!retval || TREE_CODE (retval) != INTEGER_CST)
11576             return NULL_TREE;
11577         }
11578       call = build_call_expr (fn, 2, dest, orig);
11579     }
11580
11581   if (call && retval)
11582     {
11583       retval = fold_convert
11584         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
11585          retval);
11586       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
11587     }
11588   else
11589     return call;
11590 }
11591
11592 /* Expand a call EXP to __builtin_object_size.  */
11593
11594 rtx
11595 expand_builtin_object_size (tree exp)
11596 {
11597   tree ost;
11598   int object_size_type;
11599   tree fndecl = get_callee_fndecl (exp);
11600
11601   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
11602     {
11603       error ("%Kfirst argument of %D must be a pointer, second integer constant",
11604              exp, fndecl);
11605       expand_builtin_trap ();
11606       return const0_rtx;
11607     }
11608
11609   ost = CALL_EXPR_ARG (exp, 1);
11610   STRIP_NOPS (ost);
11611
11612   if (TREE_CODE (ost) != INTEGER_CST
11613       || tree_int_cst_sgn (ost) < 0
11614       || compare_tree_int (ost, 3) > 0)
11615     {
11616       error ("%Klast argument of %D is not integer constant between 0 and 3",
11617              exp, fndecl);
11618       expand_builtin_trap ();
11619       return const0_rtx;
11620     }
11621
11622   object_size_type = tree_low_cst (ost, 0);
11623
11624   return object_size_type < 2 ? constm1_rtx : const0_rtx;
11625 }
11626
11627 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11628    FCODE is the BUILT_IN_* to use.
11629    Return NULL_RTX if we failed; the caller should emit a normal call,
11630    otherwise try to get the result in TARGET, if convenient (and in
11631    mode MODE if that's convenient).  */
11632
11633 static rtx
11634 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11635                            enum built_in_function fcode)
11636 {
11637   tree dest, src, len, size;
11638
11639   if (!validate_arglist (exp,
11640                          POINTER_TYPE,
11641                          fcode == BUILT_IN_MEMSET_CHK
11642                          ? INTEGER_TYPE : POINTER_TYPE,
11643                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
11644     return NULL_RTX;
11645
11646   dest = CALL_EXPR_ARG (exp, 0);
11647   src = CALL_EXPR_ARG (exp, 1);
11648   len = CALL_EXPR_ARG (exp, 2);
11649   size = CALL_EXPR_ARG (exp, 3);
11650
11651   if (! host_integerp (size, 1))
11652     return NULL_RTX;
11653
11654   if (host_integerp (len, 1) || integer_all_onesp (size))
11655     {
11656       tree fn;
11657
11658       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11659         {
11660           warning (0, "%Kcall to %D will always overflow destination buffer",
11661                    exp, get_callee_fndecl (exp));
11662           return NULL_RTX;
11663         }
11664
11665       fn = NULL_TREE;
11666       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11667          mem{cpy,pcpy,move,set} is available.  */
11668       switch (fcode)
11669         {
11670         case BUILT_IN_MEMCPY_CHK:
11671           fn = built_in_decls[BUILT_IN_MEMCPY];
11672           break;
11673         case BUILT_IN_MEMPCPY_CHK:
11674           fn = built_in_decls[BUILT_IN_MEMPCPY];
11675           break;
11676         case BUILT_IN_MEMMOVE_CHK:
11677           fn = built_in_decls[BUILT_IN_MEMMOVE];
11678           break;
11679         case BUILT_IN_MEMSET_CHK:
11680           fn = built_in_decls[BUILT_IN_MEMSET];
11681           break;
11682         default:
11683           break;
11684         }
11685
11686       if (! fn)
11687         return NULL_RTX;
11688
11689       fn = build_call_expr (fn, 3, dest, src, len);
11690       STRIP_TYPE_NOPS (fn);
11691       while (TREE_CODE (fn) == COMPOUND_EXPR)
11692         {
11693           expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
11694                        EXPAND_NORMAL);
11695           fn = TREE_OPERAND (fn, 1);
11696         }
11697       if (TREE_CODE (fn) == CALL_EXPR)
11698         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11699       return expand_expr (fn, target, mode, EXPAND_NORMAL);
11700     }
11701   else if (fcode == BUILT_IN_MEMSET_CHK)
11702     return NULL_RTX;
11703   else
11704     {
11705       unsigned int dest_align
11706         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
11707
11708       /* If DEST is not a pointer type, call the normal function.  */
11709       if (dest_align == 0)
11710         return NULL_RTX;
11711
11712       /* If SRC and DEST are the same (and not volatile), do nothing.  */
11713       if (operand_equal_p (src, dest, 0))
11714         {
11715           tree expr;
11716
11717           if (fcode != BUILT_IN_MEMPCPY_CHK)
11718             {
11719               /* Evaluate and ignore LEN in case it has side-effects.  */
11720               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
11721               return expand_expr (dest, target, mode, EXPAND_NORMAL);
11722             }
11723
11724           expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
11725           return expand_expr (expr, target, mode, EXPAND_NORMAL);
11726         }
11727
11728       /* __memmove_chk special case.  */
11729       if (fcode == BUILT_IN_MEMMOVE_CHK)
11730         {
11731           unsigned int src_align
11732             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
11733
11734           if (src_align == 0)
11735             return NULL_RTX;
11736
11737           /* If src is categorized for a readonly section we can use
11738              normal __memcpy_chk.  */
11739           if (readonly_data_expr (src))
11740             {
11741               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11742               if (!fn)
11743                 return NULL_RTX;
11744               fn = build_call_expr (fn, 4, dest, src, len, size);
11745               STRIP_TYPE_NOPS (fn);
11746               while (TREE_CODE (fn) == COMPOUND_EXPR)
11747                 {
11748                   expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
11749                                EXPAND_NORMAL);
11750                   fn = TREE_OPERAND (fn, 1);
11751                 }
11752               if (TREE_CODE (fn) == CALL_EXPR)
11753                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
11754               return expand_expr (fn, target, mode, EXPAND_NORMAL);
11755             }
11756         }
11757       return NULL_RTX;
11758     }
11759 }
11760
11761 /* Emit warning if a buffer overflow is detected at compile time.  */
11762
11763 static void
11764 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
11765 {
11766   int is_strlen = 0;
11767   tree len, size;
11768
11769   switch (fcode)
11770     {
11771     case BUILT_IN_STRCPY_CHK:
11772     case BUILT_IN_STPCPY_CHK:
11773     /* For __strcat_chk the warning will be emitted only if overflowing
11774        by at least strlen (dest) + 1 bytes.  */
11775     case BUILT_IN_STRCAT_CHK:
11776       len = CALL_EXPR_ARG (exp, 1);
11777       size = CALL_EXPR_ARG (exp, 2);
11778       is_strlen = 1;
11779       break;
11780     case BUILT_IN_STRNCAT_CHK:
11781     case BUILT_IN_STRNCPY_CHK:
11782       len = CALL_EXPR_ARG (exp, 2);
11783       size = CALL_EXPR_ARG (exp, 3);
11784       break;
11785     case BUILT_IN_SNPRINTF_CHK:
11786     case BUILT_IN_VSNPRINTF_CHK:
11787       len = CALL_EXPR_ARG (exp, 1);
11788       size = CALL_EXPR_ARG (exp, 3);
11789       break;
11790     default:
11791       gcc_unreachable ();
11792     }
11793
11794   if (!len || !size)
11795     return;
11796
11797   if (! host_integerp (size, 1) || integer_all_onesp (size))
11798     return;
11799
11800   if (is_strlen)
11801     {
11802       len = c_strlen (len, 1);
11803       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11804         return;
11805     }
11806   else if (fcode == BUILT_IN_STRNCAT_CHK)
11807     {
11808       tree src = CALL_EXPR_ARG (exp, 1);
11809       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
11810         return;
11811       src = c_strlen (src, 1);
11812       if (! src || ! host_integerp (src, 1))
11813         {
11814           warning (0, "%Kcall to %D might overflow destination buffer",
11815                    exp, get_callee_fndecl (exp));
11816           return;
11817         }
11818       else if (tree_int_cst_lt (src, size))
11819         return;
11820     }
11821   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
11822     return;
11823
11824   warning (0, "%Kcall to %D will always overflow destination buffer",
11825            exp, get_callee_fndecl (exp));
11826 }
11827
11828 /* Emit warning if a buffer overflow is detected at compile time
11829    in __sprintf_chk/__vsprintf_chk calls.  */
11830
11831 static void
11832 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
11833 {
11834   tree dest, size, len, fmt, flag;
11835   const char *fmt_str;
11836   int nargs = call_expr_nargs (exp);
11837
11838   /* Verify the required arguments in the original call.  */
11839   
11840   if (nargs < 4)
11841     return;
11842   dest = CALL_EXPR_ARG (exp, 0);
11843   flag = CALL_EXPR_ARG (exp, 1);
11844   size = CALL_EXPR_ARG (exp, 2);
11845   fmt = CALL_EXPR_ARG (exp, 3);
11846
11847   if (! host_integerp (size, 1) || integer_all_onesp (size))
11848     return;
11849
11850   /* Check whether the format is a literal string constant.  */
11851   fmt_str = c_getstr (fmt);
11852   if (fmt_str == NULL)
11853     return;
11854
11855   if (!init_target_chars ())
11856     return;
11857
11858   /* If the format doesn't contain % args or %%, we know its size.  */
11859   if (strchr (fmt_str, target_percent) == 0)
11860     len = build_int_cstu (size_type_node, strlen (fmt_str));
11861   /* If the format is "%s" and first ... argument is a string literal,
11862      we know it too.  */
11863   else if (fcode == BUILT_IN_SPRINTF_CHK
11864            && strcmp (fmt_str, target_percent_s) == 0)
11865     {
11866       tree arg;
11867
11868       if (nargs < 5)
11869         return;
11870       arg = CALL_EXPR_ARG (exp, 4);
11871       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
11872         return;
11873
11874       len = c_strlen (arg, 1);
11875       if (!len || ! host_integerp (len, 1))
11876         return;
11877     }
11878   else
11879     return;
11880
11881   if (! tree_int_cst_lt (len, size))
11882     {
11883       warning (0, "%Kcall to %D will always overflow destination buffer",
11884                exp, get_callee_fndecl (exp));
11885     }
11886 }
11887
11888 /* Fold a call to __builtin_object_size with arguments PTR and OST,
11889    if possible.  */
11890
11891 tree
11892 fold_builtin_object_size (tree ptr, tree ost)
11893 {
11894   tree ret = NULL_TREE;
11895   int object_size_type;
11896
11897   if (!validate_arg (ptr, POINTER_TYPE)
11898       || !validate_arg (ost, INTEGER_TYPE))
11899     return NULL_TREE;
11900
11901   STRIP_NOPS (ost);
11902
11903   if (TREE_CODE (ost) != INTEGER_CST
11904       || tree_int_cst_sgn (ost) < 0
11905       || compare_tree_int (ost, 3) > 0)
11906     return NULL_TREE;
11907
11908   object_size_type = tree_low_cst (ost, 0);
11909
11910   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
11911      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
11912      and (size_t) 0 for types 2 and 3.  */
11913   if (TREE_SIDE_EFFECTS (ptr))
11914     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
11915
11916   if (TREE_CODE (ptr) == ADDR_EXPR)
11917     ret = build_int_cstu (size_type_node,
11918                           compute_builtin_object_size (ptr, object_size_type));
11919
11920   else if (TREE_CODE (ptr) == SSA_NAME)
11921     {
11922       unsigned HOST_WIDE_INT bytes;
11923
11924       /* If object size is not known yet, delay folding until
11925        later.  Maybe subsequent passes will help determining
11926        it.  */
11927       bytes = compute_builtin_object_size (ptr, object_size_type);
11928       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
11929                                              ? -1 : 0))
11930         ret = build_int_cstu (size_type_node, bytes);
11931     }
11932
11933   if (ret)
11934     {
11935       unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
11936       HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
11937       if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
11938         ret = NULL_TREE;
11939     }
11940
11941   return ret;
11942 }
11943
11944 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11945    DEST, SRC, LEN, and SIZE are the arguments to the call.
11946    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
11947    code of the builtin.  If MAXLEN is not NULL, it is maximum length
11948    passed as third argument.  */
11949
11950 tree
11951 fold_builtin_memory_chk (tree fndecl,
11952                          tree dest, tree src, tree len, tree size,
11953                          tree maxlen, bool ignore,
11954                          enum built_in_function fcode)
11955 {
11956   tree fn;
11957
11958   if (!validate_arg (dest, POINTER_TYPE)
11959       || !validate_arg (src,
11960                         (fcode == BUILT_IN_MEMSET_CHK
11961                          ? INTEGER_TYPE : POINTER_TYPE))
11962       || !validate_arg (len, INTEGER_TYPE)
11963       || !validate_arg (size, INTEGER_TYPE))
11964     return NULL_TREE;
11965
11966   /* If SRC and DEST are the same (and not volatile), return DEST
11967      (resp. DEST+LEN for __mempcpy_chk).  */
11968   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
11969     {
11970       if (fcode != BUILT_IN_MEMPCPY_CHK)
11971         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11972       else
11973         {
11974           tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
11975           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
11976         }
11977     }
11978
11979   if (! host_integerp (size, 1))
11980     return NULL_TREE;
11981
11982   if (! integer_all_onesp (size))
11983     {
11984       if (! host_integerp (len, 1))
11985         {
11986           /* If LEN is not constant, try MAXLEN too.
11987              For MAXLEN only allow optimizing into non-_ocs function
11988              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
11989           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11990             {
11991               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
11992                 {
11993                   /* (void) __mempcpy_chk () can be optimized into
11994                      (void) __memcpy_chk ().  */
11995                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
11996                   if (!fn)
11997                     return NULL_TREE;
11998
11999                   return build_call_expr (fn, 4, dest, src, len, size);
12000                 }
12001               return NULL_TREE;
12002             }
12003         }
12004       else
12005         maxlen = len;
12006
12007       if (tree_int_cst_lt (size, maxlen))
12008         return NULL_TREE;
12009     }
12010
12011   fn = NULL_TREE;
12012   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12013      mem{cpy,pcpy,move,set} is available.  */
12014   switch (fcode)
12015     {
12016     case BUILT_IN_MEMCPY_CHK:
12017       fn = built_in_decls[BUILT_IN_MEMCPY];
12018       break;
12019     case BUILT_IN_MEMPCPY_CHK:
12020       fn = built_in_decls[BUILT_IN_MEMPCPY];
12021       break;
12022     case BUILT_IN_MEMMOVE_CHK:
12023       fn = built_in_decls[BUILT_IN_MEMMOVE];
12024       break;
12025     case BUILT_IN_MEMSET_CHK:
12026       fn = built_in_decls[BUILT_IN_MEMSET];
12027       break;
12028     default:
12029       break;
12030     }
12031
12032   if (!fn)
12033     return NULL_TREE;
12034
12035   return build_call_expr (fn, 3, dest, src, len);
12036 }
12037
12038 /* Fold a call to the __st[rp]cpy_chk builtin.
12039    DEST, SRC, and SIZE are the arguments to the call.
12040    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12041    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12042    strings passed as second argument.  */
12043
12044 tree
12045 fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
12046                          tree maxlen, bool ignore,
12047                          enum built_in_function fcode)
12048 {
12049   tree len, fn;
12050
12051   if (!validate_arg (dest, POINTER_TYPE)
12052       || !validate_arg (src, POINTER_TYPE)
12053       || !validate_arg (size, INTEGER_TYPE))
12054     return NULL_TREE;
12055
12056   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12057   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12058     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
12059
12060   if (! host_integerp (size, 1))
12061     return NULL_TREE;
12062
12063   if (! integer_all_onesp (size))
12064     {
12065       len = c_strlen (src, 1);
12066       if (! len || ! host_integerp (len, 1))
12067         {
12068           /* If LEN is not constant, try MAXLEN too.
12069              For MAXLEN only allow optimizing into non-_ocs function
12070              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12071           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12072             {
12073               if (fcode == BUILT_IN_STPCPY_CHK)
12074                 {
12075                   if (! ignore)
12076                     return NULL_TREE;
12077
12078                   /* If return value of __stpcpy_chk is ignored,
12079                      optimize into __strcpy_chk.  */
12080                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12081                   if (!fn)
12082                     return NULL_TREE;
12083
12084                   return build_call_expr (fn, 3, dest, src, size);
12085                 }
12086
12087               if (! len || TREE_SIDE_EFFECTS (len))
12088                 return NULL_TREE;
12089
12090               /* If c_strlen returned something, but not a constant,
12091                  transform __strcpy_chk into __memcpy_chk.  */
12092               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12093               if (!fn)
12094                 return NULL_TREE;
12095
12096               len = size_binop (PLUS_EXPR, len, ssize_int (1));
12097               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
12098                                    build_call_expr (fn, 4,
12099                                                     dest, src, len, size));
12100             }
12101         }
12102       else
12103         maxlen = len;
12104
12105       if (! tree_int_cst_lt (maxlen, size))
12106         return NULL_TREE;
12107     }
12108
12109   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12110   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12111                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12112   if (!fn)
12113     return NULL_TREE;
12114
12115   return build_call_expr (fn, 2, dest, src);
12116 }
12117
12118 /* Fold a call to the __strncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12119    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12120    length passed as third argument.  */
12121
12122 tree
12123 fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
12124                           tree maxlen)
12125 {
12126   tree fn;
12127
12128   if (!validate_arg (dest, POINTER_TYPE)
12129       || !validate_arg (src, POINTER_TYPE)
12130       || !validate_arg (len, INTEGER_TYPE)
12131       || !validate_arg (size, INTEGER_TYPE))
12132     return NULL_TREE;
12133
12134   if (! host_integerp (size, 1))
12135     return NULL_TREE;
12136
12137   if (! integer_all_onesp (size))
12138     {
12139       if (! host_integerp (len, 1))
12140         {
12141           /* If LEN is not constant, try MAXLEN too.
12142              For MAXLEN only allow optimizing into non-_ocs function
12143              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12144           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12145             return NULL_TREE;
12146         }
12147       else
12148         maxlen = len;
12149
12150       if (tree_int_cst_lt (size, maxlen))
12151         return NULL_TREE;
12152     }
12153
12154   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
12155   fn = built_in_decls[BUILT_IN_STRNCPY];
12156   if (!fn)
12157     return NULL_TREE;
12158
12159   return build_call_expr (fn, 3, dest, src, len);
12160 }
12161
12162 /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
12163    are the arguments to the call.  */
12164
12165 static tree
12166 fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
12167 {
12168   tree fn;
12169   const char *p;
12170
12171   if (!validate_arg (dest, POINTER_TYPE)
12172       || !validate_arg (src, POINTER_TYPE)
12173       || !validate_arg (size, INTEGER_TYPE))
12174     return NULL_TREE;
12175
12176   p = c_getstr (src);
12177   /* If the SRC parameter is "", return DEST.  */
12178   if (p && *p == '\0')
12179     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12180
12181   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12182     return NULL_TREE;
12183
12184   /* If __builtin_strcat_chk is used, assume strcat is available.  */
12185   fn = built_in_decls[BUILT_IN_STRCAT];
12186   if (!fn)
12187     return NULL_TREE;
12188
12189   return build_call_expr (fn, 2, dest, src);
12190 }
12191
12192 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12193    LEN, and SIZE.  */
12194
12195 static tree
12196 fold_builtin_strncat_chk (tree fndecl,
12197                           tree dest, tree src, tree len, tree size)
12198 {
12199   tree fn;
12200   const char *p;
12201
12202   if (!validate_arg (dest, POINTER_TYPE)
12203       || !validate_arg (src, POINTER_TYPE)
12204       || !validate_arg (size, INTEGER_TYPE)
12205       || !validate_arg (size, INTEGER_TYPE))
12206     return NULL_TREE;
12207
12208   p = c_getstr (src);
12209   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
12210   if (p && *p == '\0')
12211     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12212   else if (integer_zerop (len))
12213     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12214
12215   if (! host_integerp (size, 1))
12216     return NULL_TREE;
12217
12218   if (! integer_all_onesp (size))
12219     {
12220       tree src_len = c_strlen (src, 1);
12221       if (src_len
12222           && host_integerp (src_len, 1)
12223           && host_integerp (len, 1)
12224           && ! tree_int_cst_lt (len, src_len))
12225         {
12226           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
12227           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12228           if (!fn)
12229             return NULL_TREE;
12230
12231           return build_call_expr (fn, 3, dest, src, size);
12232         }
12233       return NULL_TREE;
12234     }
12235
12236   /* If __builtin_strncat_chk is used, assume strncat is available.  */
12237   fn = built_in_decls[BUILT_IN_STRNCAT];
12238   if (!fn)
12239     return NULL_TREE;
12240
12241   return build_call_expr (fn, 3, dest, src, len);
12242 }
12243
12244 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
12245    a normal call should be emitted rather than expanding the function
12246    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
12247
12248 static tree
12249 fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
12250 {
12251   tree dest, size, len, fn, fmt, flag;
12252   const char *fmt_str;
12253   int nargs = call_expr_nargs (exp);
12254
12255   /* Verify the required arguments in the original call.  */
12256   if (nargs < 4)
12257     return NULL_TREE;
12258   dest = CALL_EXPR_ARG (exp, 0);
12259   if (!validate_arg (dest, POINTER_TYPE))
12260     return NULL_TREE;
12261   flag = CALL_EXPR_ARG (exp, 1);
12262   if (!validate_arg (flag, INTEGER_TYPE))
12263     return NULL_TREE;
12264   size = CALL_EXPR_ARG (exp, 2);
12265   if (!validate_arg (size, INTEGER_TYPE))
12266     return NULL_TREE;
12267   fmt = CALL_EXPR_ARG (exp, 3);
12268   if (!validate_arg (fmt, POINTER_TYPE))
12269     return NULL_TREE;
12270
12271   if (! host_integerp (size, 1))
12272     return NULL_TREE;
12273
12274   len = NULL_TREE;
12275
12276   if (!init_target_chars ())
12277     return NULL_TREE;
12278
12279   /* Check whether the format is a literal string constant.  */
12280   fmt_str = c_getstr (fmt);
12281   if (fmt_str != NULL)
12282     {
12283       /* If the format doesn't contain % args or %%, we know the size.  */
12284       if (strchr (fmt_str, target_percent) == 0)
12285         {
12286           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
12287             len = build_int_cstu (size_type_node, strlen (fmt_str));
12288         }
12289       /* If the format is "%s" and first ... argument is a string literal,
12290          we know the size too.  */
12291       else if (fcode == BUILT_IN_SPRINTF_CHK
12292                && strcmp (fmt_str, target_percent_s) == 0)
12293         {
12294           tree arg;
12295
12296           if (nargs == 5)
12297             {
12298               arg = CALL_EXPR_ARG (exp, 4);
12299               if (validate_arg (arg, POINTER_TYPE))
12300                 {
12301                   len = c_strlen (arg, 1);
12302                   if (! len || ! host_integerp (len, 1))
12303                     len = NULL_TREE;
12304                 }
12305             }
12306         }
12307     }
12308
12309   if (! integer_all_onesp (size))
12310     {
12311       if (! len || ! tree_int_cst_lt (len, size))
12312         return NULL_TREE;
12313     }
12314
12315   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12316      or if format doesn't contain % chars or is "%s".  */
12317   if (! integer_zerop (flag))
12318     {
12319       if (fmt_str == NULL)
12320         return NULL_TREE;
12321       if (strchr (fmt_str, target_percent) != NULL
12322           && strcmp (fmt_str, target_percent_s))
12323         return NULL_TREE;
12324     }
12325
12326   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
12327   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12328                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12329   if (!fn)
12330     return NULL_TREE;
12331
12332   return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
12333 }
12334
12335 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
12336    a normal call should be emitted rather than expanding the function
12337    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
12338    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
12339    passed as second argument.  */
12340
12341 tree
12342 fold_builtin_snprintf_chk (tree exp, tree maxlen,
12343                            enum built_in_function fcode)
12344 {
12345   tree dest, size, len, fn, fmt, flag;
12346   const char *fmt_str;
12347
12348   /* Verify the required arguments in the original call.  */
12349   if (call_expr_nargs (exp) < 5)
12350     return NULL_TREE;
12351   dest = CALL_EXPR_ARG (exp, 0);
12352   if (!validate_arg (dest, POINTER_TYPE))
12353     return NULL_TREE;
12354   len = CALL_EXPR_ARG (exp, 1);
12355   if (!validate_arg (len, INTEGER_TYPE))
12356     return NULL_TREE;
12357   flag = CALL_EXPR_ARG (exp, 2);
12358   if (!validate_arg (flag, INTEGER_TYPE))
12359     return NULL_TREE;
12360   size = CALL_EXPR_ARG (exp, 3);
12361   if (!validate_arg (size, INTEGER_TYPE))
12362     return NULL_TREE;
12363   fmt = CALL_EXPR_ARG (exp, 4);
12364   if (!validate_arg (fmt, POINTER_TYPE))
12365     return NULL_TREE;
12366
12367   if (! host_integerp (size, 1))
12368     return NULL_TREE;
12369
12370   if (! integer_all_onesp (size))
12371     {
12372       if (! host_integerp (len, 1))
12373         {
12374           /* If LEN is not constant, try MAXLEN too.
12375              For MAXLEN only allow optimizing into non-_ocs function
12376              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12377           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12378             return NULL_TREE;
12379         }
12380       else
12381         maxlen = len;
12382
12383       if (tree_int_cst_lt (size, maxlen))
12384         return NULL_TREE;
12385     }
12386
12387   if (!init_target_chars ())
12388     return NULL_TREE;
12389
12390   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12391      or if format doesn't contain % chars or is "%s".  */
12392   if (! integer_zerop (flag))
12393     {
12394       fmt_str = c_getstr (fmt);
12395       if (fmt_str == NULL)
12396         return NULL_TREE;
12397       if (strchr (fmt_str, target_percent) != NULL
12398           && strcmp (fmt_str, target_percent_s))
12399         return NULL_TREE;
12400     }
12401
12402   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12403      available.  */
12404   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12405                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12406   if (!fn)
12407     return NULL_TREE;
12408
12409   return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
12410 }
12411
12412 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
12413    FMT and ARG are the arguments to the call; we don't fold cases with
12414    more than 2 arguments, and ARG may be null if this is a 1-argument case.
12415
12416    Return NULL_TREE if no simplification was possible, otherwise return the
12417    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12418    code of the function to be simplified.  */
12419
12420 static tree
12421 fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
12422                      enum built_in_function fcode)
12423 {
12424   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
12425   const char *fmt_str = NULL;
12426
12427   /* If the return value is used, don't do the transformation.  */
12428   if (! ignore)
12429     return NULL_TREE;
12430
12431   /* Verify the required arguments in the original call.  */
12432   if (!validate_arg (fmt, POINTER_TYPE))
12433     return NULL_TREE;
12434
12435   /* Check whether the format is a literal string constant.  */
12436   fmt_str = c_getstr (fmt);
12437   if (fmt_str == NULL)
12438     return NULL_TREE;
12439
12440   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12441     {
12442       /* If we're using an unlocked function, assume the other
12443          unlocked functions exist explicitly.  */
12444       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12445       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
12446     }
12447   else
12448     {
12449       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12450       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12451     }
12452
12453   if (!init_target_chars ())
12454     return NULL_TREE;
12455
12456   if (strcmp (fmt_str, target_percent_s) == 0
12457       || strchr (fmt_str, target_percent) == NULL)
12458     {
12459       const char *str;
12460
12461       if (strcmp (fmt_str, target_percent_s) == 0)
12462         {
12463           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12464             return NULL_TREE;
12465
12466           if (!arg || !validate_arg (arg, POINTER_TYPE))
12467             return NULL_TREE;
12468
12469           str = c_getstr (arg);
12470           if (str == NULL)
12471             return NULL_TREE;
12472         }
12473       else
12474         {
12475           /* The format specifier doesn't contain any '%' characters.  */
12476           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
12477               && arg)
12478             return NULL_TREE;
12479           str = fmt_str;
12480         }
12481
12482       /* If the string was "", printf does nothing.  */
12483       if (str[0] == '\0')
12484         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12485
12486       /* If the string has length of 1, call putchar.  */
12487       if (str[1] == '\0')
12488         {
12489           /* Given printf("c"), (where c is any one character,)
12490              convert "c"[0] to an int and pass that to the replacement
12491              function.  */
12492           newarg = build_int_cst (NULL_TREE, str[0]);
12493           if (fn_putchar)
12494             call = build_call_expr (fn_putchar, 1, newarg);
12495         }
12496       else
12497         {
12498           /* If the string was "string\n", call puts("string").  */
12499           size_t len = strlen (str);
12500           if ((unsigned char)str[len - 1] == target_newline)
12501             {
12502               /* Create a NUL-terminated string that's one char shorter
12503                  than the original, stripping off the trailing '\n'.  */
12504               char *newstr = XALLOCAVEC (char, len);
12505               memcpy (newstr, str, len - 1);
12506               newstr[len - 1] = 0;
12507
12508               newarg = build_string_literal (len, newstr);
12509               if (fn_puts)
12510                 call = build_call_expr (fn_puts, 1, newarg);
12511             }
12512           else
12513             /* We'd like to arrange to call fputs(string,stdout) here,
12514                but we need stdout and don't have a way to get it yet.  */
12515             return NULL_TREE;
12516         }
12517     }
12518
12519   /* The other optimizations can be done only on the non-va_list variants.  */
12520   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12521     return NULL_TREE;
12522
12523   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
12524   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
12525     {
12526       if (!arg || !validate_arg (arg, POINTER_TYPE))
12527         return NULL_TREE;
12528       if (fn_puts)
12529         call = build_call_expr (fn_puts, 1, arg);
12530     }
12531
12532   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
12533   else if (strcmp (fmt_str, target_percent_c) == 0)
12534     {
12535       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12536         return NULL_TREE;
12537       if (fn_putchar)
12538         call = build_call_expr (fn_putchar, 1, arg);
12539     }
12540
12541   if (!call)
12542     return NULL_TREE;
12543
12544   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12545 }
12546
12547 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
12548    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
12549    more than 3 arguments, and ARG may be null in the 2-argument case.
12550
12551    Return NULL_TREE if no simplification was possible, otherwise return the
12552    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12553    code of the function to be simplified.  */
12554
12555 static tree
12556 fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
12557                       enum built_in_function fcode)
12558 {
12559   tree fn_fputc, fn_fputs, call = NULL_TREE;
12560   const char *fmt_str = NULL;
12561
12562   /* If the return value is used, don't do the transformation.  */
12563   if (! ignore)
12564     return NULL_TREE;
12565
12566   /* Verify the required arguments in the original call.  */
12567   if (!validate_arg (fp, POINTER_TYPE))
12568     return NULL_TREE;
12569   if (!validate_arg (fmt, POINTER_TYPE))
12570     return NULL_TREE;
12571
12572   /* Check whether the format is a literal string constant.  */
12573   fmt_str = c_getstr (fmt);
12574   if (fmt_str == NULL)
12575     return NULL_TREE;
12576
12577   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12578     {
12579       /* If we're using an unlocked function, assume the other
12580          unlocked functions exist explicitly.  */
12581       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12582       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
12583     }
12584   else
12585     {
12586       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12587       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12588     }
12589
12590   if (!init_target_chars ())
12591     return NULL_TREE;
12592
12593   /* If the format doesn't contain % args or %%, use strcpy.  */
12594   if (strchr (fmt_str, target_percent) == NULL)
12595     {
12596       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
12597           && arg)
12598         return NULL_TREE;
12599
12600       /* If the format specifier was "", fprintf does nothing.  */
12601       if (fmt_str[0] == '\0')
12602         {
12603           /* If FP has side-effects, just wait until gimplification is
12604              done.  */
12605           if (TREE_SIDE_EFFECTS (fp))
12606             return NULL_TREE;
12607
12608           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12609         }
12610
12611       /* When "string" doesn't contain %, replace all cases of
12612          fprintf (fp, string) with fputs (string, fp).  The fputs
12613          builtin will take care of special cases like length == 1.  */
12614       if (fn_fputs)
12615         call = build_call_expr (fn_fputs, 2, fmt, fp);
12616     }
12617
12618   /* The other optimizations can be done only on the non-va_list variants.  */
12619   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
12620     return NULL_TREE;
12621
12622   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
12623   else if (strcmp (fmt_str, target_percent_s) == 0)
12624     {
12625       if (!arg || !validate_arg (arg, POINTER_TYPE))
12626         return NULL_TREE;
12627       if (fn_fputs)
12628         call = build_call_expr (fn_fputs, 2, arg, fp);
12629     }
12630
12631   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
12632   else if (strcmp (fmt_str, target_percent_c) == 0)
12633     {
12634       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12635         return NULL_TREE;
12636       if (fn_fputc)
12637         call = build_call_expr (fn_fputc, 2, arg, fp);
12638     }
12639
12640   if (!call)
12641     return NULL_TREE;
12642   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12643 }
12644
12645 /* Initialize format string characters in the target charset.  */
12646
12647 static bool
12648 init_target_chars (void)
12649 {
12650   static bool init;
12651   if (!init)
12652     {
12653       target_newline = lang_hooks.to_target_charset ('\n');
12654       target_percent = lang_hooks.to_target_charset ('%');
12655       target_c = lang_hooks.to_target_charset ('c');
12656       target_s = lang_hooks.to_target_charset ('s');
12657       if (target_newline == 0 || target_percent == 0 || target_c == 0
12658           || target_s == 0)
12659         return false;
12660
12661       target_percent_c[0] = target_percent;
12662       target_percent_c[1] = target_c;
12663       target_percent_c[2] = '\0';
12664
12665       target_percent_s[0] = target_percent;
12666       target_percent_s[1] = target_s;
12667       target_percent_s[2] = '\0';
12668
12669       target_percent_s_newline[0] = target_percent;
12670       target_percent_s_newline[1] = target_s;
12671       target_percent_s_newline[2] = target_newline;
12672       target_percent_s_newline[3] = '\0';
12673
12674       init = true;
12675     }
12676   return true;
12677 }
12678
12679 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
12680    and no overflow/underflow occurred.  INEXACT is true if M was not
12681    exactly calculated.  TYPE is the tree type for the result.  This
12682    function assumes that you cleared the MPFR flags and then
12683    calculated M to see if anything subsequently set a flag prior to
12684    entering this function.  Return NULL_TREE if any checks fail.  */
12685
12686 static tree
12687 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
12688 {
12689   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
12690      overflow/underflow occurred.  If -frounding-math, proceed iff the
12691      result of calling FUNC was exact.  */
12692   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
12693       && (!flag_rounding_math || !inexact))
12694     {
12695       REAL_VALUE_TYPE rr;
12696
12697       real_from_mpfr (&rr, m, type, GMP_RNDN);
12698       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
12699          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
12700          but the mpft_t is not, then we underflowed in the
12701          conversion.  */
12702       if (real_isfinite (&rr)
12703           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
12704         {
12705           REAL_VALUE_TYPE rmode;
12706
12707           real_convert (&rmode, TYPE_MODE (type), &rr);
12708           /* Proceed iff the specified mode can hold the value.  */
12709           if (real_identical (&rmode, &rr))
12710             return build_real (type, rmode);
12711         }
12712     }
12713   return NULL_TREE;
12714 }
12715
12716 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
12717    FUNC on it and return the resulting value as a tree with type TYPE.
12718    If MIN and/or MAX are not NULL, then the supplied ARG must be
12719    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
12720    acceptable values, otherwise they are not.  The mpfr precision is
12721    set to the precision of TYPE.  We assume that function FUNC returns
12722    zero if the result could be calculated exactly within the requested
12723    precision.  */
12724
12725 static tree
12726 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
12727               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
12728               bool inclusive)
12729 {
12730   tree result = NULL_TREE;
12731   
12732   STRIP_NOPS (arg);
12733
12734   /* To proceed, MPFR must exactly represent the target floating point
12735      format, which only happens when the target base equals two.  */
12736   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12737       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
12738     {
12739       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
12740
12741       if (real_isfinite (ra)
12742           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
12743           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
12744         {
12745           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12746           int inexact;
12747           mpfr_t m;
12748
12749           mpfr_init2 (m, prec);
12750           mpfr_from_real (m, ra, GMP_RNDN);
12751           mpfr_clear_flags ();
12752           inexact = func (m, m, GMP_RNDN);
12753           result = do_mpfr_ckconv (m, type, inexact);
12754           mpfr_clear (m);
12755         }
12756     }
12757   
12758   return result;
12759 }
12760
12761 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
12762    FUNC on it and return the resulting value as a tree with type TYPE.
12763    The mpfr precision is set to the precision of TYPE.  We assume that
12764    function FUNC returns zero if the result could be calculated
12765    exactly within the requested precision.  */
12766
12767 static tree
12768 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
12769               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12770 {
12771   tree result = NULL_TREE;
12772   
12773   STRIP_NOPS (arg1);
12774   STRIP_NOPS (arg2);
12775
12776   /* To proceed, MPFR must exactly represent the target floating point
12777      format, which only happens when the target base equals two.  */
12778   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12779       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12780       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
12781     {
12782       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12783       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12784
12785       if (real_isfinite (ra1) && real_isfinite (ra2))
12786         {
12787           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12788           int inexact;
12789           mpfr_t m1, m2;
12790
12791           mpfr_inits2 (prec, m1, m2, NULL);
12792           mpfr_from_real (m1, ra1, GMP_RNDN);
12793           mpfr_from_real (m2, ra2, GMP_RNDN);
12794           mpfr_clear_flags ();
12795           inexact = func (m1, m1, m2, GMP_RNDN);
12796           result = do_mpfr_ckconv (m1, type, inexact);
12797           mpfr_clears (m1, m2, NULL);
12798         }
12799     }
12800   
12801   return result;
12802 }
12803
12804 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
12805    FUNC on it and return the resulting value as a tree with type TYPE.
12806    The mpfr precision is set to the precision of TYPE.  We assume that
12807    function FUNC returns zero if the result could be calculated
12808    exactly within the requested precision.  */
12809
12810 static tree
12811 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
12812               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
12813 {
12814   tree result = NULL_TREE;
12815   
12816   STRIP_NOPS (arg1);
12817   STRIP_NOPS (arg2);
12818   STRIP_NOPS (arg3);
12819
12820   /* To proceed, MPFR must exactly represent the target floating point
12821      format, which only happens when the target base equals two.  */
12822   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12823       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
12824       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
12825       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
12826     {
12827       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
12828       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
12829       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
12830
12831       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
12832         {
12833           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12834           int inexact;
12835           mpfr_t m1, m2, m3;
12836
12837           mpfr_inits2 (prec, m1, m2, m3, NULL);
12838           mpfr_from_real (m1, ra1, GMP_RNDN);
12839           mpfr_from_real (m2, ra2, GMP_RNDN);
12840           mpfr_from_real (m3, ra3, GMP_RNDN);
12841           mpfr_clear_flags ();
12842           inexact = func (m1, m1, m2, m3, GMP_RNDN);
12843           result = do_mpfr_ckconv (m1, type, inexact);
12844           mpfr_clears (m1, m2, m3, NULL);
12845         }
12846     }
12847   
12848   return result;
12849 }
12850
12851 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
12852    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
12853    If ARG_SINP and ARG_COSP are NULL then the result is returned
12854    as a complex value.
12855    The type is taken from the type of ARG and is used for setting the
12856    precision of the calculation and results.  */
12857
12858 static tree
12859 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
12860 {
12861   tree const type = TREE_TYPE (arg);
12862   tree result = NULL_TREE;
12863   
12864   STRIP_NOPS (arg);
12865   
12866   /* To proceed, MPFR must exactly represent the target floating point
12867      format, which only happens when the target base equals two.  */
12868   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12869       && TREE_CODE (arg) == REAL_CST
12870       && !TREE_OVERFLOW (arg))
12871     {
12872       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
12873
12874       if (real_isfinite (ra))
12875         {
12876           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12877           tree result_s, result_c;
12878           int inexact;
12879           mpfr_t m, ms, mc;
12880
12881           mpfr_inits2 (prec, m, ms, mc, NULL);
12882           mpfr_from_real (m, ra, GMP_RNDN);
12883           mpfr_clear_flags ();
12884           inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
12885           result_s = do_mpfr_ckconv (ms, type, inexact);
12886           result_c = do_mpfr_ckconv (mc, type, inexact);
12887           mpfr_clears (m, ms, mc, NULL);
12888           if (result_s && result_c)
12889             {
12890               /* If we are to return in a complex value do so.  */
12891               if (!arg_sinp && !arg_cosp)
12892                 return build_complex (build_complex_type (type),
12893                                       result_c, result_s);
12894
12895               /* Dereference the sin/cos pointer arguments.  */
12896               arg_sinp = build_fold_indirect_ref (arg_sinp);
12897               arg_cosp = build_fold_indirect_ref (arg_cosp);
12898               /* Proceed if valid pointer type were passed in.  */
12899               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
12900                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
12901                 {
12902                   /* Set the values. */
12903                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
12904                                           result_s);
12905                   TREE_SIDE_EFFECTS (result_s) = 1;
12906                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
12907                                           result_c);
12908                   TREE_SIDE_EFFECTS (result_c) = 1;
12909                   /* Combine the assignments into a compound expr.  */
12910                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
12911                                                     result_s, result_c));
12912                 }
12913             }
12914         }
12915     }
12916   return result;
12917 }
12918
12919 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,3,0)
12920 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
12921    two-argument mpfr order N Bessel function FUNC on them and return
12922    the resulting value as a tree with type TYPE.  The mpfr precision
12923    is set to the precision of TYPE.  We assume that function FUNC
12924    returns zero if the result could be calculated exactly within the
12925    requested precision.  */
12926 static tree
12927 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
12928                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
12929                   const REAL_VALUE_TYPE *min, bool inclusive)
12930 {
12931   tree result = NULL_TREE;
12932
12933   STRIP_NOPS (arg1);
12934   STRIP_NOPS (arg2);
12935
12936   /* To proceed, MPFR must exactly represent the target floating point
12937      format, which only happens when the target base equals two.  */
12938   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12939       && host_integerp (arg1, 0)
12940       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
12941     {
12942       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
12943       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
12944
12945       if (n == (long)n
12946           && real_isfinite (ra)
12947           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
12948         {
12949           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12950           int inexact;
12951           mpfr_t m;
12952
12953           mpfr_init2 (m, prec);
12954           mpfr_from_real (m, ra, GMP_RNDN);
12955           mpfr_clear_flags ();
12956           inexact = func (m, n, m, GMP_RNDN);
12957           result = do_mpfr_ckconv (m, type, inexact);
12958           mpfr_clear (m);
12959         }
12960     }
12961   
12962   return result;
12963 }
12964
12965 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
12966    the pointer *(ARG_QUO) and return the result.  The type is taken
12967    from the type of ARG0 and is used for setting the precision of the
12968    calculation and results.  */
12969
12970 static tree
12971 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
12972 {
12973   tree const type = TREE_TYPE (arg0);
12974   tree result = NULL_TREE;
12975   
12976   STRIP_NOPS (arg0);
12977   STRIP_NOPS (arg1);
12978   
12979   /* To proceed, MPFR must exactly represent the target floating point
12980      format, which only happens when the target base equals two.  */
12981   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
12982       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
12983       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
12984     {
12985       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
12986       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
12987
12988       if (real_isfinite (ra0) && real_isfinite (ra1))
12989         {
12990           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
12991           tree result_rem;
12992           long integer_quo;
12993           mpfr_t m0, m1;
12994
12995           mpfr_inits2 (prec, m0, m1, NULL);
12996           mpfr_from_real (m0, ra0, GMP_RNDN);
12997           mpfr_from_real (m1, ra1, GMP_RNDN);
12998           mpfr_clear_flags ();
12999           mpfr_remquo (m0, &integer_quo, m0, m1, GMP_RNDN);
13000           /* Remquo is independent of the rounding mode, so pass
13001              inexact=0 to do_mpfr_ckconv().  */
13002           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13003           mpfr_clears (m0, m1, NULL);
13004           if (result_rem)
13005             {
13006               /* MPFR calculates quo in the host's long so it may
13007                  return more bits in quo than the target int can hold
13008                  if sizeof(host long) > sizeof(target int).  This can
13009                  happen even for native compilers in LP64 mode.  In
13010                  these cases, modulo the quo value with the largest
13011                  number that the target int can hold while leaving one
13012                  bit for the sign.  */
13013               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13014                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13015
13016               /* Dereference the quo pointer argument.  */
13017               arg_quo = build_fold_indirect_ref (arg_quo);
13018               /* Proceed iff a valid pointer type was passed in.  */
13019               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13020                 {
13021                   /* Set the value. */
13022                   tree result_quo = fold_build2 (MODIFY_EXPR,
13023                                                  TREE_TYPE (arg_quo), arg_quo,
13024                                                  build_int_cst (NULL, integer_quo));
13025                   TREE_SIDE_EFFECTS (result_quo) = 1;
13026                   /* Combine the quo assignment with the rem.  */
13027                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13028                                                     result_quo, result_rem));
13029                 }
13030             }
13031         }
13032     }
13033   return result;
13034 }
13035
13036 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13037    resulting value as a tree with type TYPE.  The mpfr precision is
13038    set to the precision of TYPE.  We assume that this mpfr function
13039    returns zero if the result could be calculated exactly within the
13040    requested precision.  In addition, the integer pointer represented
13041    by ARG_SG will be dereferenced and set to the appropriate signgam
13042    (-1,1) value.  */
13043
13044 static tree
13045 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13046 {
13047   tree result = NULL_TREE;
13048
13049   STRIP_NOPS (arg);
13050   
13051   /* To proceed, MPFR must exactly represent the target floating point
13052      format, which only happens when the target base equals two.  Also
13053      verify ARG is a constant and that ARG_SG is an int pointer.  */
13054   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13055       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13056       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13057       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13058     {
13059       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13060
13061       /* In addition to NaN and Inf, the argument cannot be zero or a
13062          negative integer.  */
13063       if (real_isfinite (ra)
13064           && ra->cl != rvc_zero
13065           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13066         {
13067           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
13068           int inexact, sg;
13069           mpfr_t m;
13070           tree result_lg;
13071
13072           mpfr_init2 (m, prec);
13073           mpfr_from_real (m, ra, GMP_RNDN);
13074           mpfr_clear_flags ();
13075           inexact = mpfr_lgamma (m, &sg, m, GMP_RNDN);
13076           result_lg = do_mpfr_ckconv (m, type, inexact);
13077           mpfr_clear (m);
13078           if (result_lg)
13079             {
13080               tree result_sg;
13081
13082               /* Dereference the arg_sg pointer argument.  */
13083               arg_sg = build_fold_indirect_ref (arg_sg);
13084               /* Assign the signgam value into *arg_sg. */
13085               result_sg = fold_build2 (MODIFY_EXPR,
13086                                        TREE_TYPE (arg_sg), arg_sg,
13087                                        build_int_cst (NULL, sg));
13088               TREE_SIDE_EFFECTS (result_sg) = 1;
13089               /* Combine the signgam assignment with the lgamma result.  */
13090               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13091                                                 result_sg, result_lg));
13092             }
13093         }
13094     }
13095
13096   return result;
13097 }
13098 #endif