OSDN Git Service

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