OSDN Git Service

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