OSDN Git Service

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