OSDN Git Service

Merge branch 'master' of git://github.com/monaka/binutils
[pf3gnuchains/pf3gnuchains3x.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4    Free Software Foundation, Inc.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "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 SLOW_UNALIGNED_ACCESS
55 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56 #endif
57
58 #ifndef PAD_VARARGS_DOWN
59 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60 #endif
61
62 /* Define the names of the builtin function types and codes.  */
63 const char *const built_in_class_names[4]
64   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
65
66 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
67 const char * built_in_names[(int) END_BUILTINS] =
68 {
69 #include "builtins.def"
70 };
71 #undef DEF_BUILTIN
72
73 /* Setup an array of _DECL trees, make sure each element is
74    initialized to NULL_TREE.  */
75 tree built_in_decls[(int) END_BUILTINS];
76 /* Declarations used when constructing the builtin implicitly in the compiler.
77    It may be NULL_TREE when this is invalid (for instance runtime is not
78    required to implement the function call in all cases).  */
79 tree implicit_built_in_decls[(int) END_BUILTINS];
80
81 static const char *c_getstr (tree);
82 static rtx c_readstr (const char *, enum machine_mode);
83 static int target_char_cast (tree, char *);
84 static rtx get_memory_rtx (tree, tree);
85 static int apply_args_size (void);
86 static int apply_result_size (void);
87 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
88 static rtx result_vector (int, rtx);
89 #endif
90 static void expand_builtin_update_setjmp_buf (rtx);
91 static void expand_builtin_prefetch (tree);
92 static rtx expand_builtin_apply_args (void);
93 static rtx expand_builtin_apply_args_1 (void);
94 static rtx expand_builtin_apply (rtx, rtx, rtx);
95 static void expand_builtin_return (rtx);
96 static enum type_class type_to_class (tree);
97 static rtx expand_builtin_classify_type (tree);
98 static void expand_errno_check (tree, rtx);
99 static rtx expand_builtin_mathfn (tree, rtx, rtx);
100 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
101 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
102 static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
103 static rtx expand_builtin_sincos (tree);
104 static rtx expand_builtin_cexpi (tree, rtx, rtx);
105 static rtx expand_builtin_int_roundingfn (tree, rtx);
106 static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
107 static rtx expand_builtin_args_info (tree);
108 static rtx expand_builtin_next_arg (void);
109 static rtx expand_builtin_va_start (tree);
110 static rtx expand_builtin_va_end (tree);
111 static rtx expand_builtin_va_copy (tree);
112 static rtx expand_builtin_memchr (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
114 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
115 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
116 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
117 static rtx expand_builtin_strcat (tree, tree, rtx, enum machine_mode);
118 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
120 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
121 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
123 static rtx expand_builtin_mempcpy_args (tree, tree, tree, tree, rtx, 
124                                         enum machine_mode, int);
125 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode, int);
126 static rtx expand_builtin_memmove_args (tree, tree, tree, tree, rtx, 
127                                         enum machine_mode, int);
128 static rtx expand_builtin_bcopy (tree, int);
129 static rtx expand_builtin_strcpy (tree, tree, rtx, enum machine_mode);
130 static rtx expand_builtin_strcpy_args (tree, tree, tree, rtx, enum machine_mode);
131 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
132 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
133 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
134 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
136 static rtx expand_builtin_bzero (tree);
137 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
138 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
139 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
140 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
141 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
142 static rtx expand_builtin_alloca (tree, rtx);
143 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
144 static rtx expand_builtin_frame_address (tree, tree);
145 static rtx expand_builtin_fputs (tree, rtx, bool);
146 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
147 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
148 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
149 static tree stabilize_va_list (tree, int);
150 static rtx expand_builtin_expect (tree, rtx);
151 static tree fold_builtin_constant_p (tree);
152 static tree fold_builtin_expect (tree, tree);
153 static tree fold_builtin_classify_type (tree);
154 static tree fold_builtin_strlen (tree);
155 static tree fold_builtin_inf (tree, int);
156 static tree fold_builtin_nan (tree, tree, int);
157 static tree rewrite_call_expr (tree, int, tree, int, ...);
158 static bool validate_arg (const_tree, enum tree_code code);
159 static bool integer_valued_real_p (tree);
160 static tree fold_trunc_transparent_mathfn (tree, tree);
161 static bool readonly_data_expr (tree);
162 static rtx expand_builtin_fabs (tree, rtx, rtx);
163 static rtx expand_builtin_signbit (tree, rtx);
164 static tree fold_builtin_sqrt (tree, tree);
165 static tree fold_builtin_cbrt (tree, tree);
166 static tree fold_builtin_pow (tree, tree, tree, tree);
167 static tree fold_builtin_powi (tree, tree, tree, tree);
168 static tree fold_builtin_cos (tree, tree, tree);
169 static tree fold_builtin_cosh (tree, tree, tree);
170 static tree fold_builtin_tan (tree, tree);
171 static tree fold_builtin_trunc (tree, tree);
172 static tree fold_builtin_floor (tree, tree);
173 static tree fold_builtin_ceil (tree, tree);
174 static tree fold_builtin_round (tree, tree);
175 static tree fold_builtin_int_roundingfn (tree, tree);
176 static tree fold_builtin_bitop (tree, tree);
177 static tree fold_builtin_memory_op (tree, tree, tree, tree, bool, int);
178 static tree fold_builtin_strchr (tree, tree, tree);
179 static tree fold_builtin_memchr (tree, tree, tree, tree);
180 static tree fold_builtin_memcmp (tree, tree, tree);
181 static tree fold_builtin_strcmp (tree, tree);
182 static tree fold_builtin_strncmp (tree, tree, tree);
183 static tree fold_builtin_signbit (tree, tree);
184 static tree fold_builtin_copysign (tree, tree, tree, tree);
185 static tree fold_builtin_isascii (tree);
186 static tree fold_builtin_toascii (tree);
187 static tree fold_builtin_isdigit (tree);
188 static tree fold_builtin_fabs (tree, tree);
189 static tree fold_builtin_abs (tree, tree);
190 static tree fold_builtin_unordered_cmp (tree, tree, tree, enum tree_code,
191                                         enum tree_code);
192 static tree fold_builtin_n (tree, tree *, int, bool);
193 static tree fold_builtin_0 (tree, bool);
194 static tree fold_builtin_1 (tree, tree, bool);
195 static tree fold_builtin_2 (tree, tree, tree, bool);
196 static tree fold_builtin_3 (tree, tree, tree, tree, bool);
197 static tree fold_builtin_4 (tree, tree, tree, tree, tree, bool);
198 static tree fold_builtin_varargs (tree, tree, bool);
199
200 static tree fold_builtin_strpbrk (tree, tree, tree);
201 static tree fold_builtin_strstr (tree, tree, tree);
202 static tree fold_builtin_strrchr (tree, tree, tree);
203 static tree fold_builtin_strcat (tree, tree);
204 static tree fold_builtin_strncat (tree, tree, tree);
205 static tree fold_builtin_strspn (tree, tree);
206 static tree fold_builtin_strcspn (tree, tree);
207 static tree fold_builtin_sprintf (tree, tree, tree, int);
208
209 static rtx expand_builtin_object_size (tree);
210 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
211                                       enum built_in_function);
212 static void maybe_emit_chk_warning (tree, enum built_in_function);
213 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
214 static void maybe_emit_free_warning (tree);
215 static tree fold_builtin_object_size (tree, tree);
216 static tree fold_builtin_strcat_chk (tree, tree, tree, tree);
217 static tree fold_builtin_strncat_chk (tree, tree, tree, tree, tree);
218 static tree fold_builtin_sprintf_chk (tree, enum built_in_function);
219 static tree fold_builtin_printf (tree, tree, tree, bool, enum built_in_function);
220 static tree fold_builtin_fprintf (tree, tree, tree, tree, bool,
221                                   enum built_in_function);
222 static bool init_target_chars (void);
223
224 static unsigned HOST_WIDE_INT target_newline;
225 static unsigned HOST_WIDE_INT target_percent;
226 static unsigned HOST_WIDE_INT target_c;
227 static unsigned HOST_WIDE_INT target_s;
228 static char target_percent_c[3];
229 static char target_percent_s[3];
230 static char target_percent_s_newline[4];
231 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
232                           const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
233 static tree do_mpfr_arg2 (tree, tree, tree,
234                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
235 static tree do_mpfr_arg3 (tree, tree, tree, tree,
236                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
237 static tree do_mpfr_sincos (tree, tree, tree);
238 static tree do_mpfr_bessel_n (tree, tree, tree,
239                               int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
240                               const REAL_VALUE_TYPE *, bool);
241 static tree do_mpfr_remquo (tree, tree, tree);
242 static tree do_mpfr_lgamma_r (tree, tree, tree);
243
244 /* Return true if NODE should be considered for inline expansion regardless
245    of the optimization level.  This means whenever a function is invoked with
246    its "internal" name, which normally contains the prefix "__builtin".  */
247
248 static bool called_as_built_in (tree node)
249 {
250   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
251   if (strncmp (name, "__builtin_", 10) == 0)
252     return true;
253   if (strncmp (name, "__sync_", 7) == 0)
254     return true;
255   return false;
256 }
257
258 /* Return the alignment in bits of EXP, an object.
259    Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
260    guessed alignment e.g. from type alignment.  */
261
262 int
263 get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
264 {
265   unsigned int inner;
266
267   inner = max_align;
268   if (handled_component_p (exp))
269    {
270       HOST_WIDE_INT bitsize, bitpos;
271       tree offset;
272       enum machine_mode mode; 
273       int unsignedp, volatilep;
274
275       exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
276                                  &mode, &unsignedp, &volatilep, true);
277       if (bitpos)
278         inner = MIN (inner, (unsigned) (bitpos & -bitpos));
279       while (offset)
280         {
281           tree next_offset;
282
283           if (TREE_CODE (offset) == PLUS_EXPR)
284             {
285               next_offset = TREE_OPERAND (offset, 0);
286               offset = TREE_OPERAND (offset, 1);
287             }
288           else
289             next_offset = NULL;
290           if (host_integerp (offset, 1))
291             {
292               /* Any overflow in calculating offset_bits won't change
293                  the alignment.  */
294               unsigned offset_bits
295                 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
296
297               if (offset_bits)
298                 inner = MIN (inner, (offset_bits & -offset_bits));
299             }
300           else if (TREE_CODE (offset) == MULT_EXPR
301                    && host_integerp (TREE_OPERAND (offset, 1), 1))
302             {
303               /* Any overflow in calculating offset_factor won't change
304                  the alignment.  */
305               unsigned offset_factor
306                 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
307                    * BITS_PER_UNIT);
308
309               if (offset_factor)
310                 inner = MIN (inner, (offset_factor & -offset_factor));
311             }
312           else
313             {
314               inner = MIN (inner, BITS_PER_UNIT);
315               break;
316             }
317           offset = next_offset;
318         }
319     }
320   if (DECL_P (exp))
321     align = MIN (inner, DECL_ALIGN (exp));
322 #ifdef CONSTANT_ALIGNMENT
323   else if (CONSTANT_CLASS_P (exp))
324     align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
325 #endif
326   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
327            || TREE_CODE (exp) == INDIRECT_REF)
328     align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
329   else
330     align = MIN (align, inner);
331   return MIN (align, max_align);
332 }
333
334 /* Return the alignment in bits of EXP, a pointer valued expression.
335    But don't return more than MAX_ALIGN no matter what.
336    The alignment returned is, by default, the alignment of the thing that
337    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
338
339    Otherwise, look at the expression to see if we can do better, i.e., if the
340    expression is actually pointing at an object whose alignment is tighter.  */
341
342 int
343 get_pointer_alignment (tree exp, unsigned int max_align)
344 {
345   unsigned int align, inner;
346
347   /* We rely on TER to compute accurate alignment information.  */
348   if (!(optimize && flag_tree_ter))
349     return 0;
350
351   if (!POINTER_TYPE_P (TREE_TYPE (exp)))
352     return 0;
353
354   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
355   align = MIN (align, max_align);
356
357   while (1)
358     {
359       switch (TREE_CODE (exp))
360         {
361         CASE_CONVERT:
362           exp = TREE_OPERAND (exp, 0);
363           if (! POINTER_TYPE_P (TREE_TYPE (exp)))
364             return align;
365
366           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
367           align = MIN (inner, max_align);
368           break;
369
370         case POINTER_PLUS_EXPR:
371           /* If sum of pointer + int, restrict our maximum alignment to that
372              imposed by the integer.  If not, we can't do any better than
373              ALIGN.  */
374           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
375             return align;
376
377           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
378                   & (max_align / BITS_PER_UNIT - 1))
379                  != 0)
380             max_align >>= 1;
381
382           exp = TREE_OPERAND (exp, 0);
383           break;
384
385         case ADDR_EXPR:
386           /* See what we are pointing at and look at its alignment.  */
387           return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
388
389         default:
390           return align;
391         }
392     }
393 }
394
395 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
396    way, because it could contain a zero byte in the middle.
397    TREE_STRING_LENGTH is the size of the character array, not the string.
398
399    ONLY_VALUE should be nonzero if the result is not going to be emitted
400    into the instruction stream and zero if it is going to be expanded.
401    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
402    is returned, otherwise NULL, since
403    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
404    evaluate the side-effects.
405
406    The value returned is of type `ssizetype'.
407
408    Unfortunately, string_constant can't access the values of const char
409    arrays with initializers, so neither can we do so here.  */
410
411 tree
412 c_strlen (tree src, int only_value)
413 {
414   tree offset_node;
415   HOST_WIDE_INT offset;
416   int max;
417   const char *ptr;
418
419   STRIP_NOPS (src);
420   if (TREE_CODE (src) == COND_EXPR
421       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
422     {
423       tree len1, len2;
424
425       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
426       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
427       if (tree_int_cst_equal (len1, len2))
428         return len1;
429     }
430
431   if (TREE_CODE (src) == COMPOUND_EXPR
432       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
433     return c_strlen (TREE_OPERAND (src, 1), only_value);
434
435   src = string_constant (src, &offset_node);
436   if (src == 0)
437     return NULL_TREE;
438
439   max = TREE_STRING_LENGTH (src) - 1;
440   ptr = TREE_STRING_POINTER (src);
441
442   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
443     {
444       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
445          compute the offset to the following null if we don't know where to
446          start searching for it.  */
447       int i;
448
449       for (i = 0; i < max; i++)
450         if (ptr[i] == 0)
451           return NULL_TREE;
452
453       /* We don't know the starting offset, but we do know that the string
454          has no internal zero bytes.  We can assume that the offset falls
455          within the bounds of the string; otherwise, the programmer deserves
456          what he gets.  Subtract the offset from the length of the string,
457          and return that.  This would perhaps not be valid if we were dealing
458          with named arrays in addition to literal string constants.  */
459
460       return size_diffop (size_int (max), offset_node);
461     }
462
463   /* We have a known offset into the string.  Start searching there for
464      a null character if we can represent it as a single HOST_WIDE_INT.  */
465   if (offset_node == 0)
466     offset = 0;
467   else if (! host_integerp (offset_node, 0))
468     offset = -1;
469   else
470     offset = tree_low_cst (offset_node, 0);
471
472   /* If the offset is known to be out of bounds, warn, and call strlen at
473      runtime.  */
474   if (offset < 0 || offset > max)
475     {
476      /* Suppress multiple warnings for propagated constant strings.  */
477       if (! TREE_NO_WARNING (src))
478         {
479           warning (0, "offset outside bounds of constant string");
480           TREE_NO_WARNING (src) = 1;
481         }
482       return NULL_TREE;
483     }
484
485   /* Use strlen to search for the first zero byte.  Since any strings
486      constructed with build_string will have nulls appended, we win even
487      if we get handed something like (char[4])"abcd".
488
489      Since OFFSET is our starting index into the string, no further
490      calculation is needed.  */
491   return ssize_int (strlen (ptr + offset));
492 }
493
494 /* Return a char pointer for a C string if it is a string constant
495    or sum of string constant and integer constant.  */
496
497 static const char *
498 c_getstr (tree src)
499 {
500   tree offset_node;
501
502   src = string_constant (src, &offset_node);
503   if (src == 0)
504     return 0;
505
506   if (offset_node == 0)
507     return TREE_STRING_POINTER (src);
508   else if (!host_integerp (offset_node, 1)
509            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
510     return 0;
511
512   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
513 }
514
515 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
516    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
517
518 static rtx
519 c_readstr (const char *str, enum machine_mode mode)
520 {
521   HOST_WIDE_INT c[2];
522   HOST_WIDE_INT ch;
523   unsigned int i, j;
524
525   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
526
527   c[0] = 0;
528   c[1] = 0;
529   ch = 1;
530   for (i = 0; i < GET_MODE_SIZE (mode); i++)
531     {
532       j = i;
533       if (WORDS_BIG_ENDIAN)
534         j = GET_MODE_SIZE (mode) - i - 1;
535       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
536           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
537         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
538       j *= BITS_PER_UNIT;
539       gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
540
541       if (ch)
542         ch = (unsigned char) str[i];
543       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
544     }
545   return immed_double_const (c[0], c[1], mode);
546 }
547
548 /* Cast a target constant CST to target CHAR and if that value fits into
549    host char type, return zero and put that value into variable pointed to by
550    P.  */
551
552 static int
553 target_char_cast (tree cst, char *p)
554 {
555   unsigned HOST_WIDE_INT val, hostval;
556
557   if (!host_integerp (cst, 1)
558       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
559     return 1;
560
561   val = tree_low_cst (cst, 1);
562   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
563     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
564
565   hostval = val;
566   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
567     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
568
569   if (val != hostval)
570     return 1;
571
572   *p = hostval;
573   return 0;
574 }
575
576 /* Similar to save_expr, but assumes that arbitrary code is not executed
577    in between the multiple evaluations.  In particular, we assume that a
578    non-addressable local variable will not be modified.  */
579
580 static tree
581 builtin_save_expr (tree exp)
582 {
583   if (TREE_ADDRESSABLE (exp) == 0
584       && (TREE_CODE (exp) == PARM_DECL
585           || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
586     return exp;
587
588   return save_expr (exp);
589 }
590
591 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
592    times to get the address of either a higher stack frame, or a return
593    address located within it (depending on FNDECL_CODE).  */
594
595 static rtx
596 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
597 {
598   int i;
599
600 #ifdef INITIAL_FRAME_ADDRESS_RTX
601   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
602 #else
603   rtx tem;
604
605   /* For a zero count with __builtin_return_address, we don't care what
606      frame address we return, because target-specific definitions will
607      override us.  Therefore frame pointer elimination is OK, and using
608      the soft frame pointer is OK.
609
610      For a nonzero count, or a zero count with __builtin_frame_address,
611      we require a stable offset from the current frame pointer to the
612      previous one, so we must use the hard frame pointer, and
613      we must disable frame pointer elimination.  */
614   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
615     tem = frame_pointer_rtx;
616   else
617     {
618       tem = hard_frame_pointer_rtx;
619
620       /* Tell reload not to eliminate the frame pointer.  */
621       crtl->accesses_prior_frames = 1;
622     }
623 #endif
624
625   /* Some machines need special handling before we can access
626      arbitrary frames.  For example, on the SPARC, we must first flush
627      all register windows to the stack.  */
628 #ifdef SETUP_FRAME_ADDRESSES
629   if (count > 0)
630     SETUP_FRAME_ADDRESSES ();
631 #endif
632
633   /* On the SPARC, the return address is not in the frame, it is in a
634      register.  There is no way to access it off of the current frame
635      pointer, but it can be accessed off the previous frame pointer by
636      reading the value from the register window save area.  */
637 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
638   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
639     count--;
640 #endif
641
642   /* Scan back COUNT frames to the specified frame.  */
643   for (i = 0; i < count; i++)
644     {
645       /* Assume the dynamic chain pointer is in the word that the
646          frame address points to, unless otherwise specified.  */
647 #ifdef DYNAMIC_CHAIN_ADDRESS
648       tem = DYNAMIC_CHAIN_ADDRESS (tem);
649 #endif
650       tem = memory_address (Pmode, tem);
651       tem = gen_frame_mem (Pmode, tem);
652       tem = copy_to_reg (tem);
653     }
654
655   /* For __builtin_frame_address, return what we've got.  But, on
656      the SPARC for example, we may have to add a bias.  */
657   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
658 #ifdef FRAME_ADDR_RTX
659     return FRAME_ADDR_RTX (tem);
660 #else
661     return tem;
662 #endif
663
664   /* For __builtin_return_address, get the return address from that frame.  */
665 #ifdef RETURN_ADDR_RTX
666   tem = RETURN_ADDR_RTX (count, tem);
667 #else
668   tem = memory_address (Pmode,
669                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
670   tem = gen_frame_mem (Pmode, tem);
671 #endif
672   return tem;
673 }
674
675 /* Alias set used for setjmp buffer.  */
676 static alias_set_type setjmp_alias_set = -1;
677
678 /* Construct the leading half of a __builtin_setjmp call.  Control will
679    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
680    exception handling code.  */
681
682 void
683 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
684 {
685   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
686   rtx stack_save;
687   rtx mem;
688
689   if (setjmp_alias_set == -1)
690     setjmp_alias_set = new_alias_set ();
691
692   buf_addr = convert_memory_address (Pmode, buf_addr);
693
694   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
695
696   /* We store the frame pointer and the address of receiver_label in
697      the buffer and use the rest of it for the stack save area, which
698      is machine-dependent.  */
699
700   mem = gen_rtx_MEM (Pmode, buf_addr);
701   set_mem_alias_set (mem, setjmp_alias_set);
702   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
703
704   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
705   set_mem_alias_set (mem, setjmp_alias_set);
706
707   emit_move_insn (validize_mem (mem),
708                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
709
710   stack_save = gen_rtx_MEM (sa_mode,
711                             plus_constant (buf_addr,
712                                            2 * GET_MODE_SIZE (Pmode)));
713   set_mem_alias_set (stack_save, setjmp_alias_set);
714   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
715
716   /* If there is further processing to do, do it.  */
717 #ifdef HAVE_builtin_setjmp_setup
718   if (HAVE_builtin_setjmp_setup)
719     emit_insn (gen_builtin_setjmp_setup (buf_addr));
720 #endif
721
722   /* Tell optimize_save_area_alloca that extra work is going to
723      need to go on during alloca.  */
724   cfun->calls_setjmp = 1;
725
726   /* We have a nonlocal label.   */
727   cfun->has_nonlocal_label = 1;
728 }
729
730 /* Construct the trailing part of a __builtin_setjmp call.  This is
731    also called directly by the SJLJ exception handling code.  */
732
733 void
734 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
735 {
736   /* Clobber the FP when we get here, so we have to make sure it's
737      marked as used by this function.  */
738   emit_use (hard_frame_pointer_rtx);
739
740   /* Mark the static chain as clobbered here so life information
741      doesn't get messed up for it.  */
742   emit_clobber (static_chain_rtx);
743
744   /* Now put in the code to restore the frame pointer, and argument
745      pointer, if needed.  */
746 #ifdef HAVE_nonlocal_goto
747   if (! HAVE_nonlocal_goto)
748 #endif
749     {
750       emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
751       /* This might change the hard frame pointer in ways that aren't
752          apparent to early optimization passes, so force a clobber.  */
753       emit_clobber (hard_frame_pointer_rtx);
754     }
755
756 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
757   if (fixed_regs[ARG_POINTER_REGNUM])
758     {
759 #ifdef ELIMINABLE_REGS
760       size_t i;
761       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
762
763       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
764         if (elim_regs[i].from == ARG_POINTER_REGNUM
765             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
766           break;
767
768       if (i == ARRAY_SIZE (elim_regs))
769 #endif
770         {
771           /* Now restore our arg pointer from the address at which it
772              was saved in our stack frame.  */
773           emit_move_insn (crtl->args.internal_arg_pointer,
774                           copy_to_reg (get_arg_pointer_save_area ()));
775         }
776     }
777 #endif
778
779 #ifdef HAVE_builtin_setjmp_receiver
780   if (HAVE_builtin_setjmp_receiver)
781     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
782   else
783 #endif
784 #ifdef HAVE_nonlocal_goto_receiver
785     if (HAVE_nonlocal_goto_receiver)
786       emit_insn (gen_nonlocal_goto_receiver ());
787     else
788 #endif
789       { /* Nothing */ }
790
791   /* We must not allow the code we just generated to be reordered by
792      scheduling.  Specifically, the update of the frame pointer must
793      happen immediately, not later.  */
794   emit_insn (gen_blockage ());
795 }
796
797 /* __builtin_longjmp is passed a pointer to an array of five words (not
798    all will be used on all machines).  It operates similarly to the C
799    library function of the same name, but is more efficient.  Much of
800    the code below is copied from the handling of non-local gotos.  */
801
802 static void
803 expand_builtin_longjmp (rtx buf_addr, rtx value)
804 {
805   rtx fp, lab, stack, insn, last;
806   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
807
808   /* DRAP is needed for stack realign if longjmp is expanded to current 
809      function  */
810   if (SUPPORTS_STACK_ALIGNMENT)
811     crtl->need_drap = true;
812
813   if (setjmp_alias_set == -1)
814     setjmp_alias_set = new_alias_set ();
815
816   buf_addr = convert_memory_address (Pmode, buf_addr);
817
818   buf_addr = force_reg (Pmode, buf_addr);
819
820   /* We used to store value in static_chain_rtx, but that fails if pointers
821      are smaller than integers.  We instead require that the user must pass
822      a second argument of 1, because that is what builtin_setjmp will
823      return.  This also makes EH slightly more efficient, since we are no
824      longer copying around a value that we don't care about.  */
825   gcc_assert (value == const1_rtx);
826
827   last = get_last_insn ();
828 #ifdef HAVE_builtin_longjmp
829   if (HAVE_builtin_longjmp)
830     emit_insn (gen_builtin_longjmp (buf_addr));
831   else
832 #endif
833     {
834       fp = gen_rtx_MEM (Pmode, buf_addr);
835       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
836                                                GET_MODE_SIZE (Pmode)));
837
838       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
839                                                    2 * GET_MODE_SIZE (Pmode)));
840       set_mem_alias_set (fp, setjmp_alias_set);
841       set_mem_alias_set (lab, setjmp_alias_set);
842       set_mem_alias_set (stack, setjmp_alias_set);
843
844       /* Pick up FP, label, and SP from the block and jump.  This code is
845          from expand_goto in stmt.c; see there for detailed comments.  */
846 #ifdef HAVE_nonlocal_goto
847       if (HAVE_nonlocal_goto)
848         /* We have to pass a value to the nonlocal_goto pattern that will
849            get copied into the static_chain pointer, but it does not matter
850            what that value is, because builtin_setjmp does not use it.  */
851         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
852       else
853 #endif
854         {
855           lab = copy_to_reg (lab);
856
857           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
858           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
859
860           emit_move_insn (hard_frame_pointer_rtx, fp);
861           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
862
863           emit_use (hard_frame_pointer_rtx);
864           emit_use (stack_pointer_rtx);
865           emit_indirect_jump (lab);
866         }
867     }
868
869   /* Search backwards and mark the jump insn as a non-local goto.
870      Note that this precludes the use of __builtin_longjmp to a
871      __builtin_setjmp target in the same function.  However, we've
872      already cautioned the user that these functions are for
873      internal exception handling use only.  */
874   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
875     {
876       gcc_assert (insn != last);
877
878       if (JUMP_P (insn))
879         {
880           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
881           break;
882         }
883       else if (CALL_P (insn))
884         break;
885     }
886 }
887
888 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
889    and the address of the save area.  */
890
891 static rtx
892 expand_builtin_nonlocal_goto (tree exp)
893 {
894   tree t_label, t_save_area;
895   rtx r_label, r_save_area, r_fp, r_sp, insn;
896
897   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
898     return NULL_RTX;
899
900   t_label = CALL_EXPR_ARG (exp, 0);
901   t_save_area = CALL_EXPR_ARG (exp, 1);
902
903   r_label = expand_normal (t_label);
904   r_label = convert_memory_address (Pmode, r_label);
905   r_save_area = expand_normal (t_save_area);
906   r_save_area = convert_memory_address (Pmode, r_save_area);
907   /* Copy the address of the save location to a register just in case it was based
908     on the frame pointer.   */
909   r_save_area = copy_to_reg (r_save_area);
910   r_fp = gen_rtx_MEM (Pmode, r_save_area);
911   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
912                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
913
914   crtl->has_nonlocal_goto = 1;
915
916 #ifdef HAVE_nonlocal_goto
917   /* ??? We no longer need to pass the static chain value, afaik.  */
918   if (HAVE_nonlocal_goto)
919     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
920   else
921 #endif
922     {
923       r_label = copy_to_reg (r_label);
924
925       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
926       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
927
928       /* Restore frame pointer for containing function.
929          This sets the actual hard register used for the frame pointer
930          to the location of the function's incoming static chain info.
931          The non-local goto handler will then adjust it to contain the
932          proper value and reload the argument pointer, if needed.  */
933       emit_move_insn (hard_frame_pointer_rtx, r_fp);
934       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
935
936       /* USE of hard_frame_pointer_rtx added for consistency;
937          not clear if really needed.  */
938       emit_use (hard_frame_pointer_rtx);
939       emit_use (stack_pointer_rtx);
940
941       /* If the architecture is using a GP register, we must
942          conservatively assume that the target function makes use of it.
943          The prologue of functions with nonlocal gotos must therefore
944          initialize the GP register to the appropriate value, and we
945          must then make sure that this value is live at the point
946          of the jump.  (Note that this doesn't necessarily apply
947          to targets with a nonlocal_goto pattern; they are free
948          to implement it in their own way.  Note also that this is
949          a no-op if the GP register is a global invariant.)  */
950       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
951           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
952         emit_use (pic_offset_table_rtx);
953
954       emit_indirect_jump (r_label);
955     }
956
957   /* Search backwards to the jump insn and mark it as a
958      non-local goto.  */
959   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
960     {
961       if (JUMP_P (insn))
962         {
963           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
964           break;
965         }
966       else if (CALL_P (insn))
967         break;
968     }
969
970   return const0_rtx;
971 }
972
973 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
974    (not all will be used on all machines) that was passed to __builtin_setjmp.
975    It updates the stack pointer in that block to correspond to the current
976    stack pointer.  */
977
978 static void
979 expand_builtin_update_setjmp_buf (rtx buf_addr)
980 {
981   enum machine_mode sa_mode = Pmode;
982   rtx stack_save;
983
984
985 #ifdef HAVE_save_stack_nonlocal
986   if (HAVE_save_stack_nonlocal)
987     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
988 #endif
989 #ifdef STACK_SAVEAREA_MODE
990   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
991 #endif
992
993   stack_save
994     = gen_rtx_MEM (sa_mode,
995                    memory_address
996                    (sa_mode,
997                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
998
999 #ifdef HAVE_setjmp
1000   if (HAVE_setjmp)
1001     emit_insn (gen_setjmp ());
1002 #endif
1003
1004   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1005 }
1006
1007 /* Expand a call to __builtin_prefetch.  For a target that does not support
1008    data prefetch, evaluate the memory address argument in case it has side
1009    effects.  */
1010
1011 static void
1012 expand_builtin_prefetch (tree exp)
1013 {
1014   tree arg0, arg1, arg2;
1015   int nargs;
1016   rtx op0, op1, op2;
1017
1018   if (!validate_arglist (exp, POINTER_TYPE, 0))
1019     return;
1020
1021   arg0 = CALL_EXPR_ARG (exp, 0);
1022
1023   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1024      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1025      locality).  */
1026   nargs = call_expr_nargs (exp);
1027   if (nargs > 1)
1028     arg1 = CALL_EXPR_ARG (exp, 1);
1029   else
1030     arg1 = integer_zero_node;
1031   if (nargs > 2)
1032     arg2 = CALL_EXPR_ARG (exp, 2);
1033   else
1034     arg2 = build_int_cst (NULL_TREE, 3);
1035
1036   /* Argument 0 is an address.  */
1037   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1038
1039   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1040   if (TREE_CODE (arg1) != INTEGER_CST)
1041     {
1042       error ("second argument to %<__builtin_prefetch%> must be a constant");
1043       arg1 = integer_zero_node;
1044     }
1045   op1 = expand_normal (arg1);
1046   /* Argument 1 must be either zero or one.  */
1047   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1048     {
1049       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1050                " using zero");
1051       op1 = const0_rtx;
1052     }
1053
1054   /* Argument 2 (locality) must be a compile-time constant int.  */
1055   if (TREE_CODE (arg2) != INTEGER_CST)
1056     {
1057       error ("third argument to %<__builtin_prefetch%> must be a constant");
1058       arg2 = integer_zero_node;
1059     }
1060   op2 = expand_normal (arg2);
1061   /* Argument 2 must be 0, 1, 2, or 3.  */
1062   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1063     {
1064       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1065       op2 = const0_rtx;
1066     }
1067
1068 #ifdef HAVE_prefetch
1069   if (HAVE_prefetch)
1070     {
1071       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1072              (op0,
1073               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1074           || (GET_MODE (op0) != Pmode))
1075         {
1076           op0 = convert_memory_address (Pmode, op0);
1077           op0 = force_reg (Pmode, op0);
1078         }
1079       emit_insn (gen_prefetch (op0, op1, op2));
1080     }
1081 #endif
1082
1083   /* Don't do anything with direct references to volatile memory, but
1084      generate code to handle other side effects.  */
1085   if (!MEM_P (op0) && side_effects_p (op0))
1086     emit_insn (op0);
1087 }
1088
1089 /* Get a MEM rtx for expression EXP which is the address of an operand
1090    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1091    the maximum length of the block of memory that might be accessed or
1092    NULL if unknown.  */
1093
1094 static rtx
1095 get_memory_rtx (tree exp, tree len)
1096 {
1097   tree orig_exp = exp;
1098   rtx addr, mem;
1099   HOST_WIDE_INT off;
1100
1101   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1102      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1103   if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1104     exp = TREE_OPERAND (exp, 0);
1105
1106   addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1107   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1108
1109   /* Get an expression we can use to find the attributes to assign to MEM.
1110      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1111      we can.  First remove any nops.  */
1112   while (CONVERT_EXPR_P (exp)
1113          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1114     exp = TREE_OPERAND (exp, 0);
1115
1116   off = 0;
1117   if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1118       && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1119       && host_integerp (TREE_OPERAND (exp, 1), 0)
1120       && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1121     exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1122   else if (TREE_CODE (exp) == ADDR_EXPR)
1123     exp = TREE_OPERAND (exp, 0);
1124   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1125     exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1126   else
1127     exp = NULL;
1128
1129   /* Honor attributes derived from exp, except for the alias set
1130      (as builtin stringops may alias with anything) and the size
1131      (as stringops may access multiple array elements).  */
1132   if (exp)
1133     {
1134       set_mem_attributes (mem, exp, 0);
1135
1136       if (off)
1137         mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1138
1139       /* Allow the string and memory builtins to overflow from one
1140          field into another, see http://gcc.gnu.org/PR23561.
1141          Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1142          memory accessed by the string or memory builtin will fit
1143          within the field.  */
1144       if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1145         {
1146           tree mem_expr = MEM_EXPR (mem);
1147           HOST_WIDE_INT offset = -1, length = -1;
1148           tree inner = exp;
1149
1150           while (TREE_CODE (inner) == ARRAY_REF
1151                  || CONVERT_EXPR_P (inner)
1152                  || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1153                  || TREE_CODE (inner) == SAVE_EXPR)
1154             inner = TREE_OPERAND (inner, 0);
1155
1156           gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1157
1158           if (MEM_OFFSET (mem)
1159               && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
1160             offset = INTVAL (MEM_OFFSET (mem));
1161
1162           if (offset >= 0 && len && host_integerp (len, 0))
1163             length = tree_low_cst (len, 0);
1164
1165           while (TREE_CODE (inner) == COMPONENT_REF)
1166             {
1167               tree field = TREE_OPERAND (inner, 1);
1168               gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1169               gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1170
1171               /* Bitfields are generally not byte-addressable.  */
1172               gcc_assert (!DECL_BIT_FIELD (field)
1173                           || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1174                                % BITS_PER_UNIT) == 0
1175                               && host_integerp (DECL_SIZE (field), 0)
1176                               && (TREE_INT_CST_LOW (DECL_SIZE (field))
1177                                   % BITS_PER_UNIT) == 0));
1178
1179               /* If we can prove that the memory starting at XEXP (mem, 0) and
1180                  ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1181                  can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
1182                  fields without DECL_SIZE_UNIT like flexible array members.  */
1183               if (length >= 0
1184                   && DECL_SIZE_UNIT (field)
1185                   && host_integerp (DECL_SIZE_UNIT (field), 0))
1186                 {
1187                   HOST_WIDE_INT size
1188                     = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
1189                   if (offset <= size
1190                       && length <= size
1191                       && offset + length <= size)
1192                     break;
1193                 }
1194
1195               if (offset >= 0
1196                   && host_integerp (DECL_FIELD_OFFSET (field), 0))
1197                 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
1198                           + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1199                             / BITS_PER_UNIT;
1200               else
1201                 {
1202                   offset = -1;
1203                   length = -1;
1204                 }
1205
1206               mem_expr = TREE_OPERAND (mem_expr, 0);
1207               inner = TREE_OPERAND (inner, 0);
1208             }
1209
1210           if (mem_expr == NULL)
1211             offset = -1;
1212           if (mem_expr != MEM_EXPR (mem))
1213             {
1214               set_mem_expr (mem, mem_expr);
1215               set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1216             }
1217         }
1218       set_mem_alias_set (mem, 0);
1219       set_mem_size (mem, NULL_RTX);
1220     }
1221
1222   return mem;
1223 }
1224 \f
1225 /* Built-in functions to perform an untyped call and return.  */
1226
1227 /* For each register that may be used for calling a function, this
1228    gives a mode used to copy the register's value.  VOIDmode indicates
1229    the register is not used for calling a function.  If the machine
1230    has register windows, this gives only the outbound registers.
1231    INCOMING_REGNO gives the corresponding inbound register.  */
1232 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1233
1234 /* For each register that may be used for returning values, this gives
1235    a mode used to copy the register's value.  VOIDmode indicates the
1236    register is not used for returning values.  If the machine has
1237    register windows, this gives only the outbound registers.
1238    INCOMING_REGNO gives the corresponding inbound register.  */
1239 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1240
1241 /* For each register that may be used for calling a function, this
1242    gives the offset of that register into the block returned by
1243    __builtin_apply_args.  0 indicates that the register is not
1244    used for calling a function.  */
1245 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1246
1247 /* Return the size required for the block returned by __builtin_apply_args,
1248    and initialize apply_args_mode.  */
1249
1250 static int
1251 apply_args_size (void)
1252 {
1253   static int size = -1;
1254   int align;
1255   unsigned int regno;
1256   enum machine_mode mode;
1257
1258   /* The values computed by this function never change.  */
1259   if (size < 0)
1260     {
1261       /* The first value is the incoming arg-pointer.  */
1262       size = GET_MODE_SIZE (Pmode);
1263
1264       /* The second value is the structure value address unless this is
1265          passed as an "invisible" first argument.  */
1266       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1267         size += GET_MODE_SIZE (Pmode);
1268
1269       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1270         if (FUNCTION_ARG_REGNO_P (regno))
1271           {
1272             mode = reg_raw_mode[regno];
1273
1274             gcc_assert (mode != VOIDmode);
1275
1276             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1277             if (size % align != 0)
1278               size = CEIL (size, align) * align;
1279             apply_args_reg_offset[regno] = size;
1280             size += GET_MODE_SIZE (mode);
1281             apply_args_mode[regno] = mode;
1282           }
1283         else
1284           {
1285             apply_args_mode[regno] = VOIDmode;
1286             apply_args_reg_offset[regno] = 0;
1287           }
1288     }
1289   return size;
1290 }
1291
1292 /* Return the size required for the block returned by __builtin_apply,
1293    and initialize apply_result_mode.  */
1294
1295 static int
1296 apply_result_size (void)
1297 {
1298   static int size = -1;
1299   int align, regno;
1300   enum machine_mode mode;
1301
1302   /* The values computed by this function never change.  */
1303   if (size < 0)
1304     {
1305       size = 0;
1306
1307       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1308         if (FUNCTION_VALUE_REGNO_P (regno))
1309           {
1310             mode = reg_raw_mode[regno];
1311
1312             gcc_assert (mode != VOIDmode);
1313
1314             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1315             if (size % align != 0)
1316               size = CEIL (size, align) * align;
1317             size += GET_MODE_SIZE (mode);
1318             apply_result_mode[regno] = mode;
1319           }
1320         else
1321           apply_result_mode[regno] = VOIDmode;
1322
1323       /* Allow targets that use untyped_call and untyped_return to override
1324          the size so that machine-specific information can be stored here.  */
1325 #ifdef APPLY_RESULT_SIZE
1326       size = APPLY_RESULT_SIZE;
1327 #endif
1328     }
1329   return size;
1330 }
1331
1332 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1333 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1334    the result block is used to save the values; otherwise it is used to
1335    restore the values.  */
1336
1337 static rtx
1338 result_vector (int savep, rtx result)
1339 {
1340   int regno, size, align, nelts;
1341   enum machine_mode mode;
1342   rtx reg, mem;
1343   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1344
1345   size = nelts = 0;
1346   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1347     if ((mode = apply_result_mode[regno]) != VOIDmode)
1348       {
1349         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1350         if (size % align != 0)
1351           size = CEIL (size, align) * align;
1352         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1353         mem = adjust_address (result, mode, size);
1354         savevec[nelts++] = (savep
1355                             ? gen_rtx_SET (VOIDmode, mem, reg)
1356                             : gen_rtx_SET (VOIDmode, reg, mem));
1357         size += GET_MODE_SIZE (mode);
1358       }
1359   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1360 }
1361 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1362
1363 /* Save the state required to perform an untyped call with the same
1364    arguments as were passed to the current function.  */
1365
1366 static rtx
1367 expand_builtin_apply_args_1 (void)
1368 {
1369   rtx registers, tem;
1370   int size, align, regno;
1371   enum machine_mode mode;
1372   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1373
1374   /* Create a block where the arg-pointer, structure value address,
1375      and argument registers can be saved.  */
1376   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1377
1378   /* Walk past the arg-pointer and structure value address.  */
1379   size = GET_MODE_SIZE (Pmode);
1380   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1381     size += GET_MODE_SIZE (Pmode);
1382
1383   /* Save each register used in calling a function to the block.  */
1384   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1385     if ((mode = apply_args_mode[regno]) != VOIDmode)
1386       {
1387         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1388         if (size % align != 0)
1389           size = CEIL (size, align) * align;
1390
1391         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1392
1393         emit_move_insn (adjust_address (registers, mode, size), tem);
1394         size += GET_MODE_SIZE (mode);
1395       }
1396
1397   /* Save the arg pointer to the block.  */
1398   tem = copy_to_reg (crtl->args.internal_arg_pointer);
1399 #ifdef STACK_GROWS_DOWNWARD
1400   /* We need the pointer as the caller actually passed them to us, not
1401      as we might have pretended they were passed.  Make sure it's a valid
1402      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1403   tem
1404     = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
1405                      NULL_RTX);
1406 #endif
1407   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1408
1409   size = GET_MODE_SIZE (Pmode);
1410
1411   /* Save the structure value address unless this is passed as an
1412      "invisible" first argument.  */
1413   if (struct_incoming_value)
1414     {
1415       emit_move_insn (adjust_address (registers, Pmode, size),
1416                       copy_to_reg (struct_incoming_value));
1417       size += GET_MODE_SIZE (Pmode);
1418     }
1419
1420   /* Return the address of the block.  */
1421   return copy_addr_to_reg (XEXP (registers, 0));
1422 }
1423
1424 /* __builtin_apply_args returns block of memory allocated on
1425    the stack into which is stored the arg pointer, structure
1426    value address, static chain, and all the registers that might
1427    possibly be used in performing a function call.  The code is
1428    moved to the start of the function so the incoming values are
1429    saved.  */
1430
1431 static rtx
1432 expand_builtin_apply_args (void)
1433 {
1434   /* Don't do __builtin_apply_args more than once in a function.
1435      Save the result of the first call and reuse it.  */
1436   if (apply_args_value != 0)
1437     return apply_args_value;
1438   {
1439     /* When this function is called, it means that registers must be
1440        saved on entry to this function.  So we migrate the
1441        call to the first insn of this function.  */
1442     rtx temp;
1443     rtx seq;
1444
1445     start_sequence ();
1446     temp = expand_builtin_apply_args_1 ();
1447     seq = get_insns ();
1448     end_sequence ();
1449
1450     apply_args_value = temp;
1451
1452     /* Put the insns after the NOTE that starts the function.
1453        If this is inside a start_sequence, make the outer-level insn
1454        chain current, so the code is placed at the start of the
1455        function.  If internal_arg_pointer is a non-virtual pseudo,
1456        it needs to be placed after the function that initializes
1457        that pseudo.  */
1458     push_topmost_sequence ();
1459     if (REG_P (crtl->args.internal_arg_pointer)
1460         && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1461       emit_insn_before (seq, parm_birth_insn);
1462     else
1463       emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1464     pop_topmost_sequence ();
1465     return temp;
1466   }
1467 }
1468
1469 /* Perform an untyped call and save the state required to perform an
1470    untyped return of whatever value was returned by the given function.  */
1471
1472 static rtx
1473 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1474 {
1475   int size, align, regno;
1476   enum machine_mode mode;
1477   rtx incoming_args, result, reg, dest, src, call_insn;
1478   rtx old_stack_level = 0;
1479   rtx call_fusage = 0;
1480   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1481
1482   arguments = convert_memory_address (Pmode, arguments);
1483
1484   /* Create a block where the return registers can be saved.  */
1485   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1486
1487   /* Fetch the arg pointer from the ARGUMENTS block.  */
1488   incoming_args = gen_reg_rtx (Pmode);
1489   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1490 #ifndef STACK_GROWS_DOWNWARD
1491   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1492                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1493 #endif
1494
1495   /* Push a new argument block and copy the arguments.  Do not allow
1496      the (potential) memcpy call below to interfere with our stack
1497      manipulations.  */
1498   do_pending_stack_adjust ();
1499   NO_DEFER_POP;
1500
1501   /* Save the stack with nonlocal if available.  */
1502 #ifdef HAVE_save_stack_nonlocal
1503   if (HAVE_save_stack_nonlocal)
1504     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1505   else
1506 #endif
1507     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1508
1509   /* Allocate a block of memory onto the stack and copy the memory
1510      arguments to the outgoing arguments address.  */
1511   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1512
1513   /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1514      may have already set current_function_calls_alloca to true.
1515      current_function_calls_alloca won't be set if argsize is zero,
1516      so we have to guarantee need_drap is true here.  */
1517   if (SUPPORTS_STACK_ALIGNMENT)
1518     crtl->need_drap = true;
1519
1520   dest = virtual_outgoing_args_rtx;
1521 #ifndef STACK_GROWS_DOWNWARD
1522   if (GET_CODE (argsize) == CONST_INT)
1523     dest = plus_constant (dest, -INTVAL (argsize));
1524   else
1525     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1526 #endif
1527   dest = gen_rtx_MEM (BLKmode, dest);
1528   set_mem_align (dest, PARM_BOUNDARY);
1529   src = gen_rtx_MEM (BLKmode, incoming_args);
1530   set_mem_align (src, PARM_BOUNDARY);
1531   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1532
1533   /* Refer to the argument block.  */
1534   apply_args_size ();
1535   arguments = gen_rtx_MEM (BLKmode, arguments);
1536   set_mem_align (arguments, PARM_BOUNDARY);
1537
1538   /* Walk past the arg-pointer and structure value address.  */
1539   size = GET_MODE_SIZE (Pmode);
1540   if (struct_value)
1541     size += GET_MODE_SIZE (Pmode);
1542
1543   /* Restore each of the registers previously saved.  Make USE insns
1544      for each of these registers for use in making the call.  */
1545   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1546     if ((mode = apply_args_mode[regno]) != VOIDmode)
1547       {
1548         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1549         if (size % align != 0)
1550           size = CEIL (size, align) * align;
1551         reg = gen_rtx_REG (mode, regno);
1552         emit_move_insn (reg, adjust_address (arguments, mode, size));
1553         use_reg (&call_fusage, reg);
1554         size += GET_MODE_SIZE (mode);
1555       }
1556
1557   /* Restore the structure value address unless this is passed as an
1558      "invisible" first argument.  */
1559   size = GET_MODE_SIZE (Pmode);
1560   if (struct_value)
1561     {
1562       rtx value = gen_reg_rtx (Pmode);
1563       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1564       emit_move_insn (struct_value, value);
1565       if (REG_P (struct_value))
1566         use_reg (&call_fusage, struct_value);
1567       size += GET_MODE_SIZE (Pmode);
1568     }
1569
1570   /* All arguments and registers used for the call are set up by now!  */
1571   function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1572
1573   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1574      and we don't want to load it into a register as an optimization,
1575      because prepare_call_address already did it if it should be done.  */
1576   if (GET_CODE (function) != SYMBOL_REF)
1577     function = memory_address (FUNCTION_MODE, function);
1578
1579   /* Generate the actual call instruction and save the return value.  */
1580 #ifdef HAVE_untyped_call
1581   if (HAVE_untyped_call)
1582     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1583                                       result, result_vector (1, result)));
1584   else
1585 #endif
1586 #ifdef HAVE_call_value
1587   if (HAVE_call_value)
1588     {
1589       rtx valreg = 0;
1590
1591       /* Locate the unique return register.  It is not possible to
1592          express a call that sets more than one return register using
1593          call_value; use untyped_call for that.  In fact, untyped_call
1594          only needs to save the return registers in the given block.  */
1595       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1596         if ((mode = apply_result_mode[regno]) != VOIDmode)
1597           {
1598             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1599
1600             valreg = gen_rtx_REG (mode, regno);
1601           }
1602
1603       emit_call_insn (GEN_CALL_VALUE (valreg,
1604                                       gen_rtx_MEM (FUNCTION_MODE, function),
1605                                       const0_rtx, NULL_RTX, const0_rtx));
1606
1607       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1608     }
1609   else
1610 #endif
1611     gcc_unreachable ();
1612
1613   /* Find the CALL insn we just emitted, and attach the register usage
1614      information.  */
1615   call_insn = last_call_insn ();
1616   add_function_usage_to (call_insn, call_fusage);
1617
1618   /* Restore the stack.  */
1619 #ifdef HAVE_save_stack_nonlocal
1620   if (HAVE_save_stack_nonlocal)
1621     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1622   else
1623 #endif
1624     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1625
1626   OK_DEFER_POP;
1627
1628   /* Return the address of the result block.  */
1629   result = copy_addr_to_reg (XEXP (result, 0));
1630   return convert_memory_address (ptr_mode, result);
1631 }
1632
1633 /* Perform an untyped return.  */
1634
1635 static void
1636 expand_builtin_return (rtx result)
1637 {
1638   int size, align, regno;
1639   enum machine_mode mode;
1640   rtx reg;
1641   rtx call_fusage = 0;
1642
1643   result = convert_memory_address (Pmode, result);
1644
1645   apply_result_size ();
1646   result = gen_rtx_MEM (BLKmode, result);
1647
1648 #ifdef HAVE_untyped_return
1649   if (HAVE_untyped_return)
1650     {
1651       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1652       emit_barrier ();
1653       return;
1654     }
1655 #endif
1656
1657   /* Restore the return value and note that each value is used.  */
1658   size = 0;
1659   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1660     if ((mode = apply_result_mode[regno]) != VOIDmode)
1661       {
1662         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1663         if (size % align != 0)
1664           size = CEIL (size, align) * align;
1665         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1666         emit_move_insn (reg, adjust_address (result, mode, size));
1667
1668         push_to_sequence (call_fusage);
1669         emit_use (reg);
1670         call_fusage = get_insns ();
1671         end_sequence ();
1672         size += GET_MODE_SIZE (mode);
1673       }
1674
1675   /* Put the USE insns before the return.  */
1676   emit_insn (call_fusage);
1677
1678   /* Return whatever values was restored by jumping directly to the end
1679      of the function.  */
1680   expand_naked_return ();
1681 }
1682
1683 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1684
1685 static enum type_class
1686 type_to_class (tree type)
1687 {
1688   switch (TREE_CODE (type))
1689     {
1690     case VOID_TYPE:        return void_type_class;
1691     case INTEGER_TYPE:     return integer_type_class;
1692     case ENUMERAL_TYPE:    return enumeral_type_class;
1693     case BOOLEAN_TYPE:     return boolean_type_class;
1694     case POINTER_TYPE:     return pointer_type_class;
1695     case REFERENCE_TYPE:   return reference_type_class;
1696     case OFFSET_TYPE:      return offset_type_class;
1697     case REAL_TYPE:        return real_type_class;
1698     case COMPLEX_TYPE:     return complex_type_class;
1699     case FUNCTION_TYPE:    return function_type_class;
1700     case METHOD_TYPE:      return method_type_class;
1701     case RECORD_TYPE:      return record_type_class;
1702     case UNION_TYPE:
1703     case QUAL_UNION_TYPE:  return union_type_class;
1704     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1705                                    ? string_type_class : array_type_class);
1706     case LANG_TYPE:        return lang_type_class;
1707     default:               return no_type_class;
1708     }
1709 }
1710
1711 /* Expand a call EXP to __builtin_classify_type.  */
1712
1713 static rtx
1714 expand_builtin_classify_type (tree exp)
1715 {
1716   if (call_expr_nargs (exp))
1717     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1718   return GEN_INT (no_type_class);
1719 }
1720
1721 /* This helper macro, meant to be used in mathfn_built_in below,
1722    determines which among a set of three builtin math functions is
1723    appropriate for a given type mode.  The `F' and `L' cases are
1724    automatically generated from the `double' case.  */
1725 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1726   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1727   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1728   fcodel = BUILT_IN_MATHFN##L ; break;
1729 /* Similar to above, but appends _R after any F/L suffix.  */
1730 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1731   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1732   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1733   fcodel = BUILT_IN_MATHFN##L_R ; break;
1734
1735 /* Return mathematic function equivalent to FN but operating directly
1736    on TYPE, if available.  If IMPLICIT is true find the function in
1737    implicit_built_in_decls[], otherwise use built_in_decls[].  If we
1738    can't do the conversion, return zero.  */
1739
1740 static tree
1741 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
1742 {
1743   tree const *const fn_arr
1744     = implicit ? implicit_built_in_decls : built_in_decls;
1745   enum built_in_function fcode, fcodef, fcodel;
1746
1747   switch (fn)
1748     {
1749       CASE_MATHFN (BUILT_IN_ACOS)
1750       CASE_MATHFN (BUILT_IN_ACOSH)
1751       CASE_MATHFN (BUILT_IN_ASIN)
1752       CASE_MATHFN (BUILT_IN_ASINH)
1753       CASE_MATHFN (BUILT_IN_ATAN)
1754       CASE_MATHFN (BUILT_IN_ATAN2)
1755       CASE_MATHFN (BUILT_IN_ATANH)
1756       CASE_MATHFN (BUILT_IN_CBRT)
1757       CASE_MATHFN (BUILT_IN_CEIL)
1758       CASE_MATHFN (BUILT_IN_CEXPI)
1759       CASE_MATHFN (BUILT_IN_COPYSIGN)
1760       CASE_MATHFN (BUILT_IN_COS)
1761       CASE_MATHFN (BUILT_IN_COSH)
1762       CASE_MATHFN (BUILT_IN_DREM)
1763       CASE_MATHFN (BUILT_IN_ERF)
1764       CASE_MATHFN (BUILT_IN_ERFC)
1765       CASE_MATHFN (BUILT_IN_EXP)
1766       CASE_MATHFN (BUILT_IN_EXP10)
1767       CASE_MATHFN (BUILT_IN_EXP2)
1768       CASE_MATHFN (BUILT_IN_EXPM1)
1769       CASE_MATHFN (BUILT_IN_FABS)
1770       CASE_MATHFN (BUILT_IN_FDIM)
1771       CASE_MATHFN (BUILT_IN_FLOOR)
1772       CASE_MATHFN (BUILT_IN_FMA)
1773       CASE_MATHFN (BUILT_IN_FMAX)
1774       CASE_MATHFN (BUILT_IN_FMIN)
1775       CASE_MATHFN (BUILT_IN_FMOD)
1776       CASE_MATHFN (BUILT_IN_FREXP)
1777       CASE_MATHFN (BUILT_IN_GAMMA)
1778       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1779       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1780       CASE_MATHFN (BUILT_IN_HYPOT)
1781       CASE_MATHFN (BUILT_IN_ILOGB)
1782       CASE_MATHFN (BUILT_IN_INF)
1783       CASE_MATHFN (BUILT_IN_ISINF)
1784       CASE_MATHFN (BUILT_IN_J0)
1785       CASE_MATHFN (BUILT_IN_J1)
1786       CASE_MATHFN (BUILT_IN_JN)
1787       CASE_MATHFN (BUILT_IN_LCEIL)
1788       CASE_MATHFN (BUILT_IN_LDEXP)
1789       CASE_MATHFN (BUILT_IN_LFLOOR)
1790       CASE_MATHFN (BUILT_IN_LGAMMA)
1791       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1792       CASE_MATHFN (BUILT_IN_LLCEIL)
1793       CASE_MATHFN (BUILT_IN_LLFLOOR)
1794       CASE_MATHFN (BUILT_IN_LLRINT)
1795       CASE_MATHFN (BUILT_IN_LLROUND)
1796       CASE_MATHFN (BUILT_IN_LOG)
1797       CASE_MATHFN (BUILT_IN_LOG10)
1798       CASE_MATHFN (BUILT_IN_LOG1P)
1799       CASE_MATHFN (BUILT_IN_LOG2)
1800       CASE_MATHFN (BUILT_IN_LOGB)
1801       CASE_MATHFN (BUILT_IN_LRINT)
1802       CASE_MATHFN (BUILT_IN_LROUND)
1803       CASE_MATHFN (BUILT_IN_MODF)
1804       CASE_MATHFN (BUILT_IN_NAN)
1805       CASE_MATHFN (BUILT_IN_NANS)
1806       CASE_MATHFN (BUILT_IN_NEARBYINT)
1807       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1808       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1809       CASE_MATHFN (BUILT_IN_POW)
1810       CASE_MATHFN (BUILT_IN_POWI)
1811       CASE_MATHFN (BUILT_IN_POW10)
1812       CASE_MATHFN (BUILT_IN_REMAINDER)
1813       CASE_MATHFN (BUILT_IN_REMQUO)
1814       CASE_MATHFN (BUILT_IN_RINT)
1815       CASE_MATHFN (BUILT_IN_ROUND)
1816       CASE_MATHFN (BUILT_IN_SCALB)
1817       CASE_MATHFN (BUILT_IN_SCALBLN)
1818       CASE_MATHFN (BUILT_IN_SCALBN)
1819       CASE_MATHFN (BUILT_IN_SIGNBIT)
1820       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1821       CASE_MATHFN (BUILT_IN_SIN)
1822       CASE_MATHFN (BUILT_IN_SINCOS)
1823       CASE_MATHFN (BUILT_IN_SINH)
1824       CASE_MATHFN (BUILT_IN_SQRT)
1825       CASE_MATHFN (BUILT_IN_TAN)
1826       CASE_MATHFN (BUILT_IN_TANH)
1827       CASE_MATHFN (BUILT_IN_TGAMMA)
1828       CASE_MATHFN (BUILT_IN_TRUNC)
1829       CASE_MATHFN (BUILT_IN_Y0)
1830       CASE_MATHFN (BUILT_IN_Y1)
1831       CASE_MATHFN (BUILT_IN_YN)
1832
1833       default:
1834         return NULL_TREE;
1835       }
1836
1837   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1838     return fn_arr[fcode];
1839   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1840     return fn_arr[fcodef];
1841   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1842     return fn_arr[fcodel];
1843   else
1844     return NULL_TREE;
1845 }
1846
1847 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1848
1849 tree
1850 mathfn_built_in (tree type, enum built_in_function fn)
1851 {
1852   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1853 }
1854
1855 /* If errno must be maintained, expand the RTL to check if the result,
1856    TARGET, of a built-in function call, EXP, is NaN, and if so set
1857    errno to EDOM.  */
1858
1859 static void
1860 expand_errno_check (tree exp, rtx target)
1861 {
1862   rtx lab = gen_label_rtx ();
1863
1864   /* Test the result; if it is NaN, set errno=EDOM because
1865      the argument was not in the domain.  */
1866   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1867                            0, lab);
1868
1869 #ifdef TARGET_EDOM
1870   /* If this built-in doesn't throw an exception, set errno directly.  */
1871   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1872     {
1873 #ifdef GEN_ERRNO_RTX
1874       rtx errno_rtx = GEN_ERRNO_RTX;
1875 #else
1876       rtx errno_rtx
1877           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1878 #endif
1879       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1880       emit_label (lab);
1881       return;
1882     }
1883 #endif
1884
1885   /* Make sure the library call isn't expanded as a tail call.  */
1886   CALL_EXPR_TAILCALL (exp) = 0;
1887
1888   /* We can't set errno=EDOM directly; let the library call do it.
1889      Pop the arguments right away in case the call gets deleted.  */
1890   NO_DEFER_POP;
1891   expand_call (exp, target, 0);
1892   OK_DEFER_POP;
1893   emit_label (lab);
1894 }
1895
1896 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1897    Return NULL_RTX if a normal call should be emitted rather than expanding
1898    the function in-line.  EXP is the expression that is a call to the builtin
1899    function; if convenient, the result should be placed in TARGET.
1900    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1901
1902 static rtx
1903 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1904 {
1905   optab builtin_optab;
1906   rtx op0, insns, before_call;
1907   tree fndecl = get_callee_fndecl (exp);
1908   enum machine_mode mode;
1909   bool errno_set = false;
1910   tree arg;
1911
1912   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1913     return NULL_RTX;
1914
1915   arg = CALL_EXPR_ARG (exp, 0);
1916
1917   switch (DECL_FUNCTION_CODE (fndecl))
1918     {
1919     CASE_FLT_FN (BUILT_IN_SQRT):
1920       errno_set = ! tree_expr_nonnegative_p (arg);
1921       builtin_optab = sqrt_optab;
1922       break;
1923     CASE_FLT_FN (BUILT_IN_EXP):
1924       errno_set = true; builtin_optab = exp_optab; break;
1925     CASE_FLT_FN (BUILT_IN_EXP10):
1926     CASE_FLT_FN (BUILT_IN_POW10):
1927       errno_set = true; builtin_optab = exp10_optab; break;
1928     CASE_FLT_FN (BUILT_IN_EXP2):
1929       errno_set = true; builtin_optab = exp2_optab; break;
1930     CASE_FLT_FN (BUILT_IN_EXPM1):
1931       errno_set = true; builtin_optab = expm1_optab; break;
1932     CASE_FLT_FN (BUILT_IN_LOGB):
1933       errno_set = true; builtin_optab = logb_optab; break;
1934     CASE_FLT_FN (BUILT_IN_LOG):
1935       errno_set = true; builtin_optab = log_optab; break;
1936     CASE_FLT_FN (BUILT_IN_LOG10):
1937       errno_set = true; builtin_optab = log10_optab; break;
1938     CASE_FLT_FN (BUILT_IN_LOG2):
1939       errno_set = true; builtin_optab = log2_optab; break;
1940     CASE_FLT_FN (BUILT_IN_LOG1P):
1941       errno_set = true; builtin_optab = log1p_optab; break;
1942     CASE_FLT_FN (BUILT_IN_ASIN):
1943       builtin_optab = asin_optab; break;
1944     CASE_FLT_FN (BUILT_IN_ACOS):
1945       builtin_optab = acos_optab; break;
1946     CASE_FLT_FN (BUILT_IN_TAN):
1947       builtin_optab = tan_optab; break;
1948     CASE_FLT_FN (BUILT_IN_ATAN):
1949       builtin_optab = atan_optab; break;
1950     CASE_FLT_FN (BUILT_IN_FLOOR):
1951       builtin_optab = floor_optab; break;
1952     CASE_FLT_FN (BUILT_IN_CEIL):
1953       builtin_optab = ceil_optab; break;
1954     CASE_FLT_FN (BUILT_IN_TRUNC):
1955       builtin_optab = btrunc_optab; break;
1956     CASE_FLT_FN (BUILT_IN_ROUND):
1957       builtin_optab = round_optab; break;
1958     CASE_FLT_FN (BUILT_IN_NEARBYINT):
1959       builtin_optab = nearbyint_optab;
1960       if (flag_trapping_math)
1961         break;
1962       /* Else fallthrough and expand as rint.  */
1963     CASE_FLT_FN (BUILT_IN_RINT):
1964       builtin_optab = rint_optab; break;
1965     default:
1966       gcc_unreachable ();
1967     }
1968
1969   /* Make a suitable register to place result in.  */
1970   mode = TYPE_MODE (TREE_TYPE (exp));
1971
1972   if (! flag_errno_math || ! HONOR_NANS (mode))
1973     errno_set = false;
1974
1975   /* Before working hard, check whether the instruction is available.  */
1976   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
1977     {
1978       target = gen_reg_rtx (mode);
1979
1980       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1981          need to expand the argument again.  This way, we will not perform
1982          side-effects more the once.  */
1983       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
1984
1985       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
1986
1987       start_sequence ();
1988
1989       /* Compute into TARGET.
1990          Set TARGET to wherever the result comes back.  */
1991       target = expand_unop (mode, builtin_optab, op0, target, 0);
1992
1993       if (target != 0)
1994         {
1995           if (errno_set)
1996             expand_errno_check (exp, target);
1997
1998           /* Output the entire sequence.  */
1999           insns = get_insns ();
2000           end_sequence ();
2001           emit_insn (insns);
2002           return target;
2003         }
2004
2005       /* If we were unable to expand via the builtin, stop the sequence
2006          (without outputting the insns) and call to the library function
2007          with the stabilized argument list.  */
2008       end_sequence ();
2009     }
2010
2011   before_call = get_last_insn ();
2012
2013   return expand_call (exp, target, target == const0_rtx);
2014 }
2015
2016 /* Expand a call to the builtin binary math functions (pow and atan2).
2017    Return NULL_RTX if a normal call should be emitted rather than expanding the
2018    function in-line.  EXP is the expression that is a call to the builtin
2019    function; if convenient, the result should be placed in TARGET.
2020    SUBTARGET may be used as the target for computing one of EXP's
2021    operands.  */
2022
2023 static rtx
2024 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2025 {
2026   optab builtin_optab;
2027   rtx op0, op1, insns;
2028   int op1_type = REAL_TYPE;
2029   tree fndecl = get_callee_fndecl (exp);
2030   tree arg0, arg1;
2031   enum machine_mode mode;
2032   bool errno_set = true;
2033
2034   switch (DECL_FUNCTION_CODE (fndecl))
2035     {
2036     CASE_FLT_FN (BUILT_IN_SCALBN):
2037     CASE_FLT_FN (BUILT_IN_SCALBLN):
2038     CASE_FLT_FN (BUILT_IN_LDEXP):
2039       op1_type = INTEGER_TYPE;
2040     default:
2041       break;
2042     }
2043
2044   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2045     return NULL_RTX;
2046
2047   arg0 = CALL_EXPR_ARG (exp, 0);
2048   arg1 = CALL_EXPR_ARG (exp, 1);
2049
2050   switch (DECL_FUNCTION_CODE (fndecl))
2051     {
2052     CASE_FLT_FN (BUILT_IN_POW):
2053       builtin_optab = pow_optab; break;
2054     CASE_FLT_FN (BUILT_IN_ATAN2):
2055       builtin_optab = atan2_optab; break;
2056     CASE_FLT_FN (BUILT_IN_SCALB):
2057       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2058         return 0;
2059       builtin_optab = scalb_optab; break;
2060     CASE_FLT_FN (BUILT_IN_SCALBN):
2061     CASE_FLT_FN (BUILT_IN_SCALBLN):
2062       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2063         return 0;
2064     /* Fall through... */
2065     CASE_FLT_FN (BUILT_IN_LDEXP):
2066       builtin_optab = ldexp_optab; break;
2067     CASE_FLT_FN (BUILT_IN_FMOD):
2068       builtin_optab = fmod_optab; break;
2069     CASE_FLT_FN (BUILT_IN_REMAINDER):
2070     CASE_FLT_FN (BUILT_IN_DREM):
2071       builtin_optab = remainder_optab; break;
2072     default:
2073       gcc_unreachable ();
2074     }
2075
2076   /* Make a suitable register to place result in.  */
2077   mode = TYPE_MODE (TREE_TYPE (exp));
2078
2079   /* Before working hard, check whether the instruction is available.  */
2080   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2081     return NULL_RTX;
2082
2083   target = gen_reg_rtx (mode);
2084
2085   if (! flag_errno_math || ! HONOR_NANS (mode))
2086     errno_set = false;
2087
2088   /* Always stabilize the argument list.  */
2089   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2090   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2091
2092   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2093   op1 = expand_normal (arg1);
2094
2095   start_sequence ();
2096
2097   /* Compute into TARGET.
2098      Set TARGET to wherever the result comes back.  */
2099   target = expand_binop (mode, builtin_optab, op0, op1,
2100                          target, 0, OPTAB_DIRECT);
2101
2102   /* If we were unable to expand via the builtin, stop the sequence
2103      (without outputting the insns) and call to the library function
2104      with the stabilized argument list.  */
2105   if (target == 0)
2106     {
2107       end_sequence ();
2108       return expand_call (exp, target, target == const0_rtx);
2109     }
2110
2111   if (errno_set)
2112     expand_errno_check (exp, target);
2113
2114   /* Output the entire sequence.  */
2115   insns = get_insns ();
2116   end_sequence ();
2117   emit_insn (insns);
2118
2119   return target;
2120 }
2121
2122 /* Expand a call to the builtin sin and cos math functions.
2123    Return NULL_RTX if a normal call should be emitted rather than expanding the
2124    function in-line.  EXP is the expression that is a call to the builtin
2125    function; if convenient, the result should be placed in TARGET.
2126    SUBTARGET may be used as the target for computing one of EXP's
2127    operands.  */
2128
2129 static rtx
2130 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2131 {
2132   optab builtin_optab;
2133   rtx op0, insns;
2134   tree fndecl = get_callee_fndecl (exp);
2135   enum machine_mode mode;
2136   tree arg;
2137
2138   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2139     return NULL_RTX;
2140
2141   arg = CALL_EXPR_ARG (exp, 0);
2142
2143   switch (DECL_FUNCTION_CODE (fndecl))
2144     {
2145     CASE_FLT_FN (BUILT_IN_SIN):
2146     CASE_FLT_FN (BUILT_IN_COS):
2147       builtin_optab = sincos_optab; break;
2148     default:
2149       gcc_unreachable ();
2150     }
2151
2152   /* Make a suitable register to place result in.  */
2153   mode = TYPE_MODE (TREE_TYPE (exp));
2154
2155   /* Check if sincos insn is available, otherwise fallback
2156      to sin or cos insn.  */
2157   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2158     switch (DECL_FUNCTION_CODE (fndecl))
2159       {
2160       CASE_FLT_FN (BUILT_IN_SIN):
2161         builtin_optab = sin_optab; break;
2162       CASE_FLT_FN (BUILT_IN_COS):
2163         builtin_optab = cos_optab; break;
2164       default:
2165         gcc_unreachable ();
2166       }
2167
2168   /* Before working hard, check whether the instruction is available.  */
2169   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
2170     {
2171       target = gen_reg_rtx (mode);
2172
2173       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2174          need to expand the argument again.  This way, we will not perform
2175          side-effects more the once.  */
2176       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2177
2178       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2179
2180       start_sequence ();
2181
2182       /* Compute into TARGET.
2183          Set TARGET to wherever the result comes back.  */
2184       if (builtin_optab == sincos_optab)
2185         {
2186           int result;
2187
2188           switch (DECL_FUNCTION_CODE (fndecl))
2189             {
2190             CASE_FLT_FN (BUILT_IN_SIN):
2191               result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2192               break;
2193             CASE_FLT_FN (BUILT_IN_COS):
2194               result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2195               break;
2196             default:
2197               gcc_unreachable ();
2198             }
2199           gcc_assert (result);
2200         }
2201       else
2202         {
2203           target = expand_unop (mode, builtin_optab, op0, target, 0);
2204         }
2205
2206       if (target != 0)
2207         {
2208           /* Output the entire sequence.  */
2209           insns = get_insns ();
2210           end_sequence ();
2211           emit_insn (insns);
2212           return target;
2213         }
2214
2215       /* If we were unable to expand via the builtin, stop the sequence
2216          (without outputting the insns) and call to the library function
2217          with the stabilized argument list.  */
2218       end_sequence ();
2219     }
2220
2221   target = expand_call (exp, target, target == const0_rtx);
2222
2223   return target;
2224 }
2225
2226 /* Expand a call to one of the builtin math functions that operate on
2227    floating point argument and output an integer result (ilogb, isinf,
2228    isnan, etc).
2229    Return 0 if a normal call should be emitted rather than expanding the
2230    function in-line.  EXP is the expression that is a call to the builtin
2231    function; if convenient, the result should be placed in TARGET.
2232    SUBTARGET may be used as the target for computing one of EXP's operands.  */
2233
2234 static rtx
2235 expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2236 {
2237   optab builtin_optab = 0;
2238   enum insn_code icode = CODE_FOR_nothing;
2239   rtx op0;
2240   tree fndecl = get_callee_fndecl (exp);
2241   enum machine_mode mode;
2242   bool errno_set = false;
2243   tree arg;
2244
2245   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2246     return NULL_RTX;
2247
2248   arg = CALL_EXPR_ARG (exp, 0);
2249
2250   switch (DECL_FUNCTION_CODE (fndecl))
2251     {
2252     CASE_FLT_FN (BUILT_IN_ILOGB):
2253       errno_set = true; builtin_optab = ilogb_optab; break;
2254     CASE_FLT_FN (BUILT_IN_ISINF):
2255       builtin_optab = isinf_optab; break;
2256     case BUILT_IN_ISNORMAL:
2257     case BUILT_IN_ISFINITE:
2258     CASE_FLT_FN (BUILT_IN_FINITE):
2259       /* These builtins have no optabs (yet).  */
2260       break;
2261     default:
2262       gcc_unreachable ();
2263     }
2264
2265   /* There's no easy way to detect the case we need to set EDOM.  */
2266   if (flag_errno_math && errno_set)
2267     return NULL_RTX;
2268
2269   /* Optab mode depends on the mode of the input argument.  */
2270   mode = TYPE_MODE (TREE_TYPE (arg));
2271
2272   if (builtin_optab)
2273     icode = optab_handler (builtin_optab, mode)->insn_code;
2274  
2275   /* Before working hard, check whether the instruction is available.  */
2276   if (icode != CODE_FOR_nothing)
2277     {
2278       /* Make a suitable register to place result in.  */
2279       if (!target
2280           || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2281          target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2282
2283       gcc_assert (insn_data[icode].operand[0].predicate
2284                   (target, GET_MODE (target)));
2285
2286       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2287          need to expand the argument again.  This way, we will not perform
2288          side-effects more the once.  */
2289       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2290
2291       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2292
2293       if (mode != GET_MODE (op0))
2294         op0 = convert_to_mode (mode, op0, 0);
2295
2296       /* Compute into TARGET.
2297          Set TARGET to wherever the result comes back.  */
2298       emit_unop_insn (icode, target, op0, UNKNOWN);
2299       return target;
2300     }
2301
2302   /* If there is no optab, try generic code.  */
2303   switch (DECL_FUNCTION_CODE (fndecl))
2304     {
2305       tree result;
2306
2307     CASE_FLT_FN (BUILT_IN_ISINF):
2308       {
2309         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
2310         tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
2311         tree const type = TREE_TYPE (arg);
2312         REAL_VALUE_TYPE r;
2313         char buf[128];
2314
2315         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2316         real_from_string (&r, buf);
2317         result = build_call_expr (isgr_fn, 2,
2318                                   fold_build1 (ABS_EXPR, type, arg),
2319                                   build_real (type, r));
2320         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2321       }
2322     CASE_FLT_FN (BUILT_IN_FINITE):
2323     case BUILT_IN_ISFINITE:
2324       {
2325         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
2326         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2327         tree const type = TREE_TYPE (arg);
2328         REAL_VALUE_TYPE r;
2329         char buf[128];
2330
2331         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2332         real_from_string (&r, buf);
2333         result = build_call_expr (isle_fn, 2,
2334                                   fold_build1 (ABS_EXPR, type, arg),
2335                                   build_real (type, r));
2336         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2337       }
2338     case BUILT_IN_ISNORMAL:
2339       {
2340         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
2341            islessequal(fabs(x),DBL_MAX).  */
2342         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
2343         tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
2344         tree const type = TREE_TYPE (arg);
2345         REAL_VALUE_TYPE rmax, rmin;
2346         char buf[128];
2347
2348         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
2349         real_from_string (&rmax, buf);
2350         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
2351         real_from_string (&rmin, buf);
2352         arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
2353         result = build_call_expr (isle_fn, 2, arg,
2354                                   build_real (type, rmax));
2355         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
2356                               build_call_expr (isge_fn, 2, arg,
2357                                                build_real (type, rmin)));
2358         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
2359       }
2360     default:
2361       break;
2362     }
2363
2364   target = expand_call (exp, target, target == const0_rtx);
2365
2366   return target;
2367 }
2368
2369 /* Expand a call to the builtin sincos math function.
2370    Return NULL_RTX if a normal call should be emitted rather than expanding the
2371    function in-line.  EXP is the expression that is a call to the builtin
2372    function.  */
2373
2374 static rtx
2375 expand_builtin_sincos (tree exp)
2376 {
2377   rtx op0, op1, op2, target1, target2;
2378   enum machine_mode mode;
2379   tree arg, sinp, cosp;
2380   int result;
2381
2382   if (!validate_arglist (exp, REAL_TYPE,
2383                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2384     return NULL_RTX;
2385
2386   arg = CALL_EXPR_ARG (exp, 0);
2387   sinp = CALL_EXPR_ARG (exp, 1);
2388   cosp = CALL_EXPR_ARG (exp, 2);
2389
2390   /* Make a suitable register to place result in.  */
2391   mode = TYPE_MODE (TREE_TYPE (arg));
2392
2393   /* Check if sincos insn is available, otherwise emit the call.  */
2394   if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
2395     return NULL_RTX;
2396
2397   target1 = gen_reg_rtx (mode);
2398   target2 = gen_reg_rtx (mode);
2399
2400   op0 = expand_normal (arg);
2401   op1 = expand_normal (build_fold_indirect_ref (sinp));
2402   op2 = expand_normal (build_fold_indirect_ref (cosp));
2403
2404   /* Compute into target1 and target2.
2405      Set TARGET to wherever the result comes back.  */
2406   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2407   gcc_assert (result);
2408
2409   /* Move target1 and target2 to the memory locations indicated
2410      by op1 and op2.  */
2411   emit_move_insn (op1, target1);
2412   emit_move_insn (op2, target2);
2413
2414   return const0_rtx;
2415 }
2416
2417 /* Expand a call to the internal cexpi builtin to the sincos math function.
2418    EXP is the expression that is a call to the builtin function; if convenient,
2419    the result should be placed in TARGET.  SUBTARGET may be used as the target
2420    for computing one of EXP's operands.  */
2421
2422 static rtx
2423 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2424 {
2425   tree fndecl = get_callee_fndecl (exp);
2426   tree arg, type;
2427   enum machine_mode mode;
2428   rtx op0, op1, op2;
2429
2430   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2431     return NULL_RTX;
2432
2433   arg = CALL_EXPR_ARG (exp, 0);
2434   type = TREE_TYPE (arg);
2435   mode = TYPE_MODE (TREE_TYPE (arg));
2436
2437   /* Try expanding via a sincos optab, fall back to emitting a libcall
2438      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2439      is only generated from sincos, cexp or if we have either of them.  */
2440   if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
2441     {
2442       op1 = gen_reg_rtx (mode);
2443       op2 = gen_reg_rtx (mode);
2444
2445       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2446
2447       /* Compute into op1 and op2.  */
2448       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2449     }
2450   else if (TARGET_HAS_SINCOS)
2451     {
2452       tree call, fn = NULL_TREE;
2453       tree top1, top2;
2454       rtx op1a, op2a;
2455
2456       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2457         fn = built_in_decls[BUILT_IN_SINCOSF];
2458       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2459         fn = built_in_decls[BUILT_IN_SINCOS];
2460       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2461         fn = built_in_decls[BUILT_IN_SINCOSL];
2462       else
2463         gcc_unreachable ();
2464  
2465       op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2466       op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2467       op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2468       op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2469       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2470       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2471
2472       /* Make sure not to fold the sincos call again.  */
2473       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2474       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2475                                       call, 3, arg, top1, top2));
2476     }
2477   else
2478     {
2479       tree call, fn = NULL_TREE, narg;
2480       tree ctype = build_complex_type (type);
2481
2482       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2483         fn = built_in_decls[BUILT_IN_CEXPF];
2484       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2485         fn = built_in_decls[BUILT_IN_CEXP];
2486       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2487         fn = built_in_decls[BUILT_IN_CEXPL];
2488       else
2489         gcc_unreachable ();
2490
2491       /* If we don't have a decl for cexp create one.  This is the
2492          friendliest fallback if the user calls __builtin_cexpi
2493          without full target C99 function support.  */
2494       if (fn == NULL_TREE)
2495         {
2496           tree fntype;
2497           const char *name = NULL;
2498
2499           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2500             name = "cexpf";
2501           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2502             name = "cexp";
2503           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2504             name = "cexpl";
2505
2506           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2507           fn = build_fn_decl (name, fntype);
2508         }
2509
2510       narg = fold_build2 (COMPLEX_EXPR, ctype,
2511                           build_real (type, dconst0), arg);
2512
2513       /* Make sure not to fold the cexp call again.  */
2514       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2515       return expand_expr (build_call_nary (ctype, call, 1, narg), 
2516                           target, VOIDmode, EXPAND_NORMAL);
2517     }
2518
2519   /* Now build the proper return type.  */
2520   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2521                               make_tree (TREE_TYPE (arg), op2),
2522                               make_tree (TREE_TYPE (arg), op1)),
2523                       target, VOIDmode, EXPAND_NORMAL);
2524 }
2525
2526 /* Expand a call to one of the builtin rounding functions gcc defines
2527    as an extension (lfloor and lceil).  As these are gcc extensions we
2528    do not need to worry about setting errno to EDOM.
2529    If expanding via optab fails, lower expression to (int)(floor(x)).
2530    EXP is the expression that is a call to the builtin function;
2531    if convenient, the result should be placed in TARGET.  */
2532
2533 static rtx
2534 expand_builtin_int_roundingfn (tree exp, rtx target)
2535 {
2536   convert_optab builtin_optab;
2537   rtx op0, insns, tmp;
2538   tree fndecl = get_callee_fndecl (exp);
2539   enum built_in_function fallback_fn;
2540   tree fallback_fndecl;
2541   enum machine_mode mode;
2542   tree arg;
2543
2544   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2545     gcc_unreachable ();
2546
2547   arg = CALL_EXPR_ARG (exp, 0);
2548
2549   switch (DECL_FUNCTION_CODE (fndecl))
2550     {
2551     CASE_FLT_FN (BUILT_IN_LCEIL):
2552     CASE_FLT_FN (BUILT_IN_LLCEIL):
2553       builtin_optab = lceil_optab;
2554       fallback_fn = BUILT_IN_CEIL;
2555       break;
2556
2557     CASE_FLT_FN (BUILT_IN_LFLOOR):
2558     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2559       builtin_optab = lfloor_optab;
2560       fallback_fn = BUILT_IN_FLOOR;
2561       break;
2562
2563     default:
2564       gcc_unreachable ();
2565     }
2566
2567   /* Make a suitable register to place result in.  */
2568   mode = TYPE_MODE (TREE_TYPE (exp));
2569
2570   target = gen_reg_rtx (mode);
2571
2572   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2573      need to expand the argument again.  This way, we will not perform
2574      side-effects more the once.  */
2575   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2576
2577   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2578
2579   start_sequence ();
2580
2581   /* Compute into TARGET.  */
2582   if (expand_sfix_optab (target, op0, builtin_optab))
2583     {
2584       /* Output the entire sequence.  */
2585       insns = get_insns ();
2586       end_sequence ();
2587       emit_insn (insns);
2588       return target;
2589     }
2590
2591   /* If we were unable to expand via the builtin, stop the sequence
2592      (without outputting the insns).  */
2593   end_sequence ();
2594
2595   /* Fall back to floating point rounding optab.  */
2596   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2597
2598   /* For non-C99 targets we may end up without a fallback fndecl here
2599      if the user called __builtin_lfloor directly.  In this case emit
2600      a call to the floor/ceil variants nevertheless.  This should result
2601      in the best user experience for not full C99 targets.  */
2602   if (fallback_fndecl == NULL_TREE)
2603     {
2604       tree fntype;
2605       const char *name = NULL;
2606
2607       switch (DECL_FUNCTION_CODE (fndecl))
2608         {
2609         case BUILT_IN_LCEIL:
2610         case BUILT_IN_LLCEIL:
2611           name = "ceil";
2612           break;
2613         case BUILT_IN_LCEILF:
2614         case BUILT_IN_LLCEILF:
2615           name = "ceilf";
2616           break;
2617         case BUILT_IN_LCEILL:
2618         case BUILT_IN_LLCEILL:
2619           name = "ceill";
2620           break;
2621         case BUILT_IN_LFLOOR:
2622         case BUILT_IN_LLFLOOR:
2623           name = "floor";
2624           break;
2625         case BUILT_IN_LFLOORF:
2626         case BUILT_IN_LLFLOORF:
2627           name = "floorf";
2628           break;
2629         case BUILT_IN_LFLOORL:
2630         case BUILT_IN_LLFLOORL:
2631           name = "floorl";
2632           break;
2633         default:
2634           gcc_unreachable ();
2635         }
2636
2637       fntype = build_function_type_list (TREE_TYPE (arg),
2638                                          TREE_TYPE (arg), NULL_TREE);
2639       fallback_fndecl = build_fn_decl (name, fntype);
2640     }
2641
2642   exp = build_call_expr (fallback_fndecl, 1, arg);
2643
2644   tmp = expand_normal (exp);
2645
2646   /* Truncate the result of floating point optab to integer
2647      via expand_fix ().  */
2648   target = gen_reg_rtx (mode);
2649   expand_fix (target, tmp, 0);
2650
2651   return target;
2652 }
2653
2654 /* Expand a call to one of the builtin math functions doing integer
2655    conversion (lrint).
2656    Return 0 if a normal call should be emitted rather than expanding the
2657    function in-line.  EXP is the expression that is a call to the builtin
2658    function; if convenient, the result should be placed in TARGET.  */
2659
2660 static rtx
2661 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2662 {
2663   convert_optab builtin_optab;
2664   rtx op0, insns;
2665   tree fndecl = get_callee_fndecl (exp);
2666   tree arg;
2667   enum machine_mode mode;
2668
2669   /* There's no easy way to detect the case we need to set EDOM.  */
2670   if (flag_errno_math)
2671     return NULL_RTX;
2672
2673   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2674      gcc_unreachable ();
2675  
2676   arg = CALL_EXPR_ARG (exp, 0);
2677
2678   switch (DECL_FUNCTION_CODE (fndecl))
2679     {
2680     CASE_FLT_FN (BUILT_IN_LRINT):
2681     CASE_FLT_FN (BUILT_IN_LLRINT):
2682       builtin_optab = lrint_optab; break;
2683     CASE_FLT_FN (BUILT_IN_LROUND):
2684     CASE_FLT_FN (BUILT_IN_LLROUND):
2685       builtin_optab = lround_optab; break;
2686     default:
2687       gcc_unreachable ();
2688     }
2689
2690   /* Make a suitable register to place result in.  */
2691   mode = TYPE_MODE (TREE_TYPE (exp));
2692
2693   target = gen_reg_rtx (mode);
2694
2695   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2696      need to expand the argument again.  This way, we will not perform
2697      side-effects more the once.  */
2698   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2699
2700   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2701
2702   start_sequence ();
2703
2704   if (expand_sfix_optab (target, op0, builtin_optab))
2705     {
2706       /* Output the entire sequence.  */
2707       insns = get_insns ();
2708       end_sequence ();
2709       emit_insn (insns);
2710       return target;
2711     }
2712
2713   /* If we were unable to expand via the builtin, stop the sequence
2714      (without outputting the insns) and call to the library function
2715      with the stabilized argument list.  */
2716   end_sequence ();
2717
2718   target = expand_call (exp, target, target == const0_rtx);
2719
2720   return target;
2721 }
2722
2723 /* To evaluate powi(x,n), the floating point value x raised to the
2724    constant integer exponent n, we use a hybrid algorithm that
2725    combines the "window method" with look-up tables.  For an
2726    introduction to exponentiation algorithms and "addition chains",
2727    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2728    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2729    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2730    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2731
2732 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2733    multiplications to inline before calling the system library's pow
2734    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2735    so this default never requires calling pow, powf or powl.  */
2736
2737 #ifndef POWI_MAX_MULTS
2738 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2739 #endif
2740
2741 /* The size of the "optimal power tree" lookup table.  All
2742    exponents less than this value are simply looked up in the
2743    powi_table below.  This threshold is also used to size the
2744    cache of pseudo registers that hold intermediate results.  */
2745 #define POWI_TABLE_SIZE 256
2746
2747 /* The size, in bits of the window, used in the "window method"
2748    exponentiation algorithm.  This is equivalent to a radix of
2749    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2750 #define POWI_WINDOW_SIZE 3
2751
2752 /* The following table is an efficient representation of an
2753    "optimal power tree".  For each value, i, the corresponding
2754    value, j, in the table states than an optimal evaluation
2755    sequence for calculating pow(x,i) can be found by evaluating
2756    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2757    100 integers is given in Knuth's "Seminumerical algorithms".  */
2758
2759 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2760   {
2761       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2762       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2763       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2764      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2765      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2766      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2767      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2768      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2769      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2770      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2771      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2772      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2773      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2774      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2775      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2776      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2777      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2778      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2779      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2780      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2781      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2782      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2783      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2784      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2785      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2786     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2787     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2788     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2789     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2790     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2791     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2792     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2793   };
2794
2795
2796 /* Return the number of multiplications required to calculate
2797    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2798    subroutine of powi_cost.  CACHE is an array indicating
2799    which exponents have already been calculated.  */
2800
2801 static int
2802 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2803 {
2804   /* If we've already calculated this exponent, then this evaluation
2805      doesn't require any additional multiplications.  */
2806   if (cache[n])
2807     return 0;
2808
2809   cache[n] = true;
2810   return powi_lookup_cost (n - powi_table[n], cache)
2811          + powi_lookup_cost (powi_table[n], cache) + 1;
2812 }
2813
2814 /* Return the number of multiplications required to calculate
2815    powi(x,n) for an arbitrary x, given the exponent N.  This
2816    function needs to be kept in sync with expand_powi below.  */
2817
2818 static int
2819 powi_cost (HOST_WIDE_INT n)
2820 {
2821   bool cache[POWI_TABLE_SIZE];
2822   unsigned HOST_WIDE_INT digit;
2823   unsigned HOST_WIDE_INT val;
2824   int result;
2825
2826   if (n == 0)
2827     return 0;
2828
2829   /* Ignore the reciprocal when calculating the cost.  */
2830   val = (n < 0) ? -n : n;
2831
2832   /* Initialize the exponent cache.  */
2833   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2834   cache[1] = true;
2835
2836   result = 0;
2837
2838   while (val >= POWI_TABLE_SIZE)
2839     {
2840       if (val & 1)
2841         {
2842           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2843           result += powi_lookup_cost (digit, cache)
2844                     + POWI_WINDOW_SIZE + 1;
2845           val >>= POWI_WINDOW_SIZE;
2846         }
2847       else
2848         {
2849           val >>= 1;
2850           result++;
2851         }
2852     }
2853
2854   return result + powi_lookup_cost (val, cache);
2855 }
2856
2857 /* Recursive subroutine of expand_powi.  This function takes the array,
2858    CACHE, of already calculated exponents and an exponent N and returns
2859    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2860
2861 static rtx
2862 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2863 {
2864   unsigned HOST_WIDE_INT digit;
2865   rtx target, result;
2866   rtx op0, op1;
2867
2868   if (n < POWI_TABLE_SIZE)
2869     {
2870       if (cache[n])
2871         return cache[n];
2872
2873       target = gen_reg_rtx (mode);
2874       cache[n] = target;
2875
2876       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2877       op1 = expand_powi_1 (mode, powi_table[n], cache);
2878     }
2879   else if (n & 1)
2880     {
2881       target = gen_reg_rtx (mode);
2882       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2883       op0 = expand_powi_1 (mode, n - digit, cache);
2884       op1 = expand_powi_1 (mode, digit, cache);
2885     }
2886   else
2887     {
2888       target = gen_reg_rtx (mode);
2889       op0 = expand_powi_1 (mode, n >> 1, cache);
2890       op1 = op0;
2891     }
2892
2893   result = expand_mult (mode, op0, op1, target, 0);
2894   if (result != target)
2895     emit_move_insn (target, result);
2896   return target;
2897 }
2898
2899 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2900    floating point operand in mode MODE, and N is the exponent.  This
2901    function needs to be kept in sync with powi_cost above.  */
2902
2903 static rtx
2904 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2905 {
2906   unsigned HOST_WIDE_INT val;
2907   rtx cache[POWI_TABLE_SIZE];
2908   rtx result;
2909
2910   if (n == 0)
2911     return CONST1_RTX (mode);
2912
2913   val = (n < 0) ? -n : n;
2914
2915   memset (cache, 0, sizeof (cache));
2916   cache[1] = x;
2917
2918   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2919
2920   /* If the original exponent was negative, reciprocate the result.  */
2921   if (n < 0)
2922     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2923                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2924
2925   return result;
2926 }
2927
2928 /* Expand a call to the pow built-in mathematical function.  Return NULL_RTX if
2929    a normal call should be emitted rather than expanding the function
2930    in-line.  EXP is the expression that is a call to the builtin
2931    function; if convenient, the result should be placed in TARGET.  */
2932
2933 static rtx
2934 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2935 {
2936   tree arg0, arg1;
2937   tree fn, narg0;
2938   tree type = TREE_TYPE (exp);
2939   REAL_VALUE_TYPE cint, c, c2;
2940   HOST_WIDE_INT n;
2941   rtx op, op2;
2942   enum machine_mode mode = TYPE_MODE (type);
2943
2944   if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2945     return NULL_RTX;
2946
2947   arg0 = CALL_EXPR_ARG (exp, 0);
2948   arg1 = CALL_EXPR_ARG (exp, 1);
2949
2950   if (TREE_CODE (arg1) != REAL_CST
2951       || TREE_OVERFLOW (arg1))
2952     return expand_builtin_mathfn_2 (exp, target, subtarget);
2953
2954   /* Handle constant exponents.  */
2955
2956   /* For integer valued exponents we can expand to an optimal multiplication
2957      sequence using expand_powi.  */
2958   c = TREE_REAL_CST (arg1);
2959   n = real_to_integer (&c);
2960   real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2961   if (real_identical (&c, &cint)
2962       && ((n >= -1 && n <= 2)
2963           || (flag_unsafe_math_optimizations
2964               && optimize_insn_for_speed_p ()
2965               && powi_cost (n) <= POWI_MAX_MULTS)))
2966     {
2967       op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2968       if (n != 1)
2969         {
2970           op = force_reg (mode, op);
2971           op = expand_powi (op, mode, n);
2972         }
2973       return op;
2974     }
2975
2976   narg0 = builtin_save_expr (arg0);
2977
2978   /* If the exponent is not integer valued, check if it is half of an integer.
2979      In this case we can expand to sqrt (x) * x**(n/2).  */
2980   fn = mathfn_built_in (type, BUILT_IN_SQRT);
2981   if (fn != NULL_TREE)
2982     {
2983       real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2984       n = real_to_integer (&c2);
2985       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2986       if (real_identical (&c2, &cint)
2987           && ((flag_unsafe_math_optimizations
2988                && optimize_insn_for_speed_p ()
2989                && powi_cost (n/2) <= POWI_MAX_MULTS)
2990               || n == 1))
2991         {
2992           tree call_expr = build_call_expr (fn, 1, narg0);
2993           /* Use expand_expr in case the newly built call expression
2994              was folded to a non-call.  */
2995           op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
2996           if (n != 1)
2997             {
2998               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2999               op2 = force_reg (mode, op2);
3000               op2 = expand_powi (op2, mode, abs (n / 2));
3001               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3002                                         0, OPTAB_LIB_WIDEN);
3003               /* If the original exponent was negative, reciprocate the
3004                  result.  */
3005               if (n < 0)
3006                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3007                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3008             }
3009           return op;
3010         }
3011     }
3012
3013   /* Try if the exponent is a third of an integer.  In this case
3014      we can expand to x**(n/3) * cbrt(x)**(n%3).  As cbrt (x) is
3015      different from pow (x, 1./3.) due to rounding and behavior
3016      with negative x we need to constrain this transformation to
3017      unsafe math and positive x or finite math.  */
3018   fn = mathfn_built_in (type, BUILT_IN_CBRT);
3019   if (fn != NULL_TREE
3020       && flag_unsafe_math_optimizations
3021       && (tree_expr_nonnegative_p (arg0)
3022           || !HONOR_NANS (mode)))
3023     {
3024       REAL_VALUE_TYPE dconst3;
3025       real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
3026       real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3027       real_round (&c2, mode, &c2);
3028       n = real_to_integer (&c2);
3029       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3030       real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3031       real_convert (&c2, mode, &c2);
3032       if (real_identical (&c2, &c)
3033           && ((optimize_insn_for_speed_p ()
3034                && powi_cost (n/3) <= POWI_MAX_MULTS)
3035               || n == 1))
3036         {
3037           tree call_expr = build_call_expr (fn, 1,narg0);
3038           op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3039           if (abs (n) % 3 == 2)
3040             op = expand_simple_binop (mode, MULT, op, op, op,
3041                                       0, OPTAB_LIB_WIDEN);
3042           if (n != 1)
3043             {
3044               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
3045               op2 = force_reg (mode, op2);
3046               op2 = expand_powi (op2, mode, abs (n / 3));
3047               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3048                                         0, OPTAB_LIB_WIDEN);
3049               /* If the original exponent was negative, reciprocate the
3050                  result.  */
3051               if (n < 0)
3052                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3053                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3054             }
3055           return op;
3056         }
3057     }
3058
3059   /* Fall back to optab expansion.  */
3060   return expand_builtin_mathfn_2 (exp, target, subtarget);
3061 }
3062
3063 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
3064    a normal call should be emitted rather than expanding the function
3065    in-line.  EXP is the expression that is a call to the builtin
3066    function; if convenient, the result should be placed in TARGET.  */
3067
3068 static rtx
3069 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3070 {
3071   tree arg0, arg1;
3072   rtx op0, op1;
3073   enum machine_mode mode;
3074   enum machine_mode mode2;
3075
3076   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3077     return NULL_RTX;
3078
3079   arg0 = CALL_EXPR_ARG (exp, 0);
3080   arg1 = CALL_EXPR_ARG (exp, 1);
3081   mode = TYPE_MODE (TREE_TYPE (exp));
3082
3083   /* Handle constant power.  */
3084
3085   if (TREE_CODE (arg1) == INTEGER_CST
3086       && !TREE_OVERFLOW (arg1))
3087     {
3088       HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3089
3090       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3091          Otherwise, check the number of multiplications required.  */
3092       if ((TREE_INT_CST_HIGH (arg1) == 0
3093            || TREE_INT_CST_HIGH (arg1) == -1)
3094           && ((n >= -1 && n <= 2)
3095               || (optimize_insn_for_speed_p ()
3096                   && powi_cost (n) <= POWI_MAX_MULTS)))
3097         {
3098           op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
3099           op0 = force_reg (mode, op0);
3100           return expand_powi (op0, mode, n);
3101         }
3102     }
3103
3104   /* Emit a libcall to libgcc.  */
3105
3106   /* Mode of the 2nd argument must match that of an int.  */
3107   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3108
3109   if (target == NULL_RTX)
3110     target = gen_reg_rtx (mode);
3111
3112   op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
3113   if (GET_MODE (op0) != mode)
3114     op0 = convert_to_mode (mode, op0, 0);
3115   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
3116   if (GET_MODE (op1) != mode2)
3117     op1 = convert_to_mode (mode2, op1, 0);
3118
3119   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
3120                                     target, LCT_CONST, mode, 2,
3121                                     op0, mode, op1, mode2);
3122
3123   return target;
3124 }
3125
3126 /* Expand expression EXP which is a call to the strlen builtin.  Return 
3127    NULL_RTX if we failed the caller should emit a normal call, otherwise
3128    try to get the result in TARGET, if convenient.  */
3129
3130 static rtx
3131 expand_builtin_strlen (tree exp, rtx target,
3132                        enum machine_mode target_mode)
3133 {
3134   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3135     return NULL_RTX;
3136   else
3137     {
3138       rtx pat;
3139       tree len;
3140       tree src = CALL_EXPR_ARG (exp, 0);
3141       rtx result, src_reg, char_rtx, before_strlen;
3142       enum machine_mode insn_mode = target_mode, char_mode;
3143       enum insn_code icode = CODE_FOR_nothing;
3144       int align;
3145
3146       /* If the length can be computed at compile-time, return it.  */
3147       len = c_strlen (src, 0);
3148       if (len)
3149         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3150
3151       /* If the length can be computed at compile-time and is constant
3152          integer, but there are side-effects in src, evaluate
3153          src for side-effects, then return len.
3154          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3155          can be optimized into: i++; x = 3;  */
3156       len = c_strlen (src, 1);
3157       if (len && TREE_CODE (len) == INTEGER_CST)
3158         {
3159           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3160           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3161         }
3162
3163       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3164
3165       /* If SRC is not a pointer type, don't do this operation inline.  */
3166       if (align == 0)
3167         return NULL_RTX;
3168
3169       /* Bail out if we can't compute strlen in the right mode.  */
3170       while (insn_mode != VOIDmode)
3171         {
3172           icode = optab_handler (strlen_optab, insn_mode)->insn_code;
3173           if (icode != CODE_FOR_nothing)
3174             break;
3175
3176           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3177         }
3178       if (insn_mode == VOIDmode)
3179         return NULL_RTX;
3180
3181       /* Make a place to write the result of the instruction.  */
3182       result = target;
3183       if (! (result != 0
3184              && REG_P (result)
3185              && GET_MODE (result) == insn_mode
3186              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3187         result = gen_reg_rtx (insn_mode);
3188
3189       /* Make a place to hold the source address.  We will not expand
3190          the actual source until we are sure that the expansion will
3191          not fail -- there are trees that cannot be expanded twice.  */
3192       src_reg = gen_reg_rtx (Pmode);
3193
3194       /* Mark the beginning of the strlen sequence so we can emit the
3195          source operand later.  */
3196       before_strlen = get_last_insn ();
3197
3198       char_rtx = const0_rtx;
3199       char_mode = insn_data[(int) icode].operand[2].mode;
3200       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3201                                                             char_mode))
3202         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3203
3204       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3205                              char_rtx, GEN_INT (align));
3206       if (! pat)
3207         return NULL_RTX;
3208       emit_insn (pat);
3209
3210       /* Now that we are assured of success, expand the source.  */
3211       start_sequence ();
3212       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
3213       if (pat != src_reg)
3214         emit_move_insn (src_reg, pat);
3215       pat = get_insns ();
3216       end_sequence ();
3217
3218       if (before_strlen)
3219         emit_insn_after (pat, before_strlen);
3220       else
3221         emit_insn_before (pat, get_insns ());
3222
3223       /* Return the value in the proper mode for this function.  */
3224       if (GET_MODE (result) == target_mode)
3225         target = result;
3226       else if (target != 0)
3227         convert_move (target, result, 0);
3228       else
3229         target = convert_to_mode (target_mode, result, 0);
3230
3231       return target;
3232     }
3233 }
3234
3235 /* Expand a call to the strstr 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_strstr (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_strstr (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 /* Expand a call to the strchr builtin.  Return NULL_RTX if we failed the
3254    caller should emit a normal call, otherwise try to get the result
3255    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3256
3257 static rtx
3258 expand_builtin_strchr (tree exp, rtx target, enum machine_mode mode)
3259 {
3260   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3261     {
3262       tree type = TREE_TYPE (exp);
3263       tree result = fold_builtin_strchr (CALL_EXPR_ARG (exp, 0),
3264                                          CALL_EXPR_ARG (exp, 1), type);
3265       if (result)
3266         return expand_expr (result, target, mode, EXPAND_NORMAL);
3267
3268       /* FIXME: Should use strchrM optab so that ports can optimize this.  */
3269     }
3270   return NULL_RTX;
3271 }
3272
3273 /* Expand a call to the strrchr builtin.  Return NULL_RTX if we failed the
3274    caller should emit a normal call, otherwise try to get the result
3275    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3276
3277 static rtx
3278 expand_builtin_strrchr (tree exp, rtx target, enum machine_mode mode)
3279 {
3280   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3281     {
3282       tree type = TREE_TYPE (exp);
3283       tree result = fold_builtin_strrchr (CALL_EXPR_ARG (exp, 0),
3284                                           CALL_EXPR_ARG (exp, 1), type);
3285       if (result)
3286         return expand_expr (result, target, mode, EXPAND_NORMAL);
3287     }
3288   return NULL_RTX;
3289 }
3290
3291 /* Expand a call to the strpbrk builtin.  Return NULL_RTX if we failed the
3292    caller should emit a normal call, otherwise try to get the result
3293    in TARGET, if convenient (and in mode MODE if that's convenient).  */
3294
3295 static rtx
3296 expand_builtin_strpbrk (tree exp, rtx target, enum machine_mode mode)
3297 {
3298   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3299     {
3300       tree type = TREE_TYPE (exp);
3301       tree result = fold_builtin_strpbrk (CALL_EXPR_ARG (exp, 0),
3302                                           CALL_EXPR_ARG (exp, 1), type);
3303       if (result)
3304         return expand_expr (result, target, mode, EXPAND_NORMAL);
3305     }
3306   return NULL_RTX;
3307 }
3308
3309 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3310    bytes from constant string DATA + OFFSET and return it as target
3311    constant.  */
3312
3313 static rtx
3314 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3315                          enum machine_mode mode)
3316 {
3317   const char *str = (const char *) data;
3318
3319   gcc_assert (offset >= 0
3320               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3321                   <= strlen (str) + 1));
3322
3323   return c_readstr (str + offset, mode);
3324 }
3325
3326 /* Expand a call EXP to the memcpy builtin.
3327    Return NULL_RTX if we failed, the caller should emit a normal call,
3328    otherwise try to get the result in TARGET, if convenient (and in
3329    mode MODE if that's convenient).  */
3330
3331 static rtx
3332 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
3333 {
3334   tree fndecl = get_callee_fndecl (exp);
3335
3336   if (!validate_arglist (exp,
3337                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3338     return NULL_RTX;
3339   else
3340     {
3341       tree dest = CALL_EXPR_ARG (exp, 0);
3342       tree src = CALL_EXPR_ARG (exp, 1);
3343       tree len = CALL_EXPR_ARG (exp, 2);
3344       const char *src_str;
3345       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3346       unsigned int dest_align
3347         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3348       rtx dest_mem, src_mem, dest_addr, len_rtx;
3349       tree result = fold_builtin_memory_op (dest, src, len, 
3350                                             TREE_TYPE (TREE_TYPE (fndecl)),
3351                                             false, /*endp=*/0);
3352       HOST_WIDE_INT expected_size = -1;
3353       unsigned int expected_align = 0;
3354       tree_ann_common_t ann;
3355
3356       if (result)
3357         {
3358           while (TREE_CODE (result) == COMPOUND_EXPR)
3359             {
3360               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3361                            EXPAND_NORMAL);
3362               result = TREE_OPERAND (result, 1);
3363             }
3364           return expand_expr (result, target, mode, EXPAND_NORMAL);
3365         }
3366
3367       /* If DEST is not a pointer type, call the normal function.  */
3368       if (dest_align == 0)
3369         return NULL_RTX;
3370
3371       /* If either SRC is not a pointer type, don't do this
3372          operation in-line.  */
3373       if (src_align == 0)
3374         return NULL_RTX;
3375  
3376       ann = tree_common_ann (exp);
3377       if (ann)
3378         stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3379
3380       if (expected_align < dest_align)
3381         expected_align = dest_align;
3382       dest_mem = get_memory_rtx (dest, len);
3383       set_mem_align (dest_mem, dest_align);
3384       len_rtx = expand_normal (len);
3385       src_str = c_getstr (src);
3386
3387       /* If SRC is a string constant and block move would be done
3388          by pieces, we can avoid loading the string from memory
3389          and only stored the computed constants.  */
3390       if (src_str
3391           && GET_CODE (len_rtx) == CONST_INT
3392           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3393           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3394                                   CONST_CAST (char *, src_str),
3395                                   dest_align, false))
3396         {
3397           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3398                                       builtin_memcpy_read_str,
3399                                       CONST_CAST (char *, src_str),
3400                                       dest_align, false, 0);
3401           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3402           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3403           return dest_mem;
3404         }
3405
3406       src_mem = get_memory_rtx (src, len);
3407       set_mem_align (src_mem, src_align);
3408
3409       /* Copy word part most expediently.  */
3410       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3411                                          CALL_EXPR_TAILCALL (exp)
3412                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3413                                          expected_align, expected_size);
3414
3415       if (dest_addr == 0)
3416         {
3417           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3418           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3419         }
3420       return dest_addr;
3421     }
3422 }
3423
3424 /* Expand a call EXP to the mempcpy builtin.
3425    Return NULL_RTX if we failed; the caller should emit a normal call,
3426    otherwise try to get the result in TARGET, if convenient (and in
3427    mode MODE if that's convenient).  If ENDP is 0 return the
3428    destination pointer, if ENDP is 1 return the end pointer ala
3429    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3430    stpcpy.  */
3431
3432 static rtx
3433 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3434 {
3435   if (!validate_arglist (exp,
3436                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3437     return NULL_RTX;
3438   else
3439     {
3440       tree dest = CALL_EXPR_ARG (exp, 0);
3441       tree src = CALL_EXPR_ARG (exp, 1);
3442       tree len = CALL_EXPR_ARG (exp, 2);
3443       return expand_builtin_mempcpy_args (dest, src, len,
3444                                           TREE_TYPE (exp),
3445                                           target, mode, /*endp=*/ 1);
3446     }
3447 }
3448
3449 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3450    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3451    so that this can also be called without constructing an actual CALL_EXPR.
3452    TYPE is the return type of the call.  The other arguments and return value
3453    are the same as for expand_builtin_mempcpy.  */
3454
3455 static rtx
3456 expand_builtin_mempcpy_args (tree dest, tree src, tree len, tree type,
3457                              rtx target, enum machine_mode mode, int endp)
3458 {
3459     /* If return value is ignored, transform mempcpy into memcpy.  */
3460   if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
3461     {
3462       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3463       tree result = build_call_expr (fn, 3, dest, src, len);
3464
3465       while (TREE_CODE (result) == COMPOUND_EXPR)
3466         {
3467           expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3468                        EXPAND_NORMAL);
3469           result = TREE_OPERAND (result, 1);
3470         }
3471       return expand_expr (result, target, mode, EXPAND_NORMAL);
3472     }
3473   else
3474     {
3475       const char *src_str;
3476       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3477       unsigned int dest_align
3478         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3479       rtx dest_mem, src_mem, len_rtx;
3480       tree result = fold_builtin_memory_op (dest, src, len, type, false, endp);
3481
3482       if (result)
3483         {
3484           while (TREE_CODE (result) == COMPOUND_EXPR)
3485             {
3486               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3487                            EXPAND_NORMAL);
3488               result = TREE_OPERAND (result, 1);
3489             }
3490           return expand_expr (result, target, mode, EXPAND_NORMAL);
3491         }
3492
3493       /* If either SRC or DEST is not a pointer type, don't do this
3494          operation in-line.  */
3495       if (dest_align == 0 || src_align == 0)
3496         return NULL_RTX;
3497
3498       /* If LEN is not constant, call the normal function.  */
3499       if (! host_integerp (len, 1))
3500         return NULL_RTX;
3501
3502       len_rtx = expand_normal (len);
3503       src_str = c_getstr (src);
3504
3505       /* If SRC is a string constant and block move would be done
3506          by pieces, we can avoid loading the string from memory
3507          and only stored the computed constants.  */
3508       if (src_str
3509           && GET_CODE (len_rtx) == CONST_INT
3510           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3511           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3512                                   CONST_CAST (char *, src_str),
3513                                   dest_align, false))
3514         {
3515           dest_mem = get_memory_rtx (dest, len);
3516           set_mem_align (dest_mem, dest_align);
3517           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3518                                       builtin_memcpy_read_str,
3519                                       CONST_CAST (char *, src_str),
3520                                       dest_align, false, endp);
3521           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3522           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3523           return dest_mem;
3524         }
3525
3526       if (GET_CODE (len_rtx) == CONST_INT
3527           && can_move_by_pieces (INTVAL (len_rtx),
3528                                  MIN (dest_align, src_align)))
3529         {
3530           dest_mem = get_memory_rtx (dest, len);
3531           set_mem_align (dest_mem, dest_align);
3532           src_mem = get_memory_rtx (src, len);
3533           set_mem_align (src_mem, src_align);
3534           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3535                                      MIN (dest_align, src_align), endp);
3536           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3537           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3538           return dest_mem;
3539         }
3540
3541       return NULL_RTX;
3542     }
3543 }
3544
3545 /* Expand expression EXP, which is a call to the memmove builtin.  Return 
3546    NULL_RTX if we failed; the caller should emit a normal call.  */
3547
3548 static rtx
3549 expand_builtin_memmove (tree exp, rtx target, enum machine_mode mode, int ignore)
3550 {
3551   if (!validate_arglist (exp,
3552                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3553     return NULL_RTX;
3554   else
3555     {
3556       tree dest = CALL_EXPR_ARG (exp, 0);
3557       tree src = CALL_EXPR_ARG (exp, 1);
3558       tree len = CALL_EXPR_ARG (exp, 2);
3559       return expand_builtin_memmove_args (dest, src, len, TREE_TYPE (exp), 
3560                                           target, mode, ignore);
3561     }
3562 }
3563
3564 /* Helper function to do the actual work for expand_builtin_memmove.  The
3565    arguments to the builtin_memmove call DEST, SRC, and LEN are broken out
3566    so that this can also be called without constructing an actual CALL_EXPR.
3567    TYPE is the return type of the call.  The other arguments and return value
3568    are the same as for expand_builtin_memmove.  */
3569
3570 static rtx
3571 expand_builtin_memmove_args (tree dest, tree src, tree len,
3572                              tree type, rtx target, enum machine_mode mode, 
3573                              int ignore)
3574 {
3575   tree result = fold_builtin_memory_op (dest, src, len, type, ignore, /*endp=*/3);
3576
3577   if (result)
3578     {
3579       STRIP_TYPE_NOPS (result);
3580       while (TREE_CODE (result) == COMPOUND_EXPR)
3581         {
3582           expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3583                        EXPAND_NORMAL);
3584           result = TREE_OPERAND (result, 1);
3585         }
3586       return expand_expr (result, target, mode, EXPAND_NORMAL);
3587     }
3588   
3589   /* Otherwise, call the normal function.  */
3590   return NULL_RTX;
3591 }
3592
3593 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 
3594    NULL_RTX if we failed the caller should emit a normal call.  */
3595
3596 static rtx
3597 expand_builtin_bcopy (tree exp, int ignore)
3598 {
3599   tree type = TREE_TYPE (exp);
3600   tree src, dest, size;
3601
3602   if (!validate_arglist (exp,
3603                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3604     return NULL_RTX;
3605
3606   src = CALL_EXPR_ARG (exp, 0);
3607   dest = CALL_EXPR_ARG (exp, 1);
3608   size = CALL_EXPR_ARG (exp, 2);
3609
3610   /* Transform bcopy(ptr x, ptr y, int z) to memmove(ptr y, ptr x, size_t z).
3611      This is done this way so that if it isn't expanded inline, we fall
3612      back to calling bcopy instead of memmove.  */
3613   return expand_builtin_memmove_args (dest, src,
3614                                       fold_convert (sizetype, size),
3615                                       type, const0_rtx, VOIDmode, 
3616                                       ignore);
3617 }
3618
3619 #ifndef HAVE_movstr
3620 # define HAVE_movstr 0
3621 # define CODE_FOR_movstr CODE_FOR_nothing
3622 #endif
3623
3624 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3625    we failed, the caller should emit a normal call, otherwise try to
3626    get the result in TARGET, if convenient.  If ENDP is 0 return the
3627    destination pointer, if ENDP is 1 return the end pointer ala
3628    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3629    stpcpy.  */
3630
3631 static rtx
3632 expand_movstr (tree dest, tree src, rtx target, int endp)
3633 {
3634   rtx end;
3635   rtx dest_mem;
3636   rtx src_mem;
3637   rtx insn;
3638   const struct insn_data * data;
3639
3640   if (!HAVE_movstr)
3641     return NULL_RTX;
3642
3643   dest_mem = get_memory_rtx (dest, NULL);
3644   src_mem = get_memory_rtx (src, NULL);
3645   if (!endp)
3646     {
3647       target = force_reg (Pmode, XEXP (dest_mem, 0));
3648       dest_mem = replace_equiv_address (dest_mem, target);
3649       end = gen_reg_rtx (Pmode);
3650     }
3651   else
3652     {
3653       if (target == 0 || target == const0_rtx)
3654         {
3655           end = gen_reg_rtx (Pmode);
3656           if (target == 0)
3657             target = end;
3658         }
3659       else
3660         end = target;
3661     }
3662
3663   data = insn_data + CODE_FOR_movstr;
3664
3665   if (data->operand[0].mode != VOIDmode)
3666     end = gen_lowpart (data->operand[0].mode, end);
3667
3668   insn = data->genfun (end, dest_mem, src_mem);
3669
3670   gcc_assert (insn);
3671
3672   emit_insn (insn);
3673
3674   /* movstr is supposed to set end to the address of the NUL
3675      terminator.  If the caller requested a mempcpy-like return value,
3676      adjust it.  */
3677   if (endp == 1 && target != const0_rtx)
3678     {
3679       rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3680       emit_move_insn (target, force_operand (tem, NULL_RTX));
3681     }
3682
3683   return target;
3684 }
3685
3686 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 
3687    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3688    try to get the result in TARGET, if convenient (and in mode MODE if that's
3689    convenient).  */
3690
3691 static rtx
3692 expand_builtin_strcpy (tree fndecl, tree exp, rtx target, enum machine_mode mode)
3693 {
3694   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3695    {
3696      tree dest = CALL_EXPR_ARG (exp, 0);
3697      tree src = CALL_EXPR_ARG (exp, 1);
3698      return expand_builtin_strcpy_args (fndecl, dest, src, target, mode);
3699    }
3700    return NULL_RTX;
3701 }
3702
3703 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3704    arguments to the builtin_strcpy call DEST and SRC are broken out
3705    so that this can also be called without constructing an actual CALL_EXPR.
3706    The other arguments and return value are the same as for
3707    expand_builtin_strcpy.  */
3708
3709 static rtx
3710 expand_builtin_strcpy_args (tree fndecl, tree dest, tree src,
3711                             rtx target, enum machine_mode mode)
3712 {
3713   tree result = fold_builtin_strcpy (fndecl, dest, src, 0);
3714   if (result)
3715     return expand_expr (result, target, mode, EXPAND_NORMAL);
3716   return expand_movstr (dest, src, target, /*endp=*/0);
3717
3718 }
3719
3720 /* Expand a call EXP to the stpcpy builtin.
3721    Return NULL_RTX if we failed the caller should emit a normal call,
3722    otherwise try to get the result in TARGET, if convenient (and in
3723    mode MODE if that's convenient).  */
3724
3725 static rtx
3726 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3727 {
3728   tree dst, src;
3729
3730   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3731     return NULL_RTX;
3732
3733   dst = CALL_EXPR_ARG (exp, 0);
3734   src = CALL_EXPR_ARG (exp, 1);
3735
3736   /* If return value is ignored, transform stpcpy into strcpy.  */
3737   if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
3738     {
3739       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3740       tree result = build_call_expr (fn, 2, dst, src);
3741
3742       STRIP_NOPS (result);
3743       while (TREE_CODE (result) == COMPOUND_EXPR)
3744         {
3745           expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3746                        EXPAND_NORMAL);
3747           result = TREE_OPERAND (result, 1);
3748         }
3749       return expand_expr (result, target, mode, EXPAND_NORMAL);
3750     }
3751   else
3752     {
3753       tree len, lenp1;
3754       rtx ret;
3755
3756       /* Ensure we get an actual string whose length can be evaluated at
3757          compile-time, not an expression containing a string.  This is
3758          because the latter will potentially produce pessimized code
3759          when used to produce the return value.  */
3760       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3761         return expand_movstr (dst, src, target, /*endp=*/2);
3762
3763       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3764       ret = expand_builtin_mempcpy_args (dst, src, lenp1, TREE_TYPE (exp),
3765                                          target, mode, /*endp=*/2);
3766
3767       if (ret)
3768         return ret;
3769
3770       if (TREE_CODE (len) == INTEGER_CST)
3771         {
3772           rtx len_rtx = expand_normal (len);
3773
3774           if (GET_CODE (len_rtx) == CONST_INT)
3775             {
3776               ret = expand_builtin_strcpy_args (get_callee_fndecl (exp),
3777                                                 dst, src, target, mode);
3778
3779               if (ret)
3780                 {
3781                   if (! target)
3782                     {
3783                       if (mode != VOIDmode)
3784                         target = gen_reg_rtx (mode);
3785                       else
3786                         target = gen_reg_rtx (GET_MODE (ret));
3787                     }
3788                   if (GET_MODE (target) != GET_MODE (ret))
3789                     ret = gen_lowpart (GET_MODE (target), ret);
3790
3791                   ret = plus_constant (ret, INTVAL (len_rtx));
3792                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3793                   gcc_assert (ret);
3794
3795                   return target;
3796                 }
3797             }
3798         }
3799
3800       return expand_movstr (dst, src, target, /*endp=*/2);
3801     }
3802 }
3803
3804 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3805    bytes from constant string DATA + OFFSET and return it as target
3806    constant.  */
3807
3808 rtx
3809 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3810                           enum machine_mode mode)
3811 {
3812   const char *str = (const char *) data;
3813
3814   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3815     return const0_rtx;
3816
3817   return c_readstr (str + offset, mode);
3818 }
3819
3820 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 
3821    NULL_RTX if we failed the caller should emit a normal call.  */
3822
3823 static rtx
3824 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3825 {
3826   tree fndecl = get_callee_fndecl (exp);
3827
3828   if (validate_arglist (exp,
3829                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3830     {
3831       tree dest = CALL_EXPR_ARG (exp, 0);
3832       tree src = CALL_EXPR_ARG (exp, 1);
3833       tree len = CALL_EXPR_ARG (exp, 2);
3834       tree slen = c_strlen (src, 1);
3835       tree result = fold_builtin_strncpy (fndecl, dest, src, len, slen);
3836
3837       if (result)
3838         {
3839           while (TREE_CODE (result) == COMPOUND_EXPR)
3840             {
3841               expand_expr (TREE_OPERAND (result, 0), const0_rtx, VOIDmode,
3842                            EXPAND_NORMAL);
3843               result = TREE_OPERAND (result, 1);
3844             }
3845           return expand_expr (result, target, mode, EXPAND_NORMAL);
3846         }
3847
3848       /* We must be passed a constant len and src parameter.  */
3849       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3850         return NULL_RTX;
3851
3852       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3853
3854       /* We're required to pad with trailing zeros if the requested
3855          len is greater than strlen(s2)+1.  In that case try to
3856          use store_by_pieces, if it fails, punt.  */
3857       if (tree_int_cst_lt (slen, len))
3858         {
3859           unsigned int dest_align
3860             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3861           const char *p = c_getstr (src);
3862           rtx dest_mem;
3863
3864           if (!p || dest_align == 0 || !host_integerp (len, 1)
3865               || !can_store_by_pieces (tree_low_cst (len, 1),
3866                                        builtin_strncpy_read_str,
3867                                        CONST_CAST (char *, p),
3868                                        dest_align, false))
3869             return NULL_RTX;
3870
3871           dest_mem = get_memory_rtx (dest, len);
3872           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3873                            builtin_strncpy_read_str,
3874                            CONST_CAST (char *, p), dest_align, false, 0);
3875           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3876           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3877           return dest_mem;
3878         }
3879     }
3880   return NULL_RTX;
3881 }
3882
3883 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3884    bytes from constant string DATA + OFFSET and return it as target
3885    constant.  */
3886
3887 rtx
3888 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3889                          enum machine_mode mode)
3890 {
3891   const char *c = (const char *) data;
3892   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3893
3894   memset (p, *c, GET_MODE_SIZE (mode));
3895
3896   return c_readstr (p, mode);
3897 }
3898
3899 /* Callback routine for store_by_pieces.  Return the RTL of a register
3900    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3901    char value given in the RTL register data.  For example, if mode is
3902    4 bytes wide, return the RTL for 0x01010101*data.  */
3903
3904 static rtx
3905 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3906                         enum machine_mode mode)
3907 {
3908   rtx target, coeff;
3909   size_t size;
3910   char *p;
3911
3912   size = GET_MODE_SIZE (mode);
3913   if (size == 1)
3914     return (rtx) data;
3915
3916   p = XALLOCAVEC (char, size);
3917   memset (p, 1, size);
3918   coeff = c_readstr (p, mode);
3919
3920   target = convert_to_mode (mode, (rtx) data, 1);
3921   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3922   return force_reg (mode, target);
3923 }
3924
3925 /* Expand expression EXP, which is a call to the memset builtin.  Return 
3926    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3927    try to get the result in TARGET, if convenient (and in mode MODE if that's
3928    convenient).  */
3929
3930 static rtx
3931 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3932 {
3933   if (!validate_arglist (exp,
3934                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3935     return NULL_RTX;
3936   else
3937     {
3938       tree dest = CALL_EXPR_ARG (exp, 0);
3939       tree val = CALL_EXPR_ARG (exp, 1);
3940       tree len = CALL_EXPR_ARG (exp, 2);
3941       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3942     }
3943 }
3944
3945 /* Helper function to do the actual work for expand_builtin_memset.  The
3946    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3947    so that this can also be called without constructing an actual CALL_EXPR.
3948    The other arguments and return value are the same as for
3949    expand_builtin_memset.  */
3950
3951 static rtx
3952 expand_builtin_memset_args (tree dest, tree val, tree len,
3953                             rtx target, enum machine_mode mode, tree orig_exp)
3954 {
3955   tree fndecl, fn;
3956   enum built_in_function fcode;
3957   char c;
3958   unsigned int dest_align;
3959   rtx dest_mem, dest_addr, len_rtx;
3960   HOST_WIDE_INT expected_size = -1;
3961   unsigned int expected_align = 0;
3962   tree_ann_common_t ann;
3963
3964   dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3965
3966   /* If DEST is not a pointer type, don't do this operation in-line.  */
3967   if (dest_align == 0)
3968     return NULL_RTX;
3969
3970   ann = tree_common_ann (orig_exp);
3971   if (ann)
3972     stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3973
3974   if (expected_align < dest_align)
3975     expected_align = dest_align;
3976
3977   /* If the LEN parameter is zero, return DEST.  */
3978   if (integer_zerop (len))
3979     {
3980       /* Evaluate and ignore VAL in case it has side-effects.  */
3981       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3982       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3983     }
3984
3985   /* Stabilize the arguments in case we fail.  */
3986   dest = builtin_save_expr (dest);
3987   val = builtin_save_expr (val);
3988   len = builtin_save_expr (len);
3989
3990   len_rtx = expand_normal (len);
3991   dest_mem = get_memory_rtx (dest, len);
3992
3993   if (TREE_CODE (val) != INTEGER_CST)
3994     {
3995       rtx val_rtx;
3996
3997       val_rtx = expand_normal (val);
3998       val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3999                                  val_rtx, 0);
4000
4001       /* Assume that we can memset by pieces if we can store
4002        * the coefficients by pieces (in the required modes).
4003        * We can't pass builtin_memset_gen_str as that emits RTL.  */
4004       c = 1;
4005       if (host_integerp (len, 1)
4006           && can_store_by_pieces (tree_low_cst (len, 1),
4007                                   builtin_memset_read_str, &c, dest_align,
4008                                   true))
4009         {
4010           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
4011                                val_rtx);
4012           store_by_pieces (dest_mem, tree_low_cst (len, 1),
4013                            builtin_memset_gen_str, val_rtx, dest_align,
4014                            true, 0);
4015         }
4016       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
4017                                         dest_align, expected_align,
4018                                         expected_size))
4019         goto do_libcall;
4020       
4021       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4022       dest_mem = convert_memory_address (ptr_mode, dest_mem);
4023       return dest_mem;
4024     }
4025
4026   if (target_char_cast (val, &c))
4027     goto do_libcall;
4028
4029   if (c)
4030     {
4031       if (host_integerp (len, 1)
4032           && can_store_by_pieces (tree_low_cst (len, 1),
4033                                   builtin_memset_read_str, &c, dest_align,
4034                                   true))
4035         store_by_pieces (dest_mem, tree_low_cst (len, 1),
4036                          builtin_memset_read_str, &c, dest_align, true, 0);
4037       else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
4038                                         dest_align, expected_align,
4039                                         expected_size))
4040         goto do_libcall;
4041       
4042       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4043       dest_mem = convert_memory_address (ptr_mode, dest_mem);
4044       return dest_mem;
4045     }
4046
4047   set_mem_align (dest_mem, dest_align);
4048   dest_addr = clear_storage_hints (dest_mem, len_rtx,
4049                                    CALL_EXPR_TAILCALL (orig_exp)
4050                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
4051                                    expected_align, expected_size);
4052
4053   if (dest_addr == 0)
4054     {
4055       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
4056       dest_addr = convert_memory_address (ptr_mode, dest_addr);
4057     }
4058
4059   return dest_addr;
4060
4061  do_libcall:
4062   fndecl = get_callee_fndecl (orig_exp);
4063   fcode = DECL_FUNCTION_CODE (fndecl);
4064   if (fcode == BUILT_IN_MEMSET)
4065     fn = build_call_expr (fndecl, 3, dest, val, len);
4066   else if (fcode == BUILT_IN_BZERO)
4067     fn = build_call_expr (fndecl, 2, dest, len);
4068   else
4069     gcc_unreachable ();
4070   if (TREE_CODE (fn) == CALL_EXPR)
4071     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
4072   return expand_call (fn, target, target == const0_rtx);
4073 }
4074
4075 /* Expand expression EXP, which is a call to the bzero builtin.  Return 
4076    NULL_RTX if we failed the caller should emit a normal call.  */
4077
4078 static rtx
4079 expand_builtin_bzero (tree exp)
4080 {
4081   tree dest, size;
4082
4083   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4084     return NULL_RTX;
4085
4086   dest = CALL_EXPR_ARG (exp, 0);
4087   size = CALL_EXPR_ARG (exp, 1);
4088
4089   /* New argument list transforming bzero(ptr x, int y) to
4090      memset(ptr x, int 0, size_t y).   This is done this way
4091      so that if it isn't expanded inline, we fallback to
4092      calling bzero instead of memset.  */
4093
4094   return expand_builtin_memset_args (dest, integer_zero_node,
4095                                      fold_convert (sizetype, size),
4096                                      const0_rtx, VOIDmode, exp);
4097 }
4098
4099 /* Expand a call to the memchr builtin.  Return NULL_RTX if we failed the
4100    caller should emit a normal call, otherwise try to get the result
4101    in TARGET, if convenient (and in mode MODE if that's convenient).  */
4102
4103 static rtx
4104 expand_builtin_memchr (tree exp, rtx target, enum machine_mode mode)
4105 {
4106   if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE,
4107                         INTEGER_TYPE, VOID_TYPE))
4108     {
4109       tree type = TREE_TYPE (exp);
4110       tree result = fold_builtin_memchr (CALL_EXPR_ARG (exp, 0),
4111                                          CALL_EXPR_ARG (exp, 1),
4112                                          CALL_EXPR_ARG (exp, 2), type);
4113       if (result)
4114         return expand_expr (result, target, mode, EXPAND_NORMAL);
4115     }
4116   return NULL_RTX;
4117 }
4118
4119 /* Expand expression EXP, which is a call to the memcmp built-in function.
4120    Return NULL_RTX if we failed and the
4121    caller should emit a normal call, otherwise try to get the result in
4122    TARGET, if convenient (and in mode MODE, if that's convenient).  */
4123
4124 static rtx
4125 expand_builtin_memcmp (tree exp, rtx target, enum machine_mode mode)
4126 {
4127   if (!validate_arglist (exp,
4128                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4129     return NULL_RTX;
4130   else
4131     {
4132       tree result = fold_builtin_memcmp (CALL_EXPR_ARG (exp, 0),
4133                                          CALL_EXPR_ARG (exp, 1),
4134                                          CALL_EXPR_ARG (exp, 2));
4135       if (result)
4136         return expand_expr (result, target, mode, EXPAND_NORMAL);
4137     }
4138
4139 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
4140   {
4141     rtx arg1_rtx, arg2_rtx, arg3_rtx;
4142     rtx result;
4143     rtx insn;
4144     tree arg1 = CALL_EXPR_ARG (exp, 0);
4145     tree arg2 = CALL_EXPR_ARG (exp, 1);
4146     tree len = CALL_EXPR_ARG (exp, 2);
4147
4148     int arg1_align
4149       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4150     int arg2_align
4151       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4152     enum machine_mode insn_mode;
4153
4154 #ifdef HAVE_cmpmemsi
4155     if (HAVE_cmpmemsi)
4156       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
4157     else
4158 #endif
4159 #ifdef HAVE_cmpstrnsi
4160     if (HAVE_cmpstrnsi)
4161       insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4162     else
4163 #endif
4164       return NULL_RTX;
4165
4166     /* If we don't have POINTER_TYPE, call the function.  */
4167     if (arg1_align == 0 || arg2_align == 0)
4168       return NULL_RTX;
4169
4170     /* Make a place to write the result of the instruction.  */
4171     result = target;
4172     if (! (result != 0
4173            && REG_P (result) && GET_MODE (result) == insn_mode
4174            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4175       result = gen_reg_rtx (insn_mode);
4176
4177     arg1_rtx = get_memory_rtx (arg1, len);
4178     arg2_rtx = get_memory_rtx (arg2, len);
4179     arg3_rtx = expand_normal (len);
4180
4181     /* Set MEM_SIZE as appropriate.  */
4182     if (GET_CODE (arg3_rtx) == CONST_INT)
4183       {
4184         set_mem_size (arg1_rtx, arg3_rtx);
4185         set_mem_size (arg2_rtx, arg3_rtx);
4186       }
4187
4188 #ifdef HAVE_cmpmemsi
4189     if (HAVE_cmpmemsi)
4190       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4191                            GEN_INT (MIN (arg1_align, arg2_align)));
4192     else
4193 #endif
4194 #ifdef HAVE_cmpstrnsi
4195     if (HAVE_cmpstrnsi)
4196       insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4197                             GEN_INT (MIN (arg1_align, arg2_align)));
4198     else
4199 #endif
4200       gcc_unreachable ();
4201
4202     if (insn)
4203       emit_insn (insn);
4204     else
4205       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
4206                                TYPE_MODE (integer_type_node), 3,
4207                                XEXP (arg1_rtx, 0), Pmode,
4208                                XEXP (arg2_rtx, 0), Pmode,
4209                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
4210                                                 TYPE_UNSIGNED (sizetype)),
4211                                TYPE_MODE (sizetype));
4212
4213     /* Return the value in the proper mode for this function.  */
4214     mode = TYPE_MODE (TREE_TYPE (exp));
4215     if (GET_MODE (result) == mode)
4216       return result;
4217     else if (target != 0)
4218       {
4219         convert_move (target, result, 0);
4220         return target;
4221       }
4222     else
4223       return convert_to_mode (mode, result, 0);
4224   }
4225 #endif
4226
4227   return NULL_RTX;
4228 }
4229
4230 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
4231    if we failed the caller should emit a normal call, otherwise try to get
4232    the result in TARGET, if convenient.  */
4233
4234 static rtx
4235 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
4236 {
4237   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4238     return NULL_RTX;
4239   else
4240     {
4241       tree result = fold_builtin_strcmp (CALL_EXPR_ARG (exp, 0),
4242                                          CALL_EXPR_ARG (exp, 1));
4243       if (result)
4244         return expand_expr (result, target, mode, EXPAND_NORMAL);
4245     }
4246
4247 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
4248   if (cmpstr_optab[SImode] != CODE_FOR_nothing
4249       || cmpstrn_optab[SImode] != CODE_FOR_nothing)
4250     {
4251       rtx arg1_rtx, arg2_rtx;
4252       rtx result, insn = NULL_RTX;
4253       tree fndecl, fn;
4254       tree arg1 = CALL_EXPR_ARG (exp, 0);
4255       tree arg2 = CALL_EXPR_ARG (exp, 1);
4256
4257       int arg1_align
4258         = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4259       int arg2_align
4260         = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4261
4262       /* If we don't have POINTER_TYPE, call the function.  */
4263       if (arg1_align == 0 || arg2_align == 0)
4264         return NULL_RTX;
4265
4266       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
4267       arg1 = builtin_save_expr (arg1);
4268       arg2 = builtin_save_expr (arg2);
4269
4270       arg1_rtx = get_memory_rtx (arg1, NULL);
4271       arg2_rtx = get_memory_rtx (arg2, NULL);
4272
4273 #ifdef HAVE_cmpstrsi
4274       /* Try to call cmpstrsi.  */
4275       if (HAVE_cmpstrsi)
4276         {
4277           enum machine_mode insn_mode
4278             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4279
4280           /* Make a place to write the result of the instruction.  */
4281           result = target;
4282           if (! (result != 0
4283                  && REG_P (result) && GET_MODE (result) == insn_mode
4284                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4285             result = gen_reg_rtx (insn_mode);
4286
4287           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4288                                GEN_INT (MIN (arg1_align, arg2_align)));
4289         }
4290 #endif
4291 #ifdef HAVE_cmpstrnsi
4292       /* Try to determine at least one length and call cmpstrnsi.  */
4293       if (!insn && HAVE_cmpstrnsi)
4294         {
4295           tree len;
4296           rtx arg3_rtx;
4297
4298           enum machine_mode insn_mode
4299             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4300           tree len1 = c_strlen (arg1, 1);
4301           tree len2 = c_strlen (arg2, 1);
4302
4303           if (len1)
4304             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4305           if (len2)
4306             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4307
4308           /* If we don't have a constant length for the first, use the length
4309              of the second, if we know it.  We don't require a constant for
4310              this case; some cost analysis could be done if both are available
4311              but neither is constant.  For now, assume they're equally cheap,
4312              unless one has side effects.  If both strings have constant lengths,
4313              use the smaller.  */
4314
4315           if (!len1)
4316             len = len2;
4317           else if (!len2)
4318             len = len1;
4319           else if (TREE_SIDE_EFFECTS (len1))
4320             len = len2;
4321           else if (TREE_SIDE_EFFECTS (len2))
4322             len = len1;
4323           else if (TREE_CODE (len1) != INTEGER_CST)
4324             len = len2;
4325           else if (TREE_CODE (len2) != INTEGER_CST)
4326             len = len1;
4327           else if (tree_int_cst_lt (len1, len2))
4328             len = len1;
4329           else
4330             len = len2;
4331
4332           /* If both arguments have side effects, we cannot optimize.  */
4333           if (!len || TREE_SIDE_EFFECTS (len))
4334             goto do_libcall;
4335
4336           arg3_rtx = expand_normal (len);
4337
4338           /* Make a place to write the result of the instruction.  */
4339           result = target;
4340           if (! (result != 0
4341                  && REG_P (result) && GET_MODE (result) == insn_mode
4342                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4343             result = gen_reg_rtx (insn_mode);
4344
4345           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4346                                 GEN_INT (MIN (arg1_align, arg2_align)));
4347         }
4348 #endif
4349
4350       if (insn)
4351         {
4352           emit_insn (insn);
4353
4354           /* Return the value in the proper mode for this function.  */
4355           mode = TYPE_MODE (TREE_TYPE (exp));
4356           if (GET_MODE (result) == mode)
4357             return result;
4358           if (target == 0)
4359             return convert_to_mode (mode, result, 0);
4360           convert_move (target, result, 0);
4361           return target;
4362         }
4363
4364       /* Expand the library call ourselves using a stabilized argument
4365          list to avoid re-evaluating the function's arguments twice.  */
4366 #ifdef HAVE_cmpstrnsi
4367     do_libcall:
4368 #endif
4369       fndecl = get_callee_fndecl (exp);
4370       fn = build_call_expr (fndecl, 2, arg1, arg2);
4371       if (TREE_CODE (fn) == CALL_EXPR)
4372         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4373       return expand_call (fn, target, target == const0_rtx);
4374     }
4375 #endif
4376   return NULL_RTX;
4377 }
4378
4379 /* Expand expression EXP, which is a call to the strncmp builtin. Return 
4380    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
4381    the result in TARGET, if convenient.  */
4382
4383 static rtx
4384 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
4385 {
4386   if (!validate_arglist (exp,
4387                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4388     return NULL_RTX;
4389   else
4390     {
4391       tree result = fold_builtin_strncmp (CALL_EXPR_ARG (exp, 0),
4392                                           CALL_EXPR_ARG (exp, 1),
4393                                           CALL_EXPR_ARG (exp, 2));
4394       if (result)
4395         return expand_expr (result, target, mode, EXPAND_NORMAL);
4396     }
4397
4398   /* If c_strlen can determine an expression for one of the string
4399      lengths, and it doesn't have side effects, then emit cmpstrnsi
4400      using length MIN(strlen(string)+1, arg3).  */
4401 #ifdef HAVE_cmpstrnsi
4402   if (HAVE_cmpstrnsi)
4403   {
4404     tree len, len1, len2;
4405     rtx arg1_rtx, arg2_rtx, arg3_rtx;
4406     rtx result, insn;
4407     tree fndecl, fn;
4408     tree arg1 = CALL_EXPR_ARG (exp, 0);
4409     tree arg2 = CALL_EXPR_ARG (exp, 1);
4410     tree arg3 = CALL_EXPR_ARG (exp, 2);
4411
4412     int arg1_align
4413       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4414     int arg2_align
4415       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4416     enum machine_mode insn_mode
4417       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4418
4419     len1 = c_strlen (arg1, 1);
4420     len2 = c_strlen (arg2, 1);
4421
4422     if (len1)
4423       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4424     if (len2)
4425       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4426
4427     /* If we don't have a constant length for the first, use the length
4428        of the second, if we know it.  We don't require a constant for
4429        this case; some cost analysis could be done if both are available
4430        but neither is constant.  For now, assume they're equally cheap,
4431        unless one has side effects.  If both strings have constant lengths,
4432        use the smaller.  */
4433
4434     if (!len1)
4435       len = len2;
4436     else if (!len2)
4437       len = len1;
4438     else if (TREE_SIDE_EFFECTS (len1))
4439       len = len2;
4440     else if (TREE_SIDE_EFFECTS (len2))
4441       len = len1;
4442     else if (TREE_CODE (len1) != INTEGER_CST)
4443       len = len2;
4444     else if (TREE_CODE (len2) != INTEGER_CST)
4445       len = len1;
4446     else if (tree_int_cst_lt (len1, len2))
4447       len = len1;
4448     else
4449       len = len2;
4450
4451     /* If both arguments have side effects, we cannot optimize.  */
4452     if (!len || TREE_SIDE_EFFECTS (len))
4453       return NULL_RTX;
4454
4455     /* The actual new length parameter is MIN(len,arg3).  */
4456     len = fold_build2 (MIN_EXPR, TREE_TYPE (len), len,
4457                        fold_convert (TREE_TYPE (len), arg3));
4458
4459     /* If we don't have POINTER_TYPE, call the function.  */
4460     if (arg1_align == 0 || arg2_align == 0)
4461       return NULL_RTX;
4462
4463     /* Make a place to write the result of the instruction.  */
4464     result = target;
4465     if (! (result != 0
4466            && REG_P (result) && GET_MODE (result) == insn_mode
4467            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4468       result = gen_reg_rtx (insn_mode);
4469
4470     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
4471     arg1 = builtin_save_expr (arg1);
4472     arg2 = builtin_save_expr (arg2);
4473     len = builtin_save_expr (len);
4474
4475     arg1_rtx = get_memory_rtx (arg1, len);
4476     arg2_rtx = get_memory_rtx (arg2, len);
4477     arg3_rtx = expand_normal (len);
4478     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4479                           GEN_INT (MIN (arg1_align, arg2_align)));
4480     if (insn)
4481       {
4482         emit_insn (insn);
4483
4484         /* Return the value in the proper mode for this function.  */
4485         mode = TYPE_MODE (TREE_TYPE (exp));
4486         if (GET_MODE (result) == mode)
4487           return result;
4488         if (target == 0)
4489           return convert_to_mode (mode, result, 0);
4490         convert_move (target, result, 0);
4491         return target;
4492       }
4493
4494     /* Expand the library call ourselves using a stabilized argument
4495        list to avoid re-evaluating the function's arguments twice.  */
4496     fndecl = get_callee_fndecl (exp);
4497     fn = build_call_expr (fndecl, 3, arg1, arg2, len);
4498     if (TREE_CODE (fn) == CALL_EXPR)
4499       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4500     return expand_call (fn, target, target == const0_rtx);
4501   }
4502 #endif
4503   return NULL_RTX;
4504 }
4505
4506 /* Expand expression EXP, which is a call to the strcat 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_strcat (tree fndecl, tree exp, rtx target, enum machine_mode mode)
4512 {
4513   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4514     return NULL_RTX;
4515   else
4516     {
4517       tree dst = CALL_EXPR_ARG (exp, 0);
4518       tree src = CALL_EXPR_ARG (exp, 1);
4519       const char *p = c_getstr (src);
4520
4521       /* If the string length is zero, return the dst parameter.  */
4522       if (p && *p == '\0')
4523         return expand_expr (dst, target, mode, EXPAND_NORMAL);
4524
4525       if (optimize_insn_for_speed_p ())
4526         {
4527           /* See if we can store by pieces into (dst + strlen(dst)).  */
4528           tree newsrc, newdst,
4529             strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4530           rtx insns;
4531
4532           /* Stabilize the argument list.  */
4533           newsrc = builtin_save_expr (src);
4534           dst = builtin_save_expr (dst);
4535
4536           start_sequence ();
4537
4538           /* Create strlen (dst).  */
4539           newdst = build_call_expr (strlen_fn, 1, dst);
4540           /* Create (dst p+ strlen (dst)).  */
4541
4542           newdst = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dst), dst, newdst);
4543           newdst = builtin_save_expr (newdst);
4544
4545           if (!expand_builtin_strcpy_args (fndecl, newdst, newsrc, target, mode))
4546             {
4547               end_sequence (); /* Stop sequence.  */
4548               return NULL_RTX;
4549             }
4550
4551           /* Output the entire sequence.  */
4552           insns = get_insns ();
4553           end_sequence ();
4554           emit_insn (insns);
4555
4556           return expand_expr (dst, target, mode, EXPAND_NORMAL);
4557         }
4558
4559       return NULL_RTX;
4560     }
4561 }
4562
4563 /* Expand expression EXP, which is a call to the strncat builtin.
4564    Return NULL_RTX if we failed the caller should emit a normal call,
4565    otherwise try to get the result in TARGET, if convenient.  */
4566
4567 static rtx
4568 expand_builtin_strncat (tree exp, rtx target, enum machine_mode mode)
4569 {
4570   if (validate_arglist (exp,
4571                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4572     {
4573       tree result = fold_builtin_strncat (CALL_EXPR_ARG (exp, 0),
4574                                           CALL_EXPR_ARG (exp, 1),
4575                                           CALL_EXPR_ARG (exp, 2));
4576       if (result)
4577         return expand_expr (result, target, mode, EXPAND_NORMAL);
4578     }
4579   return NULL_RTX;
4580 }
4581
4582 /* Expand expression EXP, which is a call to the strspn builtin.
4583    Return NULL_RTX if we failed the caller should emit a normal call,
4584    otherwise try to get the result in TARGET, if convenient.  */
4585
4586 static rtx
4587 expand_builtin_strspn (tree exp, rtx target, enum machine_mode mode)
4588 {
4589   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4590     {
4591       tree result = fold_builtin_strspn (CALL_EXPR_ARG (exp, 0),
4592                                          CALL_EXPR_ARG (exp, 1));
4593       if (result)
4594         return expand_expr (result, target, mode, EXPAND_NORMAL);
4595     }
4596   return NULL_RTX;
4597 }
4598
4599 /* Expand expression EXP, which is a call to the strcspn builtin.
4600    Return NULL_RTX if we failed the caller should emit a normal call,
4601    otherwise try to get the result in TARGET, if convenient.  */
4602
4603 static rtx
4604 expand_builtin_strcspn (tree exp, rtx target, enum machine_mode mode)
4605 {
4606   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4607     {
4608       tree result = fold_builtin_strcspn (CALL_EXPR_ARG (exp, 0),
4609                                           CALL_EXPR_ARG (exp, 1));
4610       if (result)
4611         return expand_expr (result, target, mode, EXPAND_NORMAL);
4612     }
4613   return NULL_RTX;
4614 }
4615
4616 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4617    if that's convenient.  */
4618
4619 rtx
4620 expand_builtin_saveregs (void)
4621 {
4622   rtx val, seq;
4623
4624   /* Don't do __builtin_saveregs more than once in a function.
4625      Save the result of the first call and reuse it.  */
4626   if (saveregs_value != 0)
4627     return saveregs_value;
4628
4629   /* When this function is called, it means that registers must be
4630      saved on entry to this function.  So we migrate the call to the
4631      first insn of this function.  */
4632
4633   start_sequence ();
4634
4635   /* Do whatever the machine needs done in this case.  */
4636   val = targetm.calls.expand_builtin_saveregs ();
4637
4638   seq = get_insns ();
4639   end_sequence ();
4640
4641   saveregs_value = val;
4642
4643   /* Put the insns after the NOTE that starts the function.  If this
4644      is inside a start_sequence, make the outer-level insn chain current, so
4645      the code is placed at the start of the function.  */
4646   push_topmost_sequence ();
4647   emit_insn_after (seq, entry_of_function ());
4648   pop_topmost_sequence ();
4649
4650   return val;
4651 }
4652
4653 /* __builtin_args_info (N) returns word N of the arg space info
4654    for the current function.  The number and meanings of words
4655    is controlled by the definition of CUMULATIVE_ARGS.  */
4656
4657 static rtx
4658 expand_builtin_args_info (tree exp)
4659 {
4660   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4661   int *word_ptr = (int *) &crtl->args.info;
4662
4663   gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4664
4665   if (call_expr_nargs (exp) != 0)
4666     {
4667       if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
4668         error ("argument of %<__builtin_args_info%> must be constant");
4669       else
4670         {
4671           HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
4672
4673           if (wordnum < 0 || wordnum >= nwords)
4674             error ("argument of %<__builtin_args_info%> out of range");
4675           else
4676             return GEN_INT (word_ptr[wordnum]);
4677         }
4678     }
4679   else
4680     error ("missing argument in %<__builtin_args_info%>");
4681
4682   return const0_rtx;
4683 }
4684
4685 /* Expand a call to __builtin_next_arg.  */
4686
4687 static rtx
4688 expand_builtin_next_arg (void)
4689 {
4690   /* Checking arguments is already done in fold_builtin_next_arg
4691      that must be called before this function.  */
4692   return expand_binop (ptr_mode, add_optab,
4693                        crtl->args.internal_arg_pointer,
4694                        crtl->args.arg_offset_rtx,
4695                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4696 }
4697
4698 /* Make it easier for the backends by protecting the valist argument
4699    from multiple evaluations.  */
4700
4701 static tree
4702 stabilize_va_list (tree valist, int needs_lvalue)
4703 {
4704   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4705
4706   gcc_assert (vatype != NULL_TREE);
4707
4708   if (TREE_CODE (vatype) == ARRAY_TYPE)
4709     {
4710       if (TREE_SIDE_EFFECTS (valist))
4711         valist = save_expr (valist);
4712
4713       /* For this case, the backends will be expecting a pointer to
4714          vatype, but it's possible we've actually been given an array
4715          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4716          So fix it.  */
4717       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4718         {
4719           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4720           valist = build_fold_addr_expr_with_type (valist, p1);
4721         }
4722     }
4723   else
4724     {
4725       tree pt;
4726
4727       if (! needs_lvalue)
4728         {
4729           if (! TREE_SIDE_EFFECTS (valist))
4730             return valist;
4731
4732           pt = build_pointer_type (vatype);
4733           valist = fold_build1 (ADDR_EXPR, pt, valist);
4734           TREE_SIDE_EFFECTS (valist) = 1;
4735         }
4736
4737       if (TREE_SIDE_EFFECTS (valist))
4738         valist = save_expr (valist);
4739       valist = build_fold_indirect_ref (valist);
4740     }
4741
4742   return valist;
4743 }
4744
4745 /* The "standard" definition of va_list is void*.  */
4746
4747 tree
4748 std_build_builtin_va_list (void)
4749 {
4750   return ptr_type_node;
4751 }
4752
4753 /* The "standard" abi va_list is va_list_type_node.  */
4754
4755 tree
4756 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4757 {
4758   return va_list_type_node;
4759 }
4760
4761 /* The "standard" type of va_list is va_list_type_node.  */
4762
4763 tree
4764 std_canonical_va_list_type (tree type)
4765 {
4766   tree wtype, htype;
4767
4768   if (INDIRECT_REF_P (type))
4769     type = TREE_TYPE (type);
4770   else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4771     type = TREE_TYPE (type);
4772   wtype = va_list_type_node;
4773   htype = type;
4774   /* Treat structure va_list types.  */
4775   if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4776     htype = TREE_TYPE (htype);
4777   else if (TREE_CODE (wtype) == ARRAY_TYPE)
4778     {
4779       /* If va_list is an array type, the argument may have decayed
4780          to a pointer type, e.g. by being passed to another function.
4781          In that case, unwrap both types so that we can compare the
4782          underlying records.  */
4783       if (TREE_CODE (htype) == ARRAY_TYPE
4784           || POINTER_TYPE_P (htype))
4785         {
4786           wtype = TREE_TYPE (wtype);
4787           htype = TREE_TYPE (htype);
4788         }
4789     }
4790   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4791     return va_list_type_node;
4792
4793   return NULL_TREE;
4794 }
4795
4796 /* The "standard" implementation of va_start: just assign `nextarg' to
4797    the variable.  */
4798
4799 void
4800 std_expand_builtin_va_start (tree valist, rtx nextarg)
4801 {
4802   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4803   convert_move (va_r, nextarg, 0);
4804 }
4805
4806 /* Expand EXP, a call to __builtin_va_start.  */
4807
4808 static rtx
4809 expand_builtin_va_start (tree exp)
4810 {
4811   rtx nextarg;
4812   tree valist;
4813
4814   if (call_expr_nargs (exp) < 2)
4815     {
4816       error ("too few arguments to function %<va_start%>");
4817       return const0_rtx;
4818     }
4819
4820   if (fold_builtin_next_arg (exp, true))
4821     return const0_rtx;
4822
4823   nextarg = expand_builtin_next_arg ();
4824   valist = stabilize_va_list (CALL_EXPR_ARG (exp, 0), 1);
4825
4826   if (targetm.expand_builtin_va_start)
4827     targetm.expand_builtin_va_start (valist, nextarg);
4828   else
4829     std_expand_builtin_va_start (valist, nextarg);
4830
4831   return const0_rtx;
4832 }
4833
4834 /* The "standard" implementation of va_arg: read the value from the
4835    current (padded) address and increment by the (padded) size.  */
4836
4837 tree
4838 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4839                           gimple_seq *post_p)
4840 {
4841   tree addr, t, type_size, rounded_size, valist_tmp;
4842   unsigned HOST_WIDE_INT align, boundary;
4843   bool indirect;
4844
4845 #ifdef ARGS_GROW_DOWNWARD
4846   /* All of the alignment and movement below is for args-grow-up machines.
4847      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4848      implement their own specialized gimplify_va_arg_expr routines.  */
4849   gcc_unreachable ();
4850 #endif
4851
4852   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4853   if (indirect)
4854     type = build_pointer_type (type);
4855
4856   align = PARM_BOUNDARY / BITS_PER_UNIT;
4857   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4858
4859   /* When we align parameter on stack for caller, if the parameter
4860      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4861      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4862      here with caller.  */
4863   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4864     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4865
4866   boundary /= BITS_PER_UNIT;
4867
4868   /* Hoist the valist value into a temporary for the moment.  */
4869   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4870
4871   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4872      requires greater alignment, we must perform dynamic alignment.  */
4873   if (boundary > align
4874       && !integer_zerop (TYPE_SIZE (type)))
4875     {
4876       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4877                   fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist),
4878                                valist_tmp, size_int (boundary - 1)));
4879       gimplify_and_add (t, pre_p);
4880
4881       t = fold_convert (sizetype, valist_tmp);
4882       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4883                   fold_convert (TREE_TYPE (valist),
4884                                 fold_build2 (BIT_AND_EXPR, sizetype, t,
4885                                              size_int (-boundary))));
4886       gimplify_and_add (t, pre_p);
4887     }
4888   else
4889     boundary = align;
4890
4891   /* If the actual alignment is less than the alignment of the type,
4892      adjust the type accordingly so that we don't assume strict alignment
4893      when dereferencing the pointer.  */
4894   boundary *= BITS_PER_UNIT;
4895   if (boundary < TYPE_ALIGN (type))
4896     {
4897       type = build_variant_type_copy (type);
4898       TYPE_ALIGN (type) = boundary;
4899     }
4900
4901   /* Compute the rounded size of the type.  */
4902   type_size = size_in_bytes (type);
4903   rounded_size = round_up (type_size, align);
4904
4905   /* Reduce rounded_size so it's sharable with the postqueue.  */
4906   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4907
4908   /* Get AP.  */
4909   addr = valist_tmp;
4910   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4911     {
4912       /* Small args are padded downward.  */
4913       t = fold_build2 (GT_EXPR, sizetype, rounded_size, size_int (align));
4914       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4915                        size_binop (MINUS_EXPR, rounded_size, type_size));
4916       addr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (addr), addr, t);
4917     }
4918
4919   /* Compute new value for AP.  */
4920   t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
4921   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4922   gimplify_and_add (t, pre_p);
4923
4924   addr = fold_convert (build_pointer_type (type), addr);
4925
4926   if (indirect)
4927     addr = build_va_arg_indirect_ref (addr);
4928
4929   return build_va_arg_indirect_ref (addr);
4930 }
4931
4932 /* Build an indirect-ref expression over the given TREE, which represents a
4933    piece of a va_arg() expansion.  */
4934 tree
4935 build_va_arg_indirect_ref (tree addr)
4936 {
4937   addr = build_fold_indirect_ref (addr);
4938
4939   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4940     mf_mark (addr);
4941
4942   return addr;
4943 }
4944
4945 /* Return a dummy expression of type TYPE in order to keep going after an
4946    error.  */
4947
4948 static tree
4949 dummy_object (tree type)
4950 {
4951   tree t = build_int_cst (build_pointer_type (type), 0);
4952   return build1 (INDIRECT_REF, type, t);
4953 }
4954
4955 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4956    builtin function, but a very special sort of operator.  */
4957
4958 enum gimplify_status
4959 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4960 {
4961   tree promoted_type, have_va_type;
4962   tree valist = TREE_OPERAND (*expr_p, 0);
4963   tree type = TREE_TYPE (*expr_p);
4964   tree t;
4965
4966   /* Verify that valist is of the proper type.  */
4967   have_va_type = TREE_TYPE (valist);
4968   if (have_va_type == error_mark_node)
4969     return GS_ERROR;
4970   have_va_type = targetm.canonical_va_list_type (have_va_type);
4971
4972   if (have_va_type == NULL_TREE)
4973     {
4974       error ("first argument to %<va_arg%> not of type %<va_list%>");
4975       return GS_ERROR;
4976     }
4977
4978   /* Generate a diagnostic for requesting data of a type that cannot
4979      be passed through `...' due to type promotion at the call site.  */
4980   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4981            != type)
4982     {
4983       static bool gave_help;
4984       bool warned;
4985
4986       /* Unfortunately, this is merely undefined, rather than a constraint
4987          violation, so we cannot make this an error.  If this call is never
4988          executed, the program is still strictly conforming.  */
4989       warned = warning (0, "%qT is promoted to %qT when passed through %<...%>",
4990                         type, promoted_type);
4991       if (!gave_help && warned)
4992         {
4993           gave_help = true;
4994           inform (input_location, "(so you should pass %qT not %qT to %<va_arg%>)",
4995                    promoted_type, type);
4996         }
4997
4998       /* We can, however, treat "undefined" any way we please.
4999          Call abort to encourage the user to fix the program.  */
5000       if (warned)
5001         inform (input_location, "if this code is reached, the program will abort");
5002       t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
5003       gimplify_and_add (t, pre_p);
5004
5005       /* This is dead code, but go ahead and finish so that the
5006          mode of the result comes out right.  */
5007       *expr_p = dummy_object (type);
5008       return GS_ALL_DONE;
5009     }
5010   else
5011     {
5012       /* Make it easier for the backends by protecting the valist argument
5013          from multiple evaluations.  */
5014       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
5015         {
5016           /* For this case, the backends will be expecting a pointer to
5017              TREE_TYPE (abi), but it's possible we've
5018              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
5019              So fix it.  */
5020           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
5021             {
5022               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
5023               valist = build_fold_addr_expr_with_type (valist, p1);
5024             }
5025
5026           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
5027         }
5028       else
5029         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
5030
5031       if (!targetm.gimplify_va_arg_expr)
5032         /* FIXME: Once most targets are converted we should merely
5033            assert this is non-null.  */
5034         return GS_ALL_DONE;
5035
5036       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
5037       return GS_OK;
5038     }
5039 }
5040
5041 /* Expand EXP, a call to __builtin_va_end.  */
5042
5043 static rtx
5044 expand_builtin_va_end (tree exp)
5045 {
5046   tree valist = CALL_EXPR_ARG (exp, 0);
5047
5048   /* Evaluate for side effects, if needed.  I hate macros that don't
5049      do that.  */
5050   if (TREE_SIDE_EFFECTS (valist))
5051     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
5052
5053   return const0_rtx;
5054 }
5055
5056 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
5057    builtin rather than just as an assignment in stdarg.h because of the
5058    nastiness of array-type va_list types.  */
5059
5060 static rtx
5061 expand_builtin_va_copy (tree exp)
5062 {
5063   tree dst, src, t;
5064
5065   dst = CALL_EXPR_ARG (exp, 0);
5066   src = CALL_EXPR_ARG (exp, 1);
5067
5068   dst = stabilize_va_list (dst, 1);
5069   src = stabilize_va_list (src, 0);
5070
5071   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
5072
5073   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
5074     {
5075       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
5076       TREE_SIDE_EFFECTS (t) = 1;
5077       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5078     }
5079   else
5080     {
5081       rtx dstb, srcb, size;
5082
5083       /* Evaluate to pointers.  */
5084       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
5085       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
5086       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
5087                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
5088
5089       dstb = convert_memory_address (Pmode, dstb);
5090       srcb = convert_memory_address (Pmode, srcb);
5091
5092       /* "Dereference" to BLKmode memories.  */
5093       dstb = gen_rtx_MEM (BLKmode, dstb);
5094       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
5095       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
5096       srcb = gen_rtx_MEM (BLKmode, srcb);
5097       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
5098       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
5099
5100       /* Copy.  */
5101       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
5102     }
5103
5104   return const0_rtx;
5105 }
5106
5107 /* Expand a call to one of the builtin functions __builtin_frame_address or
5108    __builtin_return_address.  */
5109
5110 static rtx
5111 expand_builtin_frame_address (tree fndecl, tree exp)
5112 {
5113   /* The argument must be a nonnegative integer constant.
5114      It counts the number of frames to scan up the stack.
5115      The value is the return address saved in that frame.  */
5116   if (call_expr_nargs (exp) == 0)
5117     /* Warning about missing arg was already issued.  */
5118     return const0_rtx;
5119   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
5120     {
5121       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5122         error ("invalid argument to %<__builtin_frame_address%>");
5123       else
5124         error ("invalid argument to %<__builtin_return_address%>");
5125       return const0_rtx;
5126     }
5127   else
5128     {
5129       rtx tem
5130         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
5131                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
5132
5133       /* Some ports cannot access arbitrary stack frames.  */
5134       if (tem == NULL)
5135         {
5136           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5137             warning (0, "unsupported argument to %<__builtin_frame_address%>");
5138           else
5139             warning (0, "unsupported argument to %<__builtin_return_address%>");
5140           return const0_rtx;
5141         }
5142
5143       /* For __builtin_frame_address, return what we've got.  */
5144       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
5145         return tem;
5146
5147       if (!REG_P (tem)
5148           && ! CONSTANT_P (tem))
5149         tem = copy_to_mode_reg (Pmode, tem);
5150       return tem;
5151     }
5152 }
5153
5154 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if
5155    we failed and the caller should emit a normal call, otherwise try to get
5156    the result in TARGET, if convenient.  */
5157
5158 static rtx
5159 expand_builtin_alloca (tree exp, rtx target)
5160 {
5161   rtx op0;
5162   rtx result;
5163
5164   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
5165      should always expand to function calls.  These can be intercepted
5166      in libmudflap.  */
5167   if (flag_mudflap)
5168     return NULL_RTX;
5169
5170   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5171     return NULL_RTX;
5172
5173   /* Compute the argument.  */
5174   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
5175
5176   /* Allocate the desired space.  */
5177   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
5178   result = convert_memory_address (ptr_mode, result);
5179
5180   return result;
5181 }
5182
5183 /* Expand a call to a bswap builtin with argument ARG0.  MODE
5184    is the mode to expand with.  */
5185
5186 static rtx
5187 expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
5188 {
5189   enum machine_mode mode;
5190   tree arg;
5191   rtx op0;
5192
5193   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5194     return NULL_RTX;
5195
5196   arg = CALL_EXPR_ARG (exp, 0);
5197   mode = TYPE_MODE (TREE_TYPE (arg));
5198   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5199
5200   target = expand_unop (mode, bswap_optab, op0, target, 1);
5201
5202   gcc_assert (target);
5203
5204   return convert_to_mode (mode, target, 0);
5205 }
5206
5207 /* Expand a call to a unary builtin in EXP.
5208    Return NULL_RTX if a normal call should be emitted rather than expanding the
5209    function in-line.  If convenient, the result should be placed in TARGET.
5210    SUBTARGET may be used as the target for computing one of EXP's operands.  */
5211
5212 static rtx
5213 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
5214                      rtx subtarget, optab op_optab)
5215 {
5216   rtx op0;
5217
5218   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
5219     return NULL_RTX;
5220
5221   /* Compute the argument.  */
5222   op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
5223                      VOIDmode, EXPAND_NORMAL);
5224   /* Compute op, into TARGET if possible.
5225      Set TARGET to wherever the result comes back.  */
5226   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
5227                         op_optab, op0, target, 1);
5228   gcc_assert (target);
5229
5230   return convert_to_mode (target_mode, target, 0);
5231 }
5232
5233 /* If the string passed to fputs is a constant and is one character
5234    long, we attempt to transform this call into __builtin_fputc().  */
5235
5236 static rtx
5237 expand_builtin_fputs (tree exp, rtx target, bool unlocked)
5238 {
5239   /* Verify the arguments in the original call.  */
5240   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5241     {
5242       tree result = fold_builtin_fputs (CALL_EXPR_ARG (exp, 0),
5243                                         CALL_EXPR_ARG (exp, 1),
5244                                         (target == const0_rtx),
5245                                         unlocked, NULL_TREE);
5246       if (result)
5247         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
5248     }
5249   return NULL_RTX;
5250 }
5251
5252 /* Expand a call to __builtin_expect.  We just return our argument 
5253    as the builtin_expect semantic should've been already executed by
5254    tree branch prediction pass. */
5255
5256 static rtx
5257 expand_builtin_expect (tree exp, rtx target)
5258 {
5259   tree arg, c;
5260
5261   if (call_expr_nargs (exp) < 2)
5262     return const0_rtx;
5263   arg = CALL_EXPR_ARG (exp, 0);
5264   c = CALL_EXPR_ARG (exp, 1);
5265
5266   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5267   /* When guessing was done, the hints should be already stripped away.  */
5268   gcc_assert (!flag_guess_branch_prob
5269               || optimize == 0 || errorcount || sorrycount);
5270   return target;
5271 }
5272
5273 void
5274 expand_builtin_trap (void)
5275 {
5276 #ifdef HAVE_trap
5277   if (HAVE_trap)
5278     emit_insn (gen_trap ());
5279   else
5280 #endif
5281     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
5282   emit_barrier ();
5283 }
5284
5285 /* Expand EXP, a call to fabs, fabsf or fabsl.
5286    Return NULL_RTX if a normal call should be emitted rather than expanding
5287    the function inline.  If convenient, the result should be placed
5288    in TARGET.  SUBTARGET may be used as the target for computing
5289    the operand.  */
5290
5291 static rtx
5292 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
5293 {
5294   enum machine_mode mode;
5295   tree arg;
5296   rtx op0;
5297
5298   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5299     return NULL_RTX;
5300
5301   arg = CALL_EXPR_ARG (exp, 0);
5302   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
5303   mode = TYPE_MODE (TREE_TYPE (arg));
5304   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5305   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
5306 }
5307
5308 /* Expand EXP, a call to copysign, copysignf, or copysignl.
5309    Return NULL is a normal call should be emitted rather than expanding the
5310    function inline.  If convenient, the result should be placed in TARGET.
5311    SUBTARGET may be used as the target for computing the operand.  */
5312
5313 static rtx
5314 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
5315 {
5316   rtx op0, op1;
5317   tree arg;
5318
5319   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
5320     return NULL_RTX;
5321
5322   arg = CALL_EXPR_ARG (exp, 0);
5323   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
5324
5325   arg = CALL_EXPR_ARG (exp, 1);
5326   op1 = expand_normal (arg);
5327
5328   return expand_copysign (op0, op1, target);
5329 }
5330
5331 /* Create a new constant string literal and return a char* pointer to it.
5332    The STRING_CST value is the LEN characters at STR.  */
5333 tree
5334 build_string_literal (int len, const char *str)
5335 {
5336   tree t, elem, index, type;
5337
5338   t = build_string (len, str);
5339   elem = build_type_variant (char_type_node, 1, 0);
5340   index = build_index_type (size_int (len - 1));
5341   type = build_array_type (elem, index);
5342   TREE_TYPE (t) = type;
5343   TREE_CONSTANT (t) = 1;
5344   TREE_READONLY (t) = 1;
5345   TREE_STATIC (t) = 1;
5346
5347   type = build_pointer_type (elem);
5348   t = build1 (ADDR_EXPR, type,
5349               build4 (ARRAY_REF, elem,
5350                       t, integer_zero_node, NULL_TREE, NULL_TREE));
5351   return t;
5352 }
5353
5354 /* Expand EXP, a call to printf or printf_unlocked.
5355    Return NULL_RTX if a normal call should be emitted rather than transforming
5356    the function inline.  If convenient, the result should be placed in
5357    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
5358    call.  */
5359 static rtx
5360 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
5361                        bool unlocked)
5362 {
5363   /* If we're using an unlocked function, assume the other unlocked
5364      functions exist explicitly.  */
5365   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5366     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5367   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5368     : implicit_built_in_decls[BUILT_IN_PUTS];
5369   const char *fmt_str;
5370   tree fn = 0;
5371   tree fmt, arg;
5372   int nargs = call_expr_nargs (exp);
5373
5374   /* If the return value is used, don't do the transformation.  */
5375   if (target != const0_rtx)
5376     return NULL_RTX;
5377
5378   /* Verify the required arguments in the original call.  */
5379   if (nargs == 0)
5380     return NULL_RTX;
5381   fmt = CALL_EXPR_ARG (exp, 0);
5382   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5383     return NULL_RTX;
5384
5385   /* Check whether the format is a literal string constant.  */
5386   fmt_str = c_getstr (fmt);
5387   if (fmt_str == NULL)
5388     return NULL_RTX;
5389
5390   if (!init_target_chars ())
5391     return NULL_RTX;
5392
5393   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
5394   if (strcmp (fmt_str, target_percent_s_newline) == 0)
5395     {
5396       if ((nargs != 2)
5397           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5398         return NULL_RTX;
5399       if (fn_puts)
5400         fn = build_call_expr (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
5401     }
5402   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
5403   else if (strcmp (fmt_str, target_percent_c) == 0)
5404     {
5405       if ((nargs != 2)
5406           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5407         return NULL_RTX;
5408       if (fn_putchar)
5409         fn = build_call_expr (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
5410     }
5411   else
5412     {
5413       /* We can't handle anything else with % args or %% ... yet.  */
5414       if (strchr (fmt_str, target_percent))
5415         return NULL_RTX;
5416
5417       if (nargs > 1)
5418         return NULL_RTX;
5419
5420       /* If the format specifier was "", printf does nothing.  */
5421       if (fmt_str[0] == '\0')
5422         return const0_rtx;
5423       /* If the format specifier has length of 1, call putchar.  */
5424       if (fmt_str[1] == '\0')
5425         {
5426           /* Given printf("c"), (where c is any one character,)
5427              convert "c"[0] to an int and pass that to the replacement
5428              function.  */
5429           arg = build_int_cst (NULL_TREE, fmt_str[0]);
5430           if (fn_putchar)
5431             fn = build_call_expr (fn_putchar, 1, arg);
5432         }
5433       else
5434         {
5435           /* If the format specifier was "string\n", call puts("string").  */
5436           size_t len = strlen (fmt_str);
5437           if ((unsigned char)fmt_str[len - 1] == target_newline)
5438             {
5439               /* Create a NUL-terminated string that's one char shorter
5440                  than the original, stripping off the trailing '\n'.  */
5441               char *newstr = XALLOCAVEC (char, len);
5442               memcpy (newstr, fmt_str, len - 1);
5443               newstr[len - 1] = 0;
5444               arg = build_string_literal (len, newstr);
5445               if (fn_puts)
5446                 fn = build_call_expr (fn_puts, 1, arg);
5447             }
5448           else
5449             /* We'd like to arrange to call fputs(string,stdout) here,
5450                but we need stdout and don't have a way to get it yet.  */
5451             return NULL_RTX;
5452         }
5453     }
5454
5455   if (!fn)
5456     return NULL_RTX;
5457   if (TREE_CODE (fn) == CALL_EXPR)
5458     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5459   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5460 }
5461
5462 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5463    Return NULL_RTX if a normal call should be emitted rather than transforming
5464    the function inline.  If convenient, the result should be placed in
5465    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5466    call.  */
5467 static rtx
5468 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5469                         bool unlocked)
5470 {
5471   /* If we're using an unlocked function, assume the other unlocked
5472      functions exist explicitly.  */
5473   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5474     : implicit_built_in_decls[BUILT_IN_FPUTC];
5475   tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5476     : implicit_built_in_decls[BUILT_IN_FPUTS];
5477   const char *fmt_str;
5478   tree fn = 0;
5479   tree fmt, fp, arg;
5480   int nargs = call_expr_nargs (exp);
5481
5482   /* If the return value is used, don't do the transformation.  */
5483   if (target != const0_rtx)
5484     return NULL_RTX;
5485
5486   /* Verify the required arguments in the original call.  */
5487   if (nargs < 2)
5488     return NULL_RTX;
5489   fp = CALL_EXPR_ARG (exp, 0);
5490   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5491     return NULL_RTX;
5492   fmt = CALL_EXPR_ARG (exp, 1);
5493   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5494     return NULL_RTX;
5495
5496   /* Check whether the format is a literal string constant.  */
5497   fmt_str = c_getstr (fmt);
5498   if (fmt_str == NULL)
5499     return NULL_RTX;
5500
5501   if (!init_target_chars ())
5502     return NULL_RTX;
5503
5504   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5505   if (strcmp (fmt_str, target_percent_s) == 0)
5506     {
5507       if ((nargs != 3)
5508           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5509         return NULL_RTX;
5510       arg = CALL_EXPR_ARG (exp, 2);
5511       if (fn_fputs)
5512         fn = build_call_expr (fn_fputs, 2, arg, fp);
5513     }
5514   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5515   else if (strcmp (fmt_str, target_percent_c) == 0)
5516     {
5517       if ((nargs != 3)
5518           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5519         return NULL_RTX;
5520       arg = CALL_EXPR_ARG (exp, 2);
5521       if (fn_fputc)
5522         fn = build_call_expr (fn_fputc, 2, arg, fp);
5523     }
5524   else
5525     {
5526       /* We can't handle anything else with % args or %% ... yet.  */
5527       if (strchr (fmt_str, target_percent))
5528         return NULL_RTX;
5529
5530       if (nargs > 2)
5531         return NULL_RTX;
5532
5533       /* If the format specifier was "", fprintf does nothing.  */
5534       if (fmt_str[0] == '\0')
5535         {
5536           /* Evaluate and ignore FILE* argument for side-effects.  */
5537           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5538           return const0_rtx;
5539         }
5540
5541       /* When "string" doesn't contain %, replace all cases of
5542          fprintf(stream,string) with fputs(string,stream).  The fputs
5543          builtin will take care of special cases like length == 1.  */
5544       if (fn_fputs)
5545         fn = build_call_expr (fn_fputs, 2, fmt, fp);
5546     }
5547
5548   if (!fn)
5549     return NULL_RTX;
5550   if (TREE_CODE (fn) == CALL_EXPR)
5551     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5552   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5553 }
5554
5555 /* Expand a call EXP to sprintf.  Return NULL_RTX if
5556    a normal call should be emitted rather than expanding the function
5557    inline.  If convenient, the result should be placed in TARGET with
5558    mode MODE.  */
5559
5560 static rtx
5561 expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
5562 {
5563   tree dest, fmt;
5564   const char *fmt_str;
5565   int nargs = call_expr_nargs (exp);
5566
5567   /* Verify the required arguments in the original call.  */
5568   if (nargs < 2)
5569     return NULL_RTX;
5570   dest = CALL_EXPR_ARG (exp, 0);
5571   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5572     return NULL_RTX;
5573   fmt = CALL_EXPR_ARG (exp, 0);
5574   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5575     return NULL_RTX;
5576
5577   /* Check whether the format is a literal string constant.  */
5578   fmt_str = c_getstr (fmt);
5579   if (fmt_str == NULL)
5580     return NULL_RTX;
5581
5582   if (!init_target_chars ())
5583     return NULL_RTX;
5584
5585   /* If the format doesn't contain % args or %%, use strcpy.  */
5586   if (strchr (fmt_str, target_percent) == 0)
5587     {
5588       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5589       tree exp;
5590
5591       if ((nargs > 2) || ! fn)
5592         return NULL_RTX;
5593       expand_expr (build_call_expr (fn, 2, dest, fmt),
5594                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5595       if (target == const0_rtx)
5596         return const0_rtx;
5597       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5598       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5599     }
5600   /* If the format is "%s", use strcpy if the result isn't used.  */
5601   else if (strcmp (fmt_str, target_percent_s) == 0)
5602     {
5603       tree fn, arg, len;
5604       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5605
5606       if (! fn)
5607         return NULL_RTX;
5608       if (nargs != 3)
5609         return NULL_RTX;
5610       arg = CALL_EXPR_ARG (exp, 2);
5611       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5612         return NULL_RTX;
5613
5614       if (target != const0_rtx)
5615         {
5616           len = c_strlen (arg, 1);
5617           if (! len || TREE_CODE (len) != INTEGER_CST)
5618             return NULL_RTX;
5619         }
5620       else
5621         len = NULL_TREE;
5622
5623       expand_expr (build_call_expr (fn, 2, dest, arg),
5624                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5625
5626       if (target == const0_rtx)
5627         return const0_rtx;
5628       return expand_expr (len, target, mode, EXPAND_NORMAL);
5629     }
5630
5631   return NULL_RTX;
5632 }
5633
5634 /* Expand a call to either the entry or exit function profiler.  */
5635
5636 static rtx
5637 expand_builtin_profile_func (bool exitp)
5638 {
5639   rtx this_rtx, which;
5640
5641   this_rtx = DECL_RTL (current_function_decl);
5642   gcc_assert (MEM_P (this_rtx));
5643   this_rtx = XEXP (this_rtx, 0);
5644
5645   if (exitp)
5646     which = profile_function_exit_libfunc;
5647   else
5648     which = profile_function_entry_libfunc;
5649
5650   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
5651                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5652                                                  0),
5653                      Pmode);
5654
5655   return const0_rtx;
5656 }
5657
5658 /* Expand a call to __builtin___clear_cache.  */
5659
5660 static rtx
5661 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5662 {
5663 #ifndef HAVE_clear_cache
5664 #ifdef CLEAR_INSN_CACHE
5665   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5666      does something.  Just do the default expansion to a call to
5667      __clear_cache().  */
5668   return NULL_RTX;
5669 #else
5670   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5671      does nothing.  There is no need to call it.  Do nothing.  */
5672   return const0_rtx;
5673 #endif /* CLEAR_INSN_CACHE */
5674 #else
5675   /* We have a "clear_cache" insn, and it will handle everything.  */
5676   tree begin, end;
5677   rtx begin_rtx, end_rtx;
5678   enum insn_code icode;
5679
5680   /* We must not expand to a library call.  If we did, any
5681      fallback library function in libgcc that might contain a call to
5682      __builtin___clear_cache() would recurse infinitely.  */
5683   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5684     {
5685       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5686       return const0_rtx;
5687     }
5688
5689   if (HAVE_clear_cache)
5690     {
5691       icode = CODE_FOR_clear_cache;
5692
5693       begin = CALL_EXPR_ARG (exp, 0);
5694       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5695       begin_rtx = convert_memory_address (Pmode, begin_rtx);
5696       if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5697         begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5698
5699       end = CALL_EXPR_ARG (exp, 1);
5700       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5701       end_rtx = convert_memory_address (Pmode, end_rtx);
5702       if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5703         end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5704
5705       emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5706     }
5707   return const0_rtx;
5708 #endif /* HAVE_clear_cache */
5709 }
5710
5711 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5712
5713 static rtx
5714 round_trampoline_addr (rtx tramp)
5715 {
5716   rtx temp, addend, mask;
5717
5718   /* If we don't need too much alignment, we'll have been guaranteed
5719      proper alignment by get_trampoline_type.  */
5720   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5721     return tramp;
5722
5723   /* Round address up to desired boundary.  */
5724   temp = gen_reg_rtx (Pmode);
5725   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5726   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5727
5728   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5729                                temp, 0, OPTAB_LIB_WIDEN);
5730   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5731                                temp, 0, OPTAB_LIB_WIDEN);
5732
5733   return tramp;
5734 }
5735
5736 static rtx
5737 expand_builtin_init_trampoline (tree exp)
5738 {
5739   tree t_tramp, t_func, t_chain;
5740   rtx r_tramp, r_func, r_chain;
5741 #ifdef TRAMPOLINE_TEMPLATE
5742   rtx blktramp;
5743 #endif
5744
5745   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
5746                          POINTER_TYPE, VOID_TYPE))
5747     return NULL_RTX;
5748
5749   t_tramp = CALL_EXPR_ARG (exp, 0);
5750   t_func = CALL_EXPR_ARG (exp, 1);
5751   t_chain = CALL_EXPR_ARG (exp, 2);
5752
5753   r_tramp = expand_normal (t_tramp);
5754   r_func = expand_normal (t_func);
5755   r_chain = expand_normal (t_chain);
5756
5757   /* Generate insns to initialize the trampoline.  */
5758   r_tramp = round_trampoline_addr (r_tramp);
5759 #ifdef TRAMPOLINE_TEMPLATE
5760   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5761   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5762   emit_block_move (blktramp, assemble_trampoline_template (),
5763                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5764 #endif
5765   trampolines_created = 1;
5766   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5767
5768   return const0_rtx;
5769 }
5770
5771 static rtx
5772 expand_builtin_adjust_trampoline (tree exp)
5773 {
5774   rtx tramp;
5775
5776   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5777     return NULL_RTX;
5778
5779   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
5780   tramp = round_trampoline_addr (tramp);
5781 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5782   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5783 #endif
5784
5785   return tramp;
5786 }
5787
5788 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
5789    function.  The function first checks whether the back end provides
5790    an insn to implement signbit for the respective mode.  If not, it
5791    checks whether the floating point format of the value is such that
5792    the sign bit can be extracted.  If that is not the case, the
5793    function returns NULL_RTX to indicate that a normal call should be
5794    emitted rather than expanding the function in-line.  EXP is the
5795    expression that is a call to the builtin function; if convenient,
5796    the result should be placed in TARGET.  */
5797 static rtx
5798 expand_builtin_signbit (tree exp, rtx target)
5799 {
5800   const struct real_format *fmt;
5801   enum machine_mode fmode, imode, rmode;
5802   HOST_WIDE_INT hi, lo;
5803   tree arg;
5804   int word, bitpos;
5805   enum insn_code icode;
5806   rtx temp;
5807
5808   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5809     return NULL_RTX;
5810
5811   arg = CALL_EXPR_ARG (exp, 0);
5812   fmode = TYPE_MODE (TREE_TYPE (arg));
5813   rmode = TYPE_MODE (TREE_TYPE (exp));
5814   fmt = REAL_MODE_FORMAT (fmode);
5815
5816   arg = builtin_save_expr (arg);
5817
5818   /* Expand the argument yielding a RTX expression. */
5819   temp = expand_normal (arg);
5820
5821   /* Check if the back end provides an insn that handles signbit for the
5822      argument's mode. */
5823   icode = signbit_optab->handlers [(int) fmode].insn_code;
5824   if (icode != CODE_FOR_nothing)
5825     {
5826       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
5827       emit_unop_insn (icode, target, temp, UNKNOWN);
5828       return target;
5829     }
5830
5831   /* For floating point formats without a sign bit, implement signbit
5832      as "ARG < 0.0".  */
5833   bitpos = fmt->signbit_ro;
5834   if (bitpos < 0)
5835   {
5836     /* But we can't do this if the format supports signed zero.  */
5837     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5838       return NULL_RTX;
5839
5840     arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5841                        build_real (TREE_TYPE (arg), dconst0));
5842     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5843   }
5844
5845   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5846     {
5847       imode = int_mode_for_mode (fmode);
5848       if (imode == BLKmode)
5849         return NULL_RTX;
5850       temp = gen_lowpart (imode, temp);
5851     }
5852   else
5853     {
5854       imode = word_mode;
5855       /* Handle targets with different FP word orders.  */
5856       if (FLOAT_WORDS_BIG_ENDIAN)
5857         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5858       else
5859         word = bitpos / BITS_PER_WORD;
5860       temp = operand_subword_force (temp, word, fmode);
5861       bitpos = bitpos % BITS_PER_WORD;
5862     }
5863
5864   /* Force the intermediate word_mode (or narrower) result into a
5865      register.  This avoids attempting to create paradoxical SUBREGs
5866      of floating point modes below.  */
5867   temp = force_reg (imode, temp);
5868
5869   /* If the bitpos is within the "result mode" lowpart, the operation
5870      can be implement with a single bitwise AND.  Otherwise, we need
5871      a right shift and an AND.  */
5872
5873   if (bitpos < GET_MODE_BITSIZE (rmode))
5874     {
5875       if (bitpos < HOST_BITS_PER_WIDE_INT)
5876         {
5877           hi = 0;
5878           lo = (HOST_WIDE_INT) 1 << bitpos;
5879         }
5880       else
5881         {
5882           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5883           lo = 0;
5884         }
5885
5886       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5887         temp = gen_lowpart (rmode, temp);
5888       temp = expand_binop (rmode, and_optab, temp,
5889                            immed_double_const (lo, hi, rmode),
5890                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5891     }
5892   else
5893     {
5894       /* Perform a logical right shift to place the signbit in the least
5895          significant bit, then truncate the result to the desired mode
5896          and mask just this bit.  */
5897       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5898                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5899       temp = gen_lowpart (rmode, temp);
5900       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5901                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5902     }
5903
5904   return temp;
5905 }
5906
5907 /* Expand fork or exec calls.  TARGET is the desired target of the
5908    call.  EXP is the call. FN is the
5909    identificator of the actual function.  IGNORE is nonzero if the
5910    value is to be ignored.  */
5911
5912 static rtx
5913 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5914 {
5915   tree id, decl;
5916   tree call;
5917
5918   /* If we are not profiling, just call the function.  */
5919   if (!profile_arc_flag)
5920     return NULL_RTX;
5921
5922   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5923      compiler, so the code does not diverge, and the wrapper may run the
5924      code necessary for keeping the profiling sane.  */
5925
5926   switch (DECL_FUNCTION_CODE (fn))
5927     {
5928     case BUILT_IN_FORK:
5929       id = get_identifier ("__gcov_fork");
5930       break;
5931
5932     case BUILT_IN_EXECL:
5933       id = get_identifier ("__gcov_execl");
5934       break;
5935
5936     case BUILT_IN_EXECV:
5937       id = get_identifier ("__gcov_execv");
5938       break;
5939
5940     case BUILT_IN_EXECLP:
5941       id = get_identifier ("__gcov_execlp");
5942       break;
5943
5944     case BUILT_IN_EXECLE:
5945       id = get_identifier ("__gcov_execle");
5946       break;
5947
5948     case BUILT_IN_EXECVP:
5949       id = get_identifier ("__gcov_execvp");
5950       break;
5951
5952     case BUILT_IN_EXECVE:
5953       id = get_identifier ("__gcov_execve");
5954       break;
5955
5956     default:
5957       gcc_unreachable ();
5958     }
5959
5960   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5961   DECL_EXTERNAL (decl) = 1;
5962   TREE_PUBLIC (decl) = 1;
5963   DECL_ARTIFICIAL (decl) = 1;
5964   TREE_NOTHROW (decl) = 1;
5965   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5966   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5967   call = rewrite_call_expr (exp, 0, decl, 0);
5968   return expand_call (call, target, ignore);
5969  }
5970   
5971
5972 \f
5973 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5974    the pointer in these functions is void*, the tree optimizers may remove
5975    casts.  The mode computed in expand_builtin isn't reliable either, due
5976    to __sync_bool_compare_and_swap.
5977
5978    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5979    group of builtins.  This gives us log2 of the mode size.  */
5980
5981 static inline enum machine_mode
5982 get_builtin_sync_mode (int fcode_diff)
5983 {
5984   /* The size is not negotiable, so ask not to get BLKmode in return
5985      if the target indicates that a smaller size would be better.  */
5986   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5987 }
5988
5989 /* Expand the memory expression LOC and return the appropriate memory operand
5990    for the builtin_sync operations.  */
5991
5992 static rtx
5993 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5994 {
5995   rtx addr, mem;
5996
5997   addr = expand_expr (loc, NULL_RTX, Pmode, EXPAND_SUM);
5998
5999   /* Note that we explicitly do not want any alias information for this
6000      memory, so that we kill all other live memories.  Otherwise we don't
6001      satisfy the full barrier semantics of the intrinsic.  */
6002   mem = validize_mem (gen_rtx_MEM (mode, addr));
6003
6004   set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
6005   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
6006   MEM_VOLATILE_P (mem) = 1;
6007
6008   return mem;
6009 }
6010
6011 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
6012    EXP is the CALL_EXPR.  CODE is the rtx code
6013    that corresponds to the arithmetic or logical operation from the name;
6014    an exception here is that NOT actually means NAND.  TARGET is an optional
6015    place for us to store the results; AFTER is true if this is the
6016    fetch_and_xxx form.  IGNORE is true if we don't actually care about
6017    the result of the operation at all.  */
6018
6019 static rtx
6020 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
6021                                enum rtx_code code, bool after,
6022                                rtx target, bool ignore)
6023 {
6024   rtx val, mem;
6025   enum machine_mode old_mode;
6026
6027   if (code == NOT && warn_sync_nand)
6028     {
6029       tree fndecl = get_callee_fndecl (exp);
6030       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6031
6032       static bool warned_f_a_n, warned_n_a_f;
6033
6034       switch (fcode)
6035         {
6036         case BUILT_IN_FETCH_AND_NAND_1:
6037         case BUILT_IN_FETCH_AND_NAND_2:
6038         case BUILT_IN_FETCH_AND_NAND_4:
6039         case BUILT_IN_FETCH_AND_NAND_8:
6040         case BUILT_IN_FETCH_AND_NAND_16:
6041
6042           if (warned_f_a_n)
6043             break;
6044
6045           fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
6046           inform (input_location,
6047                   "%qD changed semantics in GCC 4.4", fndecl);
6048           warned_f_a_n = true;
6049           break;
6050
6051         case BUILT_IN_NAND_AND_FETCH_1:
6052         case BUILT_IN_NAND_AND_FETCH_2:
6053         case BUILT_IN_NAND_AND_FETCH_4:
6054         case BUILT_IN_NAND_AND_FETCH_8:
6055         case BUILT_IN_NAND_AND_FETCH_16:
6056
6057           if (warned_n_a_f)
6058             break;
6059
6060           fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
6061           inform (input_location,
6062                   "%qD changed semantics in GCC 4.4", fndecl);
6063           warned_n_a_f = true;
6064           break;
6065
6066         default:
6067           gcc_unreachable ();
6068         }
6069     }
6070
6071   /* Expand the operands.  */
6072   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6073
6074   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
6075   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
6076      of CONST_INTs, where we know the old_mode only from the call argument.  */
6077   old_mode = GET_MODE (val);
6078   if (old_mode == VOIDmode)
6079     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6080   val = convert_modes (mode, old_mode, val, 1);
6081
6082   if (ignore)
6083     return expand_sync_operation (mem, val, code);
6084   else
6085     return expand_sync_fetch_operation (mem, val, code, after, target);
6086 }
6087
6088 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
6089    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
6090    true if this is the boolean form.  TARGET is a place for us to store the
6091    results; this is NOT optional if IS_BOOL is true.  */
6092
6093 static rtx
6094 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
6095                                  bool is_bool, rtx target)
6096 {
6097   rtx old_val, new_val, mem;
6098   enum machine_mode old_mode;
6099
6100   /* Expand the operands.  */
6101   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6102
6103
6104   old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
6105                          mode, EXPAND_NORMAL);
6106   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
6107      of CONST_INTs, where we know the old_mode only from the call argument.  */
6108   old_mode = GET_MODE (old_val);
6109   if (old_mode == VOIDmode)
6110     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6111   old_val = convert_modes (mode, old_mode, old_val, 1);
6112
6113   new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
6114                          mode, EXPAND_NORMAL);
6115   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
6116      of CONST_INTs, where we know the old_mode only from the call argument.  */
6117   old_mode = GET_MODE (new_val);
6118   if (old_mode == VOIDmode)
6119     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
6120   new_val = convert_modes (mode, old_mode, new_val, 1);
6121
6122   if (is_bool)
6123     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
6124   else
6125     return expand_val_compare_and_swap (mem, old_val, new_val, target);
6126 }
6127
6128 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
6129    general form is actually an atomic exchange, and some targets only
6130    support a reduced form with the second argument being a constant 1.
6131    EXP is the CALL_EXPR; TARGET is an optional place for us to store 
6132    the results.  */
6133
6134 static rtx
6135 expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
6136                                   rtx target)
6137 {
6138   rtx val, mem;
6139   enum machine_mode old_mode;
6140
6141   /* Expand the operands.  */
6142   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6143   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
6144   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
6145      of CONST_INTs, where we know the old_mode only from the call argument.  */
6146   old_mode = GET_MODE (val);
6147   if (old_mode == VOIDmode)
6148     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
6149   val = convert_modes (mode, old_mode, val, 1);
6150
6151   return expand_sync_lock_test_and_set (mem, val, target);
6152 }
6153
6154 /* Expand the __sync_synchronize intrinsic.  */
6155
6156 static void
6157 expand_builtin_synchronize (void)
6158 {
6159   tree x;
6160
6161 #ifdef HAVE_memory_barrier
6162   if (HAVE_memory_barrier)
6163     {
6164       emit_insn (gen_memory_barrier ());
6165       return;
6166     }
6167 #endif
6168
6169   if (synchronize_libfunc != NULL_RTX)
6170     {
6171       emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6172       return;
6173     }
6174
6175   /* If no explicit memory barrier instruction is available, create an
6176      empty asm stmt with a memory clobber.  */
6177   x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
6178               tree_cons (NULL, build_string (6, "memory"), NULL));
6179   ASM_VOLATILE_P (x) = 1;
6180   expand_asm_expr (x);
6181 }
6182
6183 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
6184
6185 static void
6186 expand_builtin_lock_release (enum machine_mode mode, tree exp)
6187 {
6188   enum insn_code icode;
6189   rtx mem, insn;
6190   rtx val = const0_rtx;
6191
6192   /* Expand the operands.  */
6193   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
6194
6195   /* If there is an explicit operation in the md file, use it.  */
6196   icode = sync_lock_release[mode];
6197   if (icode != CODE_FOR_nothing)
6198     {
6199       if (!insn_data[icode].operand[1].predicate (val, mode))
6200         val = force_reg (mode, val);
6201
6202       insn = GEN_FCN (icode) (mem, val);
6203       if (insn)
6204         {
6205           emit_insn (insn);
6206           return;
6207         }
6208     }
6209
6210   /* Otherwise we can implement this operation by emitting a barrier
6211      followed by a store of zero.  */
6212   expand_builtin_synchronize ();
6213   emit_move_insn (mem, val);
6214 }
6215 \f
6216 /* Expand an expression EXP that calls a built-in function,
6217    with result going to TARGET if that's convenient
6218    (and in mode MODE if that's convenient).
6219    SUBTARGET may be used as the target for computing one of EXP's operands.
6220    IGNORE is nonzero if the value is to be ignored.  */
6221
6222 rtx
6223 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
6224                 int ignore)
6225 {
6226   tree fndecl = get_callee_fndecl (exp);
6227   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6228   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
6229
6230   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6231     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
6232
6233   /* When not optimizing, generate calls to library functions for a certain
6234      set of builtins.  */
6235   if (!optimize
6236       && !called_as_built_in (fndecl)
6237       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
6238       && fcode != BUILT_IN_ALLOCA
6239       && fcode != BUILT_IN_FREE)
6240     return expand_call (exp, target, ignore);
6241
6242   /* The built-in function expanders test for target == const0_rtx
6243      to determine whether the function's result will be ignored.  */
6244   if (ignore)
6245     target = const0_rtx;
6246
6247   /* If the result of a pure or const built-in function is ignored, and
6248      none of its arguments are volatile, we can avoid expanding the
6249      built-in call and just evaluate the arguments for side-effects.  */
6250   if (target == const0_rtx
6251       && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
6252     {
6253       bool volatilep = false;
6254       tree arg;
6255       call_expr_arg_iterator iter;
6256
6257       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6258         if (TREE_THIS_VOLATILE (arg))
6259           {
6260             volatilep = true;
6261             break;
6262           }
6263
6264       if (! volatilep)
6265         {
6266           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6267             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
6268           return const0_rtx;
6269         }
6270     }
6271
6272   switch (fcode)
6273     {
6274     CASE_FLT_FN (BUILT_IN_FABS):
6275       target = expand_builtin_fabs (exp, target, subtarget);
6276       if (target)
6277         return target;
6278       break;
6279
6280     CASE_FLT_FN (BUILT_IN_COPYSIGN):
6281       target = expand_builtin_copysign (exp, target, subtarget);
6282       if (target)
6283         return target;
6284       break;
6285
6286       /* Just do a normal library call if we were unable to fold
6287          the values.  */
6288     CASE_FLT_FN (BUILT_IN_CABS):
6289       break;
6290
6291     CASE_FLT_FN (BUILT_IN_EXP):
6292     CASE_FLT_FN (BUILT_IN_EXP10):
6293     CASE_FLT_FN (BUILT_IN_POW10):
6294     CASE_FLT_FN (BUILT_IN_EXP2):
6295     CASE_FLT_FN (BUILT_IN_EXPM1):
6296     CASE_FLT_FN (BUILT_IN_LOGB):
6297     CASE_FLT_FN (BUILT_IN_LOG):
6298     CASE_FLT_FN (BUILT_IN_LOG10):
6299     CASE_FLT_FN (BUILT_IN_LOG2):
6300     CASE_FLT_FN (BUILT_IN_LOG1P):
6301     CASE_FLT_FN (BUILT_IN_TAN):
6302     CASE_FLT_FN (BUILT_IN_ASIN):
6303     CASE_FLT_FN (BUILT_IN_ACOS):
6304     CASE_FLT_FN (BUILT_IN_ATAN):
6305       /* Treat these like sqrt only if unsafe math optimizations are allowed,
6306          because of possible accuracy problems.  */
6307       if (! flag_unsafe_math_optimizations)
6308         break;
6309     CASE_FLT_FN (BUILT_IN_SQRT):
6310     CASE_FLT_FN (BUILT_IN_FLOOR):
6311     CASE_FLT_FN (BUILT_IN_CEIL):
6312     CASE_FLT_FN (BUILT_IN_TRUNC):
6313     CASE_FLT_FN (BUILT_IN_ROUND):
6314     CASE_FLT_FN (BUILT_IN_NEARBYINT):
6315     CASE_FLT_FN (BUILT_IN_RINT):
6316       target = expand_builtin_mathfn (exp, target, subtarget);
6317       if (target)
6318         return target;
6319       break;
6320
6321     CASE_FLT_FN (BUILT_IN_ILOGB):
6322       if (! flag_unsafe_math_optimizations)
6323         break;
6324     CASE_FLT_FN (BUILT_IN_ISINF):
6325     CASE_FLT_FN (BUILT_IN_FINITE):
6326     case BUILT_IN_ISFINITE:
6327     case BUILT_IN_ISNORMAL:
6328       target = expand_builtin_interclass_mathfn (exp, target, subtarget);
6329       if (target)
6330         return target;
6331       break;
6332
6333     CASE_FLT_FN (BUILT_IN_LCEIL):
6334     CASE_FLT_FN (BUILT_IN_LLCEIL):
6335     CASE_FLT_FN (BUILT_IN_LFLOOR):
6336     CASE_FLT_FN (BUILT_IN_LLFLOOR):
6337       target = expand_builtin_int_roundingfn (exp, target);
6338       if (target)
6339         return target;
6340       break;
6341
6342     CASE_FLT_FN (BUILT_IN_LRINT):
6343     CASE_FLT_FN (BUILT_IN_LLRINT):
6344     CASE_FLT_FN (BUILT_IN_LROUND):
6345     CASE_FLT_FN (BUILT_IN_LLROUND):
6346       target = expand_builtin_int_roundingfn_2 (exp, target);
6347       if (target)
6348         return target;
6349       break;
6350
6351     CASE_FLT_FN (BUILT_IN_POW):
6352       target = expand_builtin_pow (exp, target, subtarget);
6353       if (target)
6354         return target;
6355       break;
6356
6357     CASE_FLT_FN (BUILT_IN_POWI):
6358       target = expand_builtin_powi (exp, target, subtarget);
6359       if (target)
6360         return target;
6361       break;
6362
6363     CASE_FLT_FN (BUILT_IN_ATAN2):
6364     CASE_FLT_FN (BUILT_IN_LDEXP):
6365     CASE_FLT_FN (BUILT_IN_SCALB):
6366     CASE_FLT_FN (BUILT_IN_SCALBN):
6367     CASE_FLT_FN (BUILT_IN_SCALBLN):
6368       if (! flag_unsafe_math_optimizations)
6369         break;
6370
6371     CASE_FLT_FN (BUILT_IN_FMOD):
6372     CASE_FLT_FN (BUILT_IN_REMAINDER):
6373     CASE_FLT_FN (BUILT_IN_DREM):
6374       target = expand_builtin_mathfn_2 (exp, target, subtarget);
6375       if (target)
6376         return target;
6377       break;
6378
6379     CASE_FLT_FN (BUILT_IN_CEXPI):
6380       target = expand_builtin_cexpi (exp, target, subtarget);
6381       gcc_assert (target);
6382       return target;
6383
6384     CASE_FLT_FN (BUILT_IN_SIN):
6385     CASE_FLT_FN (BUILT_IN_COS):
6386       if (! flag_unsafe_math_optimizations)
6387         break;
6388       target = expand_builtin_mathfn_3 (exp, target, subtarget);
6389       if (target)
6390         return target;
6391       break;
6392
6393     CASE_FLT_FN (BUILT_IN_SINCOS):
6394       if (! flag_unsafe_math_optimizations)
6395         break;
6396       target = expand_builtin_sincos (exp);
6397       if (target)
6398         return target;
6399       break;
6400
6401     case BUILT_IN_APPLY_ARGS:
6402       return expand_builtin_apply_args ();
6403
6404       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6405          FUNCTION with a copy of the parameters described by
6406          ARGUMENTS, and ARGSIZE.  It returns a block of memory
6407          allocated on the stack into which is stored all the registers
6408          that might possibly be used for returning the result of a
6409          function.  ARGUMENTS is the value returned by
6410          __builtin_apply_args.  ARGSIZE is the number of bytes of
6411          arguments that must be copied.  ??? How should this value be
6412          computed?  We'll also need a safe worst case value for varargs
6413          functions.  */
6414     case BUILT_IN_APPLY:
6415       if (!validate_arglist (exp, POINTER_TYPE,
6416                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
6417           && !validate_arglist (exp, REFERENCE_TYPE,
6418                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6419         return const0_rtx;
6420       else
6421         {
6422           rtx ops[3];
6423
6424           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6425           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6426           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6427
6428           return expand_builtin_apply (ops[0], ops[1], ops[2]);
6429         }
6430
6431       /* __builtin_return (RESULT) causes the function to return the
6432          value described by RESULT.  RESULT is address of the block of
6433          memory returned by __builtin_apply.  */
6434     case BUILT_IN_RETURN:
6435       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6436         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6437       return const0_rtx;
6438
6439     case BUILT_IN_SAVEREGS:
6440       return expand_builtin_saveregs ();
6441
6442     case BUILT_IN_ARGS_INFO:
6443       return expand_builtin_args_info (exp);
6444
6445     case BUILT_IN_VA_ARG_PACK:
6446       /* All valid uses of __builtin_va_arg_pack () are removed during
6447          inlining.  */
6448       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6449       return const0_rtx;
6450
6451     case BUILT_IN_VA_ARG_PACK_LEN:
6452       /* All valid uses of __builtin_va_arg_pack_len () are removed during
6453          inlining.  */
6454       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6455       return const0_rtx;
6456
6457       /* Return the address of the first anonymous stack arg.  */
6458     case BUILT_IN_NEXT_ARG:
6459       if (fold_builtin_next_arg (exp, false))
6460         return const0_rtx;
6461       return expand_builtin_next_arg ();
6462
6463     case BUILT_IN_CLEAR_CACHE:
6464       target = expand_builtin___clear_cache (exp);
6465       if (target)
6466         return target;
6467       break;
6468
6469     case BUILT_IN_CLASSIFY_TYPE:
6470       return expand_builtin_classify_type (exp);
6471
6472     case BUILT_IN_CONSTANT_P:
6473       return const0_rtx;
6474
6475     case BUILT_IN_FRAME_ADDRESS:
6476     case BUILT_IN_RETURN_ADDRESS:
6477       return expand_builtin_frame_address (fndecl, exp);
6478
6479     /* Returns the address of the area where the structure is returned.
6480        0 otherwise.  */
6481     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6482       if (call_expr_nargs (exp) != 0
6483           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6484           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6485         return const0_rtx;
6486       else
6487         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6488
6489     case BUILT_IN_ALLOCA:
6490       target = expand_builtin_alloca (exp, target);
6491       if (target)
6492         return target;
6493       break;
6494
6495     case BUILT_IN_STACK_SAVE:
6496       return expand_stack_save ();
6497
6498     case BUILT_IN_STACK_RESTORE:
6499       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6500       return const0_rtx;
6501
6502     case BUILT_IN_BSWAP32:
6503     case BUILT_IN_BSWAP64:
6504       target = expand_builtin_bswap (exp, target, subtarget);
6505
6506       if (target)
6507         return target;
6508       break;
6509
6510     CASE_INT_FN (BUILT_IN_FFS):
6511     case BUILT_IN_FFSIMAX:
6512       target = expand_builtin_unop (target_mode, exp, target,
6513                                     subtarget, ffs_optab);
6514       if (target)
6515         return target;
6516       break;
6517
6518     CASE_INT_FN (BUILT_IN_CLZ):
6519     case BUILT_IN_CLZIMAX:
6520       target = expand_builtin_unop (target_mode, exp, target,
6521                                     subtarget, clz_optab);
6522       if (target)
6523         return target;
6524       break;
6525
6526     CASE_INT_FN (BUILT_IN_CTZ):
6527     case BUILT_IN_CTZIMAX:
6528       target = expand_builtin_unop (target_mode, exp, target,
6529                                     subtarget, ctz_optab);
6530       if (target)
6531         return target;
6532       break;
6533
6534     CASE_INT_FN (BUILT_IN_POPCOUNT):
6535     case BUILT_IN_POPCOUNTIMAX:
6536       target = expand_builtin_unop (target_mode, exp, target,
6537                                     subtarget, popcount_optab);
6538       if (target)
6539         return target;
6540       break;
6541
6542     CASE_INT_FN (BUILT_IN_PARITY):
6543     case BUILT_IN_PARITYIMAX:
6544       target = expand_builtin_unop (target_mode, exp, target,
6545                                     subtarget, parity_optab);
6546       if (target)
6547         return target;
6548       break;
6549
6550     case BUILT_IN_STRLEN:
6551       target = expand_builtin_strlen (exp, target, target_mode);
6552       if (target)
6553         return target;
6554       break;
6555
6556     case BUILT_IN_STRCPY:
6557       target = expand_builtin_strcpy (fndecl, exp, target, mode);
6558       if (target)
6559         return target;
6560       break;
6561
6562     case BUILT_IN_STRNCPY:
6563       target = expand_builtin_strncpy (exp, target, mode);
6564       if (target)
6565         return target;
6566       break;
6567
6568     case BUILT_IN_STPCPY:
6569       target = expand_builtin_stpcpy (exp, target, mode);
6570       if (target)
6571         return target;
6572       break;
6573
6574     case BUILT_IN_STRCAT:
6575       target = expand_builtin_strcat (fndecl, exp, target, mode);
6576       if (target)
6577         return target;
6578       break;
6579
6580     case BUILT_IN_STRNCAT:
6581       target = expand_builtin_strncat (exp, target, mode);
6582       if (target)
6583         return target;
6584       break;
6585
6586     case BUILT_IN_STRSPN:
6587       target = expand_builtin_strspn (exp, target, mode);
6588       if (target)
6589         return target;
6590       break;
6591
6592     case BUILT_IN_STRCSPN:
6593       target = expand_builtin_strcspn (exp, target, mode);
6594       if (target)
6595         return target;
6596       break;
6597
6598     case BUILT_IN_STRSTR:
6599       target = expand_builtin_strstr (exp, target, mode);
6600       if (target)
6601         return target;
6602       break;
6603
6604     case BUILT_IN_STRPBRK:
6605       target = expand_builtin_strpbrk (exp, target, mode);
6606       if (target)
6607         return target;
6608       break;
6609
6610     case BUILT_IN_INDEX:
6611     case BUILT_IN_STRCHR:
6612       target = expand_builtin_strchr (exp, target, mode);
6613       if (target)
6614         return target;
6615       break;
6616
6617     case BUILT_IN_RINDEX:
6618     case BUILT_IN_STRRCHR:
6619       target = expand_builtin_strrchr (exp, target, mode);
6620       if (target)
6621         return target;
6622       break;
6623
6624     case BUILT_IN_MEMCPY:
6625       target = expand_builtin_memcpy (exp, target, mode);
6626       if (target)
6627         return target;
6628       break;
6629
6630     case BUILT_IN_MEMPCPY:
6631       target = expand_builtin_mempcpy (exp, target, mode);
6632       if (target)
6633         return target;
6634       break;
6635
6636     case BUILT_IN_MEMMOVE:
6637       target = expand_builtin_memmove (exp, target, mode, ignore);
6638       if (target)
6639         return target;
6640       break;
6641
6642     case BUILT_IN_BCOPY:
6643       target = expand_builtin_bcopy (exp, ignore);
6644       if (target)
6645         return target;
6646       break;
6647
6648     case BUILT_IN_MEMSET:
6649       target = expand_builtin_memset (exp, target, mode);
6650       if (target)
6651         return target;
6652       break;
6653
6654     case BUILT_IN_BZERO:
6655       target = expand_builtin_bzero (exp);
6656       if (target)
6657         return target;
6658       break;
6659
6660     case BUILT_IN_STRCMP:
6661       target = expand_builtin_strcmp (exp, target, mode);
6662       if (target)
6663         return target;
6664       break;
6665
6666     case BUILT_IN_STRNCMP:
6667       target = expand_builtin_strncmp (exp, target, mode);
6668       if (target)
6669         return target;
6670       break;
6671
6672     case BUILT_IN_MEMCHR:
6673       target = expand_builtin_memchr (exp, target, mode);
6674       if (target)
6675         return target;
6676       break;
6677
6678     case BUILT_IN_BCMP:
6679     case BUILT_IN_MEMCMP:
6680       target = expand_builtin_memcmp (exp, target, mode);
6681       if (target)
6682         return target;
6683       break;
6684
6685     case BUILT_IN_SETJMP:
6686       /* This should have been lowered to the builtins below.  */
6687       gcc_unreachable ();
6688
6689     case BUILT_IN_SETJMP_SETUP:
6690       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6691           and the receiver label.  */
6692       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6693         {
6694           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6695                                       VOIDmode, EXPAND_NORMAL);
6696           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6697           rtx label_r = label_rtx (label);
6698
6699           /* This is copied from the handling of non-local gotos.  */
6700           expand_builtin_setjmp_setup (buf_addr, label_r);
6701           nonlocal_goto_handler_labels
6702             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6703                                  nonlocal_goto_handler_labels);
6704           /* ??? Do not let expand_label treat us as such since we would
6705              not want to be both on the list of non-local labels and on
6706              the list of forced labels.  */
6707           FORCED_LABEL (label) = 0;
6708           return const0_rtx;
6709         }
6710       break;
6711
6712     case BUILT_IN_SETJMP_DISPATCHER:
6713        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6714       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6715         {
6716           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6717           rtx label_r = label_rtx (label);
6718
6719           /* Remove the dispatcher label from the list of non-local labels
6720              since the receiver labels have been added to it above.  */
6721           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6722           return const0_rtx;
6723         }
6724       break;
6725
6726     case BUILT_IN_SETJMP_RECEIVER:
6727        /* __builtin_setjmp_receiver is passed the receiver label.  */
6728       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6729         {
6730           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6731           rtx label_r = label_rtx (label);
6732
6733           expand_builtin_setjmp_receiver (label_r);
6734           return const0_rtx;
6735         }
6736       break;
6737
6738       /* __builtin_longjmp is passed a pointer to an array of five words.
6739          It's similar to the C library longjmp function but works with
6740          __builtin_setjmp above.  */
6741     case BUILT_IN_LONGJMP:
6742       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6743         {
6744           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6745                                       VOIDmode, EXPAND_NORMAL);
6746           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6747
6748           if (value != const1_rtx)
6749             {
6750               error ("%<__builtin_longjmp%> second argument must be 1");
6751               return const0_rtx;
6752             }
6753
6754           expand_builtin_longjmp (buf_addr, value);
6755           return const0_rtx;
6756         }
6757       break;
6758
6759     case BUILT_IN_NONLOCAL_GOTO:
6760       target = expand_builtin_nonlocal_goto (exp);
6761       if (target)
6762         return target;
6763       break;
6764
6765       /* This updates the setjmp buffer that is its argument with the value
6766          of the current stack pointer.  */
6767     case BUILT_IN_UPDATE_SETJMP_BUF:
6768       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6769         {
6770           rtx buf_addr
6771             = expand_normal (CALL_EXPR_ARG (exp, 0));
6772
6773           expand_builtin_update_setjmp_buf (buf_addr);
6774           return const0_rtx;
6775         }
6776       break;
6777
6778     case BUILT_IN_TRAP:
6779       expand_builtin_trap ();
6780       return const0_rtx;
6781
6782     case BUILT_IN_PRINTF:
6783       target = expand_builtin_printf (exp, target, mode, false);
6784       if (target)
6785         return target;
6786       break;
6787
6788     case BUILT_IN_PRINTF_UNLOCKED:
6789       target = expand_builtin_printf (exp, target, mode, true);
6790       if (target)
6791         return target;
6792       break;
6793
6794     case BUILT_IN_FPUTS:
6795       target = expand_builtin_fputs (exp, target, false);
6796       if (target)
6797         return target;
6798       break;
6799     case BUILT_IN_FPUTS_UNLOCKED:
6800       target = expand_builtin_fputs (exp, target, true);
6801       if (target)
6802         return target;
6803       break;
6804
6805     case BUILT_IN_FPRINTF:
6806       target = expand_builtin_fprintf (exp, target, mode, false);
6807       if (target)
6808         return target;
6809       break;
6810
6811     case BUILT_IN_FPRINTF_UNLOCKED:
6812       target = expand_builtin_fprintf (exp, target, mode, true);
6813       if (target)
6814         return target;
6815       break;
6816
6817     case BUILT_IN_SPRINTF:
6818       target = expand_builtin_sprintf (exp, target, mode);
6819       if (target)
6820         return target;
6821       break;
6822
6823     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6824     case BUILT_IN_SIGNBITD32:
6825     case BUILT_IN_SIGNBITD64:
6826     case BUILT_IN_SIGNBITD128:
6827       target = expand_builtin_signbit (exp, target);
6828       if (target)
6829         return target;
6830       break;
6831
6832       /* Various hooks for the DWARF 2 __throw routine.  */
6833     case BUILT_IN_UNWIND_INIT:
6834       expand_builtin_unwind_init ();
6835       return const0_rtx;
6836     case BUILT_IN_DWARF_CFA:
6837       return virtual_cfa_rtx;
6838 #ifdef DWARF2_UNWIND_INFO
6839     case BUILT_IN_DWARF_SP_COLUMN:
6840       return expand_builtin_dwarf_sp_column ();
6841     case BUILT_IN_INIT_DWARF_REG_SIZES:
6842       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6843       return const0_rtx;
6844 #endif
6845     case BUILT_IN_FROB_RETURN_ADDR:
6846       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6847     case BUILT_IN_EXTRACT_RETURN_ADDR:
6848       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6849     case BUILT_IN_EH_RETURN:
6850       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6851                                 CALL_EXPR_ARG (exp, 1));
6852       return const0_rtx;
6853 #ifdef EH_RETURN_DATA_REGNO
6854     case BUILT_IN_EH_RETURN_DATA_REGNO:
6855       return expand_builtin_eh_return_data_regno (exp);
6856 #endif
6857     case BUILT_IN_EXTEND_POINTER:
6858       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6859
6860     case BUILT_IN_VA_START:
6861       return expand_builtin_va_start (exp);
6862     case BUILT_IN_VA_END:
6863       return expand_builtin_va_end (exp);
6864     case BUILT_IN_VA_COPY:
6865       return expand_builtin_va_copy (exp);
6866     case BUILT_IN_EXPECT:
6867       return expand_builtin_expect (exp, target);
6868     case BUILT_IN_PREFETCH:
6869       expand_builtin_prefetch (exp);
6870       return const0_rtx;
6871
6872     case BUILT_IN_PROFILE_FUNC_ENTER:
6873       return expand_builtin_profile_func (false);
6874     case BUILT_IN_PROFILE_FUNC_EXIT:
6875       return expand_builtin_profile_func (true);
6876
6877     case BUILT_IN_INIT_TRAMPOLINE:
6878       return expand_builtin_init_trampoline (exp);
6879     case BUILT_IN_ADJUST_TRAMPOLINE:
6880       return expand_builtin_adjust_trampoline (exp);
6881
6882     case BUILT_IN_FORK:
6883     case BUILT_IN_EXECL:
6884     case BUILT_IN_EXECV:
6885     case BUILT_IN_EXECLP:
6886     case BUILT_IN_EXECLE:
6887     case BUILT_IN_EXECVP:
6888     case BUILT_IN_EXECVE:
6889       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6890       if (target)
6891         return target;
6892       break;
6893
6894     case BUILT_IN_FETCH_AND_ADD_1:
6895     case BUILT_IN_FETCH_AND_ADD_2:
6896     case BUILT_IN_FETCH_AND_ADD_4:
6897     case BUILT_IN_FETCH_AND_ADD_8:
6898     case BUILT_IN_FETCH_AND_ADD_16:
6899       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6900       target = expand_builtin_sync_operation (mode, exp, PLUS,
6901                                               false, target, ignore);
6902       if (target)
6903         return target;
6904       break;
6905
6906     case BUILT_IN_FETCH_AND_SUB_1:
6907     case BUILT_IN_FETCH_AND_SUB_2:
6908     case BUILT_IN_FETCH_AND_SUB_4:
6909     case BUILT_IN_FETCH_AND_SUB_8:
6910     case BUILT_IN_FETCH_AND_SUB_16:
6911       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6912       target = expand_builtin_sync_operation (mode, exp, MINUS,
6913                                               false, target, ignore);
6914       if (target)
6915         return target;
6916       break;
6917
6918     case BUILT_IN_FETCH_AND_OR_1:
6919     case BUILT_IN_FETCH_AND_OR_2:
6920     case BUILT_IN_FETCH_AND_OR_4:
6921     case BUILT_IN_FETCH_AND_OR_8:
6922     case BUILT_IN_FETCH_AND_OR_16:
6923       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6924       target = expand_builtin_sync_operation (mode, exp, IOR,
6925                                               false, target, ignore);
6926       if (target)
6927         return target;
6928       break;
6929
6930     case BUILT_IN_FETCH_AND_AND_1:
6931     case BUILT_IN_FETCH_AND_AND_2:
6932     case BUILT_IN_FETCH_AND_AND_4:
6933     case BUILT_IN_FETCH_AND_AND_8:
6934     case BUILT_IN_FETCH_AND_AND_16:
6935       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6936       target = expand_builtin_sync_operation (mode, exp, AND,
6937                                               false, target, ignore);
6938       if (target)
6939         return target;
6940       break;
6941
6942     case BUILT_IN_FETCH_AND_XOR_1:
6943     case BUILT_IN_FETCH_AND_XOR_2:
6944     case BUILT_IN_FETCH_AND_XOR_4:
6945     case BUILT_IN_FETCH_AND_XOR_8:
6946     case BUILT_IN_FETCH_AND_XOR_16:
6947       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6948       target = expand_builtin_sync_operation (mode, exp, XOR,
6949                                               false, target, ignore);
6950       if (target)
6951         return target;
6952       break;
6953
6954     case BUILT_IN_FETCH_AND_NAND_1:
6955     case BUILT_IN_FETCH_AND_NAND_2:
6956     case BUILT_IN_FETCH_AND_NAND_4:
6957     case BUILT_IN_FETCH_AND_NAND_8:
6958     case BUILT_IN_FETCH_AND_NAND_16:
6959       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6960       target = expand_builtin_sync_operation (mode, exp, NOT,
6961                                               false, target, ignore);
6962       if (target)
6963         return target;
6964       break;
6965
6966     case BUILT_IN_ADD_AND_FETCH_1:
6967     case BUILT_IN_ADD_AND_FETCH_2:
6968     case BUILT_IN_ADD_AND_FETCH_4:
6969     case BUILT_IN_ADD_AND_FETCH_8:
6970     case BUILT_IN_ADD_AND_FETCH_16:
6971       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6972       target = expand_builtin_sync_operation (mode, exp, PLUS,
6973                                               true, target, ignore);
6974       if (target)
6975         return target;
6976       break;
6977
6978     case BUILT_IN_SUB_AND_FETCH_1:
6979     case BUILT_IN_SUB_AND_FETCH_2:
6980     case BUILT_IN_SUB_AND_FETCH_4:
6981     case BUILT_IN_SUB_AND_FETCH_8:
6982     case BUILT_IN_SUB_AND_FETCH_16:
6983       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6984       target = expand_builtin_sync_operation (mode, exp, MINUS,
6985                                               true, target, ignore);
6986       if (target)
6987         return target;
6988       break;
6989
6990     case BUILT_IN_OR_AND_FETCH_1:
6991     case BUILT_IN_OR_AND_FETCH_2:
6992     case BUILT_IN_OR_AND_FETCH_4:
6993     case BUILT_IN_OR_AND_FETCH_8:
6994     case BUILT_IN_OR_AND_FETCH_16:
6995       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6996       target = expand_builtin_sync_operation (mode, exp, IOR,
6997                                               true, target, ignore);
6998       if (target)
6999         return target;
7000       break;
7001
7002     case BUILT_IN_AND_AND_FETCH_1:
7003     case BUILT_IN_AND_AND_FETCH_2:
7004     case BUILT_IN_AND_AND_FETCH_4:
7005     case BUILT_IN_AND_AND_FETCH_8:
7006     case BUILT_IN_AND_AND_FETCH_16:
7007       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
7008       target = expand_builtin_sync_operation (mode, exp, AND,
7009                                               true, target, ignore);
7010       if (target)
7011         return target;
7012       break;
7013
7014     case BUILT_IN_XOR_AND_FETCH_1:
7015     case BUILT_IN_XOR_AND_FETCH_2:
7016     case BUILT_IN_XOR_AND_FETCH_4:
7017     case BUILT_IN_XOR_AND_FETCH_8:
7018     case BUILT_IN_XOR_AND_FETCH_16:
7019       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
7020       target = expand_builtin_sync_operation (mode, exp, XOR,
7021                                               true, target, ignore);
7022       if (target)
7023         return target;
7024       break;
7025
7026     case BUILT_IN_NAND_AND_FETCH_1:
7027     case BUILT_IN_NAND_AND_FETCH_2:
7028     case BUILT_IN_NAND_AND_FETCH_4:
7029     case BUILT_IN_NAND_AND_FETCH_8:
7030     case BUILT_IN_NAND_AND_FETCH_16:
7031       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
7032       target = expand_builtin_sync_operation (mode, exp, NOT,
7033                                               true, target, ignore);
7034       if (target)
7035         return target;
7036       break;
7037
7038     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
7039     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
7040     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
7041     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
7042     case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
7043       if (mode == VOIDmode)
7044         mode = TYPE_MODE (boolean_type_node);
7045       if (!target || !register_operand (target, mode))
7046         target = gen_reg_rtx (mode);
7047
7048       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
7049       target = expand_builtin_compare_and_swap (mode, exp, true, target);
7050       if (target)
7051         return target;
7052       break;
7053
7054     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
7055     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
7056     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
7057     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
7058     case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
7059       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
7060       target = expand_builtin_compare_and_swap (mode, exp, false, target);
7061       if (target)
7062         return target;
7063       break;
7064
7065     case BUILT_IN_LOCK_TEST_AND_SET_1:
7066     case BUILT_IN_LOCK_TEST_AND_SET_2:
7067     case BUILT_IN_LOCK_TEST_AND_SET_4:
7068     case BUILT_IN_LOCK_TEST_AND_SET_8:
7069     case BUILT_IN_LOCK_TEST_AND_SET_16:
7070       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
7071       target = expand_builtin_lock_test_and_set (mode, exp, target);
7072       if (target)
7073         return target;
7074       break;
7075
7076     case BUILT_IN_LOCK_RELEASE_1:
7077     case BUILT_IN_LOCK_RELEASE_2:
7078     case BUILT_IN_LOCK_RELEASE_4:
7079     case BUILT_IN_LOCK_RELEASE_8:
7080     case BUILT_IN_LOCK_RELEASE_16:
7081       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
7082       expand_builtin_lock_release (mode, exp);
7083       return const0_rtx;
7084
7085     case BUILT_IN_SYNCHRONIZE:
7086       expand_builtin_synchronize ();
7087       return const0_rtx;
7088
7089     case BUILT_IN_OBJECT_SIZE:
7090       return expand_builtin_object_size (exp);
7091
7092     case BUILT_IN_MEMCPY_CHK:
7093     case BUILT_IN_MEMPCPY_CHK:
7094     case BUILT_IN_MEMMOVE_CHK:
7095     case BUILT_IN_MEMSET_CHK:
7096       target = expand_builtin_memory_chk (exp, target, mode, fcode);
7097       if (target)
7098         return target;
7099       break;
7100
7101     case BUILT_IN_STRCPY_CHK:
7102     case BUILT_IN_STPCPY_CHK:
7103     case BUILT_IN_STRNCPY_CHK:
7104     case BUILT_IN_STRCAT_CHK:
7105     case BUILT_IN_STRNCAT_CHK:
7106     case BUILT_IN_SNPRINTF_CHK:
7107     case BUILT_IN_VSNPRINTF_CHK:
7108       maybe_emit_chk_warning (exp, fcode);
7109       break;
7110
7111     case BUILT_IN_SPRINTF_CHK:
7112     case BUILT_IN_VSPRINTF_CHK:
7113       maybe_emit_sprintf_chk_warning (exp, fcode);
7114       break;
7115
7116     case BUILT_IN_FREE:
7117       maybe_emit_free_warning (exp);
7118       break;
7119
7120     default:    /* just do library call, if unknown builtin */
7121       break;
7122     }
7123
7124   /* The switch statement above can drop through to cause the function
7125      to be called normally.  */
7126   return expand_call (exp, target, ignore);
7127 }
7128
7129 /* Determine whether a tree node represents a call to a built-in
7130    function.  If the tree T is a call to a built-in function with
7131    the right number of arguments of the appropriate types, return
7132    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
7133    Otherwise the return value is END_BUILTINS.  */
7134
7135 enum built_in_function
7136 builtin_mathfn_code (const_tree t)
7137 {
7138   const_tree fndecl, arg, parmlist;
7139   const_tree argtype, parmtype;
7140   const_call_expr_arg_iterator iter;
7141
7142   if (TREE_CODE (t) != CALL_EXPR
7143       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
7144     return END_BUILTINS;
7145
7146   fndecl = get_callee_fndecl (t);
7147   if (fndecl == NULL_TREE
7148       || TREE_CODE (fndecl) != FUNCTION_DECL
7149       || ! DECL_BUILT_IN (fndecl)
7150       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7151     return END_BUILTINS;
7152
7153   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
7154   init_const_call_expr_arg_iterator (t, &iter);
7155   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
7156     {
7157       /* If a function doesn't take a variable number of arguments,
7158          the last element in the list will have type `void'.  */
7159       parmtype = TREE_VALUE (parmlist);
7160       if (VOID_TYPE_P (parmtype))
7161         {
7162           if (more_const_call_expr_args_p (&iter))
7163             return END_BUILTINS;
7164           return DECL_FUNCTION_CODE (fndecl);
7165         }
7166
7167       if (! more_const_call_expr_args_p (&iter))
7168         return END_BUILTINS;
7169       
7170       arg = next_const_call_expr_arg (&iter);
7171       argtype = TREE_TYPE (arg);
7172
7173       if (SCALAR_FLOAT_TYPE_P (parmtype))
7174         {
7175           if (! SCALAR_FLOAT_TYPE_P (argtype))
7176             return END_BUILTINS;
7177         }
7178       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
7179         {
7180           if (! COMPLEX_FLOAT_TYPE_P (argtype))
7181             return END_BUILTINS;
7182         }
7183       else if (POINTER_TYPE_P (parmtype))
7184         {
7185           if (! POINTER_TYPE_P (argtype))
7186             return END_BUILTINS;
7187         }
7188       else if (INTEGRAL_TYPE_P (parmtype))
7189         {
7190           if (! INTEGRAL_TYPE_P (argtype))
7191             return END_BUILTINS;
7192         }
7193       else
7194         return END_BUILTINS;
7195     }
7196
7197   /* Variable-length argument list.  */
7198   return DECL_FUNCTION_CODE (fndecl);
7199 }
7200
7201 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
7202    evaluate to a constant.  */
7203
7204 static tree
7205 fold_builtin_constant_p (tree arg)
7206 {
7207   /* We return 1 for a numeric type that's known to be a constant
7208      value at compile-time or for an aggregate type that's a
7209      literal constant.  */
7210   STRIP_NOPS (arg);
7211
7212   /* If we know this is a constant, emit the constant of one.  */
7213   if (CONSTANT_CLASS_P (arg)
7214       || (TREE_CODE (arg) == CONSTRUCTOR
7215           && TREE_CONSTANT (arg)))
7216     return integer_one_node;
7217   if (TREE_CODE (arg) == ADDR_EXPR)
7218     {
7219        tree op = TREE_OPERAND (arg, 0);
7220        if (TREE_CODE (op) == STRING_CST
7221            || (TREE_CODE (op) == ARRAY_REF
7222                && integer_zerop (TREE_OPERAND (op, 1))
7223                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
7224          return integer_one_node;
7225     }
7226
7227   /* If this expression has side effects, show we don't know it to be a
7228      constant.  Likewise if it's a pointer or aggregate type since in
7229      those case we only want literals, since those are only optimized
7230      when generating RTL, not later.
7231      And finally, if we are compiling an initializer, not code, we
7232      need to return a definite result now; there's not going to be any
7233      more optimization done.  */
7234   if (TREE_SIDE_EFFECTS (arg)
7235       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
7236       || POINTER_TYPE_P (TREE_TYPE (arg))
7237       || cfun == 0
7238       || folding_initializer)
7239     return integer_zero_node;
7240
7241   return NULL_TREE;
7242 }
7243
7244 /* Create builtin_expect with PRED and EXPECTED as its arguments and
7245    return it as a truthvalue.  */
7246
7247 static tree
7248 build_builtin_expect_predicate (tree pred, tree expected)
7249 {
7250   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
7251
7252   fn = built_in_decls[BUILT_IN_EXPECT];
7253   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
7254   ret_type = TREE_TYPE (TREE_TYPE (fn));
7255   pred_type = TREE_VALUE (arg_types);
7256   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
7257
7258   pred = fold_convert (pred_type, pred);
7259   expected = fold_convert (expected_type, expected);
7260   call_expr = build_call_expr (fn, 2, pred, expected);
7261
7262   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
7263                  build_int_cst (ret_type, 0));
7264 }
7265
7266 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
7267    NULL_TREE if no simplification is possible.  */
7268
7269 static tree
7270 fold_builtin_expect (tree arg0, tree arg1)
7271 {
7272   tree inner, fndecl;
7273   enum tree_code code;
7274
7275   /* If this is a builtin_expect within a builtin_expect keep the
7276      inner one.  See through a comparison against a constant.  It
7277      might have been added to create a thruthvalue.  */
7278   inner = arg0;
7279   if (COMPARISON_CLASS_P (inner)
7280       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
7281     inner = TREE_OPERAND (inner, 0);
7282
7283   if (TREE_CODE (inner) == CALL_EXPR
7284       && (fndecl = get_callee_fndecl (inner))
7285       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
7286       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
7287     return arg0;
7288
7289   /* Distribute the expected value over short-circuiting operators.
7290      See through the cast from truthvalue_type_node to long.  */
7291   inner = arg0;
7292   while (TREE_CODE (inner) == NOP_EXPR
7293          && INTEGRAL_TYPE_P (TREE_TYPE (inner))
7294          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
7295     inner = TREE_OPERAND (inner, 0);
7296
7297   code = TREE_CODE (inner);
7298   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
7299     {
7300       tree op0 = TREE_OPERAND (inner, 0);
7301       tree op1 = TREE_OPERAND (inner, 1);
7302
7303       op0 = build_builtin_expect_predicate (op0, arg1);
7304       op1 = build_builtin_expect_predicate (op1, arg1);
7305       inner = build2 (code, TREE_TYPE (inner), op0, op1);
7306
7307       return fold_convert (TREE_TYPE (arg0), inner);
7308     }
7309
7310   /* If the argument isn't invariant then there's nothing else we can do.  */
7311   if (!TREE_CONSTANT (arg0))
7312     return NULL_TREE;
7313
7314   /* If we expect that a comparison against the argument will fold to
7315      a constant return the constant.  In practice, this means a true
7316      constant or the address of a non-weak symbol.  */
7317   inner = arg0;
7318   STRIP_NOPS (inner);
7319   if (TREE_CODE (inner) == ADDR_EXPR)
7320     {
7321       do
7322         {
7323           inner = TREE_OPERAND (inner, 0);
7324         }
7325       while (TREE_CODE (inner) == COMPONENT_REF
7326              || TREE_CODE (inner) == ARRAY_REF);
7327       if (DECL_P (inner) && DECL_WEAK (inner))
7328         return NULL_TREE;
7329     }
7330
7331   /* Otherwise, ARG0 already has the proper type for the return value.  */
7332   return arg0;
7333 }
7334
7335 /* Fold a call to __builtin_classify_type with argument ARG.  */
7336
7337 static tree
7338 fold_builtin_classify_type (tree arg)
7339 {
7340   if (arg == 0)
7341     return build_int_cst (NULL_TREE, no_type_class);
7342
7343   return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
7344 }
7345
7346 /* Fold a call to __builtin_strlen with argument ARG.  */
7347
7348 static tree
7349 fold_builtin_strlen (tree arg)
7350 {
7351   if (!validate_arg (arg, POINTER_TYPE))
7352     return NULL_TREE;
7353   else
7354     {
7355       tree len = c_strlen (arg, 0);
7356
7357       if (len)
7358         {
7359           /* Convert from the internal "sizetype" type to "size_t".  */
7360           if (size_type_node)
7361             len = fold_convert (size_type_node, len);
7362           return len;
7363         }
7364
7365       return NULL_TREE;
7366     }
7367 }
7368
7369 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
7370
7371 static tree
7372 fold_builtin_inf (tree type, int warn)
7373 {
7374   REAL_VALUE_TYPE real;
7375
7376   /* __builtin_inff is intended to be usable to define INFINITY on all
7377      targets.  If an infinity is not available, INFINITY expands "to a
7378      positive constant of type float that overflows at translation
7379      time", footnote "In this case, using INFINITY will violate the
7380      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
7381      Thus we pedwarn to ensure this constraint violation is
7382      diagnosed.  */
7383   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
7384     pedwarn (input_location, 0, "target format does not support infinity");
7385
7386   real_inf (&real);
7387   return build_real (type, real);
7388 }
7389
7390 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
7391
7392 static tree
7393 fold_builtin_nan (tree arg, tree type, int quiet)
7394 {
7395   REAL_VALUE_TYPE real;
7396   const char *str;
7397
7398   if (!validate_arg (arg, POINTER_TYPE))
7399     return NULL_TREE;
7400   str = c_getstr (arg);
7401   if (!str)
7402     return NULL_TREE;
7403
7404   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
7405     return NULL_TREE;
7406
7407   return build_real (type, real);
7408 }
7409
7410 /* Return true if the floating point expression T has an integer value.
7411    We also allow +Inf, -Inf and NaN to be considered integer values.  */
7412
7413 static bool
7414 integer_valued_real_p (tree t)
7415 {
7416   switch (TREE_CODE (t))
7417     {
7418     case FLOAT_EXPR:
7419       return true;
7420
7421     case ABS_EXPR:
7422     case SAVE_EXPR:
7423       return integer_valued_real_p (TREE_OPERAND (t, 0));
7424
7425     case COMPOUND_EXPR:
7426     case MODIFY_EXPR:
7427     case BIND_EXPR:
7428       return integer_valued_real_p (TREE_OPERAND (t, 1));
7429
7430     case PLUS_EXPR:
7431     case MINUS_EXPR:
7432     case MULT_EXPR:
7433     case MIN_EXPR:
7434     case MAX_EXPR:
7435       return integer_valued_real_p (TREE_OPERAND (t, 0))
7436              && integer_valued_real_p (TREE_OPERAND (t, 1));
7437
7438     case COND_EXPR:
7439       return integer_valued_real_p (TREE_OPERAND (t, 1))
7440              && integer_valued_real_p (TREE_OPERAND (t, 2));
7441
7442     case REAL_CST:
7443       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7444
7445     case NOP_EXPR:
7446       {
7447         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7448         if (TREE_CODE (type) == INTEGER_TYPE)
7449           return true;
7450         if (TREE_CODE (type) == REAL_TYPE)
7451           return integer_valued_real_p (TREE_OPERAND (t, 0));
7452         break;
7453       }
7454
7455     case CALL_EXPR:
7456       switch (builtin_mathfn_code (t))
7457         {
7458         CASE_FLT_FN (BUILT_IN_CEIL):
7459         CASE_FLT_FN (BUILT_IN_FLOOR):
7460         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7461         CASE_FLT_FN (BUILT_IN_RINT):
7462         CASE_FLT_FN (BUILT_IN_ROUND):
7463         CASE_FLT_FN (BUILT_IN_TRUNC):
7464           return true;
7465
7466         CASE_FLT_FN (BUILT_IN_FMIN):
7467         CASE_FLT_FN (BUILT_IN_FMAX):
7468           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7469             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7470
7471         default:
7472           break;
7473         }
7474       break;
7475
7476     default:
7477       break;
7478     }
7479   return false;
7480 }
7481
7482 /* FNDECL is assumed to be a builtin where truncation can be propagated
7483    across (for instance floor((double)f) == (double)floorf (f).
7484    Do the transformation for a call with argument ARG.  */
7485
7486 static tree
7487 fold_trunc_transparent_mathfn (tree fndecl, tree arg)
7488 {
7489   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7490
7491   if (!validate_arg (arg, REAL_TYPE))
7492     return NULL_TREE;
7493
7494   /* Integer rounding functions are idempotent.  */
7495   if (fcode == builtin_mathfn_code (arg))
7496     return arg;
7497
7498   /* If argument is already integer valued, and we don't need to worry
7499      about setting errno, there's no need to perform rounding.  */
7500   if (! flag_errno_math && integer_valued_real_p (arg))
7501     return arg;
7502
7503   if (optimize)
7504     {
7505       tree arg0 = strip_float_extensions (arg);
7506       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7507       tree newtype = TREE_TYPE (arg0);
7508       tree decl;
7509
7510       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7511           && (decl = mathfn_built_in (newtype, fcode)))
7512         return fold_convert (ftype,
7513                              build_call_expr (decl, 1,
7514                                               fold_convert (newtype, arg0)));
7515     }
7516   return NULL_TREE;
7517 }
7518
7519 /* FNDECL is assumed to be builtin which can narrow the FP type of
7520    the argument, for instance lround((double)f) -> lroundf (f).
7521    Do the transformation for a call with argument ARG.  */
7522
7523 static tree
7524 fold_fixed_mathfn (tree fndecl, tree arg)
7525 {
7526   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7527
7528   if (!validate_arg (arg, REAL_TYPE))
7529     return NULL_TREE;
7530
7531   /* If argument is already integer valued, and we don't need to worry
7532      about setting errno, there's no need to perform rounding.  */
7533   if (! flag_errno_math && integer_valued_real_p (arg))
7534     return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
7535
7536   if (optimize)
7537     {
7538       tree ftype = TREE_TYPE (arg);
7539       tree arg0 = strip_float_extensions (arg);
7540       tree newtype = TREE_TYPE (arg0);
7541       tree decl;
7542
7543       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7544           && (decl = mathfn_built_in (newtype, fcode)))
7545         return build_call_expr (decl, 1, fold_convert (newtype, arg0));
7546     }
7547
7548   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7549      sizeof (long long) == sizeof (long).  */
7550   if (TYPE_PRECISION (long_long_integer_type_node)
7551       == TYPE_PRECISION (long_integer_type_node))
7552     {
7553       tree newfn = NULL_TREE;
7554       switch (fcode)
7555         {
7556         CASE_FLT_FN (BUILT_IN_LLCEIL):
7557           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7558           break;
7559
7560         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7561           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7562           break;
7563
7564         CASE_FLT_FN (BUILT_IN_LLROUND):
7565           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7566           break;
7567
7568         CASE_FLT_FN (BUILT_IN_LLRINT):
7569           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7570           break;
7571
7572         default:
7573           break;
7574         }
7575
7576       if (newfn)
7577         {
7578           tree newcall = build_call_expr(newfn, 1, arg);
7579           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7580         }
7581     }
7582
7583   return NULL_TREE;
7584 }
7585
7586 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7587    return type.  Return NULL_TREE if no simplification can be made.  */
7588
7589 static tree
7590 fold_builtin_cabs (tree arg, tree type, tree fndecl)
7591 {
7592   tree res;
7593
7594   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
7595       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7596     return NULL_TREE;
7597
7598   /* Calculate the result when the argument is a constant.  */
7599   if (TREE_CODE (arg) == COMPLEX_CST
7600       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7601                               type, mpfr_hypot)))
7602     return res;
7603   
7604   if (TREE_CODE (arg) == COMPLEX_EXPR)
7605     {
7606       tree real = TREE_OPERAND (arg, 0);
7607       tree imag = TREE_OPERAND (arg, 1);
7608       
7609       /* If either part is zero, cabs is fabs of the other.  */
7610       if (real_zerop (real))
7611         return fold_build1 (ABS_EXPR, type, imag);
7612       if (real_zerop (imag))
7613         return fold_build1 (ABS_EXPR, type, real);
7614
7615       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7616       if (flag_unsafe_math_optimizations
7617           && operand_equal_p (real, imag, OEP_PURE_SAME))
7618         {
7619           const REAL_VALUE_TYPE sqrt2_trunc
7620             = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7621           STRIP_NOPS (real);
7622           return fold_build2 (MULT_EXPR, type,
7623                               fold_build1 (ABS_EXPR, type, real),
7624                               build_real (type, sqrt2_trunc));
7625         }
7626     }
7627
7628   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7629   if (TREE_CODE (arg) == NEGATE_EXPR
7630       || TREE_CODE (arg) == CONJ_EXPR)
7631     return build_call_expr (fndecl, 1, TREE_OPERAND (arg, 0));
7632
7633   /* Don't do this when optimizing for size.  */
7634   if (flag_unsafe_math_optimizations
7635       && optimize && optimize_function_for_speed_p (cfun))
7636     {
7637       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7638
7639       if (sqrtfn != NULL_TREE)
7640         {
7641           tree rpart, ipart, result;
7642
7643           arg = builtin_save_expr (arg);
7644
7645           rpart = fold_build1 (REALPART_EXPR, type, arg);
7646           ipart = fold_build1 (IMAGPART_EXPR, type, arg);
7647
7648           rpart = builtin_save_expr (rpart);
7649           ipart = builtin_save_expr (ipart);
7650
7651           result = fold_build2 (PLUS_EXPR, type,
7652                                 fold_build2 (MULT_EXPR, type,
7653                                              rpart, rpart),
7654                                 fold_build2 (MULT_EXPR, type,
7655                                              ipart, ipart));
7656
7657           return build_call_expr (sqrtfn, 1, result);
7658         }
7659     }
7660
7661   return NULL_TREE;
7662 }
7663
7664 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7665    Return NULL_TREE if no simplification can be made.  */
7666
7667 static tree
7668 fold_builtin_sqrt (tree arg, tree type)
7669 {
7670
7671   enum built_in_function fcode;
7672   tree res;
7673
7674   if (!validate_arg (arg, REAL_TYPE))
7675     return NULL_TREE;
7676
7677   /* Calculate the result when the argument is a constant.  */
7678   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7679     return res;
7680   
7681   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7682   fcode = builtin_mathfn_code (arg);
7683   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7684     {
7685       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7686       arg = fold_build2 (MULT_EXPR, type,
7687                          CALL_EXPR_ARG (arg, 0),
7688                          build_real (type, dconsthalf));
7689       return build_call_expr (expfn, 1, arg);
7690     }
7691
7692   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7693   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7694     {
7695       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7696
7697       if (powfn)
7698         {
7699           tree arg0 = CALL_EXPR_ARG (arg, 0);
7700           tree tree_root;
7701           /* The inner root was either sqrt or cbrt.  */
7702           /* This was a conditional expression but it triggered a bug
7703              in Sun C 5.5.  */
7704           REAL_VALUE_TYPE dconstroot;
7705           if (BUILTIN_SQRT_P (fcode))
7706             dconstroot = dconsthalf;
7707           else
7708             dconstroot = dconst_third ();
7709
7710           /* Adjust for the outer root.  */
7711           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7712           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7713           tree_root = build_real (type, dconstroot);
7714           return build_call_expr (powfn, 2, arg0, tree_root);
7715         }
7716     }
7717
7718   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7719   if (flag_unsafe_math_optimizations
7720       && (fcode == BUILT_IN_POW
7721           || fcode == BUILT_IN_POWF
7722           || fcode == BUILT_IN_POWL))
7723     {
7724       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7725       tree arg0 = CALL_EXPR_ARG (arg, 0);
7726       tree arg1 = CALL_EXPR_ARG (arg, 1);
7727       tree narg1;
7728       if (!tree_expr_nonnegative_p (arg0))
7729         arg0 = build1 (ABS_EXPR, type, arg0);
7730       narg1 = fold_build2 (MULT_EXPR, type, arg1,
7731                            build_real (type, dconsthalf));
7732       return build_call_expr (powfn, 2, arg0, narg1);
7733     }
7734
7735   return NULL_TREE;
7736 }
7737
7738 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7739    Return NULL_TREE if no simplification can be made.  */
7740
7741 static tree
7742 fold_builtin_cbrt (tree arg, tree type)
7743 {
7744   const enum built_in_function fcode = builtin_mathfn_code (arg);
7745   tree res;
7746
7747   if (!validate_arg (arg, REAL_TYPE))
7748     return NULL_TREE;
7749
7750   /* Calculate the result when the argument is a constant.  */
7751   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7752     return res;
7753
7754   if (flag_unsafe_math_optimizations)
7755     {
7756       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7757       if (BUILTIN_EXPONENT_P (fcode))
7758         {
7759           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7760           const REAL_VALUE_TYPE third_trunc =
7761             real_value_truncate (TYPE_MODE (type), dconst_third ());
7762           arg = fold_build2 (MULT_EXPR, type,
7763                              CALL_EXPR_ARG (arg, 0),
7764                              build_real (type, third_trunc));
7765           return build_call_expr (expfn, 1, arg);
7766         }
7767
7768       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7769       if (BUILTIN_SQRT_P (fcode))
7770         {
7771           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7772
7773           if (powfn)
7774             {
7775               tree arg0 = CALL_EXPR_ARG (arg, 0);
7776               tree tree_root;
7777               REAL_VALUE_TYPE dconstroot = dconst_third ();
7778
7779               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7780               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7781               tree_root = build_real (type, dconstroot);
7782               return build_call_expr (powfn, 2, arg0, tree_root);
7783             }
7784         }
7785
7786       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7787       if (BUILTIN_CBRT_P (fcode))
7788         {
7789           tree arg0 = CALL_EXPR_ARG (arg, 0);
7790           if (tree_expr_nonnegative_p (arg0))
7791             {
7792               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7793
7794               if (powfn)
7795                 {
7796                   tree tree_root;
7797                   REAL_VALUE_TYPE dconstroot;
7798
7799                   real_arithmetic (&dconstroot, MULT_EXPR,
7800                                    dconst_third_ptr (), dconst_third_ptr ());
7801                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7802                   tree_root = build_real (type, dconstroot);
7803                   return build_call_expr (powfn, 2, arg0, tree_root);
7804                 }
7805             }
7806         }
7807
7808       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7809       if (fcode == BUILT_IN_POW 
7810           || fcode == BUILT_IN_POWF
7811           || fcode == BUILT_IN_POWL)
7812         {
7813           tree arg00 = CALL_EXPR_ARG (arg, 0);
7814           tree arg01 = CALL_EXPR_ARG (arg, 1);
7815           if (tree_expr_nonnegative_p (arg00))
7816             {
7817               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7818               const REAL_VALUE_TYPE dconstroot
7819                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7820               tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7821                                          build_real (type, dconstroot));
7822               return build_call_expr (powfn, 2, arg00, narg01);
7823             }
7824         }
7825     }
7826   return NULL_TREE;
7827 }
7828
7829 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7830    TYPE is the type of the return value.  Return NULL_TREE if no
7831    simplification can be made.  */
7832
7833 static tree
7834 fold_builtin_cos (tree arg, tree type, tree fndecl)
7835 {
7836   tree res, narg;
7837
7838   if (!validate_arg (arg, REAL_TYPE))
7839     return NULL_TREE;
7840
7841   /* Calculate the result when the argument is a constant.  */
7842   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7843     return res;
7844   
7845   /* Optimize cos(-x) into cos (x).  */
7846   if ((narg = fold_strip_sign_ops (arg)))
7847     return build_call_expr (fndecl, 1, narg);
7848
7849   return NULL_TREE;
7850 }
7851
7852 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7853    Return NULL_TREE if no simplification can be made.  */
7854
7855 static tree
7856 fold_builtin_cosh (tree arg, tree type, tree fndecl)
7857 {
7858   if (validate_arg (arg, REAL_TYPE))
7859     {
7860       tree res, narg;
7861
7862       /* Calculate the result when the argument is a constant.  */
7863       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7864         return res;
7865   
7866       /* Optimize cosh(-x) into cosh (x).  */
7867       if ((narg = fold_strip_sign_ops (arg)))
7868         return build_call_expr (fndecl, 1, narg);
7869     }
7870   
7871   return NULL_TREE;
7872 }
7873
7874 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7875    Return NULL_TREE if no simplification can be made.  */
7876
7877 static tree
7878 fold_builtin_tan (tree arg, tree type)
7879 {
7880   enum built_in_function fcode;
7881   tree res;
7882
7883   if (!validate_arg (arg, REAL_TYPE))
7884     return NULL_TREE;
7885
7886   /* Calculate the result when the argument is a constant.  */
7887   if ((res = do_mpfr_arg1 (arg, type, mpfr_tan, NULL, NULL, 0)))
7888     return res;
7889   
7890   /* Optimize tan(atan(x)) = x.  */
7891   fcode = builtin_mathfn_code (arg);
7892   if (flag_unsafe_math_optimizations
7893       && (fcode == BUILT_IN_ATAN
7894           || fcode == BUILT_IN_ATANF
7895           || fcode == BUILT_IN_ATANL))
7896     return CALL_EXPR_ARG (arg, 0);
7897
7898   return NULL_TREE;
7899 }
7900
7901 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7902    NULL_TREE if no simplification can be made.  */
7903
7904 static tree
7905 fold_builtin_sincos (tree arg0, tree arg1, tree arg2)
7906 {
7907   tree type;
7908   tree res, fn, call;
7909
7910   if (!validate_arg (arg0, REAL_TYPE)
7911       || !validate_arg (arg1, POINTER_TYPE)
7912       || !validate_arg (arg2, POINTER_TYPE))
7913     return NULL_TREE;
7914
7915   type = TREE_TYPE (arg0);
7916
7917   /* Calculate the result when the argument is a constant.  */
7918   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7919     return res;
7920
7921   /* Canonicalize sincos to cexpi.  */
7922   if (!TARGET_C99_FUNCTIONS)
7923     return NULL_TREE;
7924   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7925   if (!fn)
7926     return NULL_TREE;
7927
7928   call = build_call_expr (fn, 1, arg0);
7929   call = builtin_save_expr (call);
7930
7931   return build2 (COMPOUND_EXPR, type,
7932                  build2 (MODIFY_EXPR, void_type_node,
7933                          build_fold_indirect_ref (arg1),
7934                          build1 (IMAGPART_EXPR, type, call)),
7935                  build2 (MODIFY_EXPR, void_type_node,
7936                          build_fold_indirect_ref (arg2),
7937                          build1 (REALPART_EXPR, type, call)));
7938 }
7939
7940 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7941    NULL_TREE if no simplification can be made.  */
7942
7943 static tree
7944 fold_builtin_cexp (tree arg0, tree type)
7945 {
7946   tree rtype;
7947   tree realp, imagp, ifn;
7948
7949   if (!validate_arg (arg0, COMPLEX_TYPE))
7950     return NULL_TREE;
7951
7952   rtype = TREE_TYPE (TREE_TYPE (arg0));
7953
7954   /* In case we can figure out the real part of arg0 and it is constant zero
7955      fold to cexpi.  */
7956   if (!TARGET_C99_FUNCTIONS)
7957     return NULL_TREE;
7958   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7959   if (!ifn)
7960     return NULL_TREE;
7961
7962   if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7963       && real_zerop (realp))
7964     {
7965       tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7966       return build_call_expr (ifn, 1, narg);
7967     }
7968
7969   /* In case we can easily decompose real and imaginary parts split cexp
7970      to exp (r) * cexpi (i).  */
7971   if (flag_unsafe_math_optimizations
7972       && realp)
7973     {
7974       tree rfn, rcall, icall;
7975
7976       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7977       if (!rfn)
7978         return NULL_TREE;
7979
7980       imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7981       if (!imagp)
7982         return NULL_TREE;
7983
7984       icall = build_call_expr (ifn, 1, imagp);
7985       icall = builtin_save_expr (icall);
7986       rcall = build_call_expr (rfn, 1, realp);
7987       rcall = builtin_save_expr (rcall);
7988       return fold_build2 (COMPLEX_EXPR, type,
7989                           fold_build2 (MULT_EXPR, rtype,
7990                                        rcall,
7991                                        fold_build1 (REALPART_EXPR, rtype, icall)),
7992                           fold_build2 (MULT_EXPR, rtype,
7993                                        rcall,
7994                                        fold_build1 (IMAGPART_EXPR, rtype, icall)));
7995     }
7996
7997   return NULL_TREE;
7998 }
7999
8000 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
8001    Return NULL_TREE if no simplification can be made.  */
8002
8003 static tree
8004 fold_builtin_trunc (tree fndecl, tree arg)
8005 {
8006   if (!validate_arg (arg, REAL_TYPE))
8007     return NULL_TREE;
8008
8009   /* Optimize trunc of constant value.  */
8010   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8011     {
8012       REAL_VALUE_TYPE r, x;
8013       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8014
8015       x = TREE_REAL_CST (arg);
8016       real_trunc (&r, TYPE_MODE (type), &x);
8017       return build_real (type, r);
8018     }
8019
8020   return fold_trunc_transparent_mathfn (fndecl, arg);
8021 }
8022
8023 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
8024    Return NULL_TREE if no simplification can be made.  */
8025
8026 static tree
8027 fold_builtin_floor (tree fndecl, tree arg)
8028 {
8029   if (!validate_arg (arg, REAL_TYPE))
8030     return NULL_TREE;
8031
8032   /* Optimize floor of constant value.  */
8033   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8034     {
8035       REAL_VALUE_TYPE x;
8036
8037       x = TREE_REAL_CST (arg);
8038       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8039         {
8040           tree type = TREE_TYPE (TREE_TYPE (fndecl));
8041           REAL_VALUE_TYPE r;
8042
8043           real_floor (&r, TYPE_MODE (type), &x);
8044           return build_real (type, r);
8045         }
8046     }
8047
8048   /* Fold floor (x) where x is nonnegative to trunc (x).  */
8049   if (tree_expr_nonnegative_p (arg))
8050     {
8051       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
8052       if (truncfn)
8053         return build_call_expr (truncfn, 1, arg);
8054     }
8055
8056   return fold_trunc_transparent_mathfn (fndecl, arg);
8057 }
8058
8059 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
8060    Return NULL_TREE if no simplification can be made.  */
8061
8062 static tree
8063 fold_builtin_ceil (tree fndecl, tree arg)
8064 {
8065   if (!validate_arg (arg, REAL_TYPE))
8066     return NULL_TREE;
8067
8068   /* Optimize ceil of constant value.  */
8069   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8070     {
8071       REAL_VALUE_TYPE x;
8072
8073       x = TREE_REAL_CST (arg);
8074       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8075         {
8076           tree type = TREE_TYPE (TREE_TYPE (fndecl));
8077           REAL_VALUE_TYPE r;
8078
8079           real_ceil (&r, TYPE_MODE (type), &x);
8080           return build_real (type, r);
8081         }
8082     }
8083
8084   return fold_trunc_transparent_mathfn (fndecl, arg);
8085 }
8086
8087 /* Fold function call to builtin round, roundf or roundl with argument ARG.
8088    Return NULL_TREE if no simplification can be made.  */
8089
8090 static tree
8091 fold_builtin_round (tree fndecl, tree arg)
8092 {
8093   if (!validate_arg (arg, REAL_TYPE))
8094     return NULL_TREE;
8095
8096   /* Optimize round of constant value.  */
8097   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8098     {
8099       REAL_VALUE_TYPE x;
8100
8101       x = TREE_REAL_CST (arg);
8102       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
8103         {
8104           tree type = TREE_TYPE (TREE_TYPE (fndecl));
8105           REAL_VALUE_TYPE r;
8106
8107           real_round (&r, TYPE_MODE (type), &x);
8108           return build_real (type, r);
8109         }
8110     }
8111
8112   return fold_trunc_transparent_mathfn (fndecl, arg);
8113 }
8114
8115 /* Fold function call to builtin lround, lroundf or lroundl (or the
8116    corresponding long long versions) and other rounding functions.  ARG
8117    is the argument to the call.  Return NULL_TREE if no simplification
8118    can be made.  */
8119
8120 static tree
8121 fold_builtin_int_roundingfn (tree fndecl, tree arg)
8122 {
8123   if (!validate_arg (arg, REAL_TYPE))
8124     return NULL_TREE;
8125
8126   /* Optimize lround of constant value.  */
8127   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
8128     {
8129       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
8130
8131       if (real_isfinite (&x))
8132         {
8133           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
8134           tree ftype = TREE_TYPE (arg);
8135           unsigned HOST_WIDE_INT lo2;
8136           HOST_WIDE_INT hi, lo;
8137           REAL_VALUE_TYPE r;
8138
8139           switch (DECL_FUNCTION_CODE (fndecl))
8140             {
8141             CASE_FLT_FN (BUILT_IN_LFLOOR):
8142             CASE_FLT_FN (BUILT_IN_LLFLOOR):
8143               real_floor (&r, TYPE_MODE (ftype), &x);
8144               break;
8145
8146             CASE_FLT_FN (BUILT_IN_LCEIL):
8147             CASE_FLT_FN (BUILT_IN_LLCEIL):
8148               real_ceil (&r, TYPE_MODE (ftype), &x);
8149               break;
8150
8151             CASE_FLT_FN (BUILT_IN_LROUND):
8152             CASE_FLT_FN (BUILT_IN_LLROUND):
8153               real_round (&r, TYPE_MODE (ftype), &x);
8154               break;
8155
8156             default:
8157               gcc_unreachable ();
8158             }
8159
8160           REAL_VALUE_TO_INT (&lo, &hi, r);
8161           if (!fit_double_type (lo, hi, &lo2, &hi, itype))
8162             return build_int_cst_wide (itype, lo2, hi);
8163         }
8164     }
8165
8166   switch (DECL_FUNCTION_CODE (fndecl))
8167     {
8168     CASE_FLT_FN (BUILT_IN_LFLOOR):
8169     CASE_FLT_FN (BUILT_IN_LLFLOOR):
8170       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
8171       if (tree_expr_nonnegative_p (arg))
8172         return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
8173                             arg);
8174       break;
8175     default:;
8176     }
8177
8178   return fold_fixed_mathfn (fndecl, arg);
8179 }
8180
8181 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
8182    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
8183    the argument to the call.  Return NULL_TREE if no simplification can
8184    be made.  */
8185
8186 static tree
8187 fold_builtin_bitop (tree fndecl, tree arg)
8188 {
8189   if (!validate_arg (arg, INTEGER_TYPE))
8190     return NULL_TREE;
8191
8192   /* Optimize for constant argument.  */
8193   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8194     {
8195       HOST_WIDE_INT hi, width, result;
8196       unsigned HOST_WIDE_INT lo;
8197       tree type;
8198
8199       type = TREE_TYPE (arg);
8200       width = TYPE_PRECISION (type);
8201       lo = TREE_INT_CST_LOW (arg);
8202
8203       /* Clear all the bits that are beyond the type's precision.  */
8204       if (width > HOST_BITS_PER_WIDE_INT)
8205         {
8206           hi = TREE_INT_CST_HIGH (arg);
8207           if (width < 2 * HOST_BITS_PER_WIDE_INT)
8208             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
8209         }
8210       else
8211         {
8212           hi = 0;
8213           if (width < HOST_BITS_PER_WIDE_INT)
8214             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
8215         }
8216
8217       switch (DECL_FUNCTION_CODE (fndecl))
8218         {
8219         CASE_INT_FN (BUILT_IN_FFS):
8220           if (lo != 0)
8221             result = exact_log2 (lo & -lo) + 1;
8222           else if (hi != 0)
8223             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
8224           else
8225             result = 0;
8226           break;
8227
8228         CASE_INT_FN (BUILT_IN_CLZ):
8229           if (hi != 0)
8230             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
8231           else if (lo != 0)
8232             result = width - floor_log2 (lo) - 1;
8233           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8234             result = width;
8235           break;
8236
8237         CASE_INT_FN (BUILT_IN_CTZ):
8238           if (lo != 0)
8239             result = exact_log2 (lo & -lo);
8240           else if (hi != 0)
8241             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
8242           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
8243             result = width;
8244           break;
8245
8246         CASE_INT_FN (BUILT_IN_POPCOUNT):
8247           result = 0;
8248           while (lo)
8249             result++, lo &= lo - 1;
8250           while (hi)
8251             result++, hi &= hi - 1;
8252           break;
8253
8254         CASE_INT_FN (BUILT_IN_PARITY):
8255           result = 0;
8256           while (lo)
8257             result++, lo &= lo - 1;
8258           while (hi)
8259             result++, hi &= hi - 1;
8260           result &= 1;
8261           break;
8262
8263         default:
8264           gcc_unreachable ();
8265         }
8266
8267       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
8268     }
8269
8270   return NULL_TREE;
8271 }
8272
8273 /* Fold function call to builtin_bswap and the long and long long
8274    variants.  Return NULL_TREE if no simplification can be made.  */
8275 static tree
8276 fold_builtin_bswap (tree fndecl, tree arg)
8277 {
8278   if (! validate_arg (arg, INTEGER_TYPE))
8279     return NULL_TREE;
8280
8281   /* Optimize constant value.  */
8282   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
8283     {
8284       HOST_WIDE_INT hi, width, r_hi = 0;
8285       unsigned HOST_WIDE_INT lo, r_lo = 0;
8286       tree type;
8287
8288       type = TREE_TYPE (arg);
8289       width = TYPE_PRECISION (type);
8290       lo = TREE_INT_CST_LOW (arg);
8291       hi = TREE_INT_CST_HIGH (arg);
8292
8293       switch (DECL_FUNCTION_CODE (fndecl))
8294         {
8295           case BUILT_IN_BSWAP32:
8296           case BUILT_IN_BSWAP64:
8297             {
8298               int s;
8299
8300               for (s = 0; s < width; s += 8)
8301                 {
8302                   int d = width - s - 8;
8303                   unsigned HOST_WIDE_INT byte;
8304
8305                   if (s < HOST_BITS_PER_WIDE_INT)
8306                     byte = (lo >> s) & 0xff;
8307                   else
8308                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
8309
8310                   if (d < HOST_BITS_PER_WIDE_INT)
8311                     r_lo |= byte << d;
8312                   else
8313                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
8314                 }
8315             }
8316
8317             break;
8318
8319         default:
8320           gcc_unreachable ();
8321         }
8322
8323       if (width < HOST_BITS_PER_WIDE_INT)
8324         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
8325       else
8326         return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
8327     }
8328
8329   return NULL_TREE;
8330 }
8331
8332 /* Return true if EXPR is the real constant contained in VALUE.  */
8333
8334 static bool
8335 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
8336 {
8337   STRIP_NOPS (expr);
8338
8339   return ((TREE_CODE (expr) == REAL_CST
8340            && !TREE_OVERFLOW (expr)
8341            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
8342           || (TREE_CODE (expr) == COMPLEX_CST
8343               && real_dconstp (TREE_REALPART (expr), value)
8344               && real_zerop (TREE_IMAGPART (expr))));
8345 }
8346
8347 /* A subroutine of fold_builtin to fold the various logarithmic
8348    functions.  Return NULL_TREE if no simplification can me made.
8349    FUNC is the corresponding MPFR logarithm function.  */
8350
8351 static tree
8352 fold_builtin_logarithm (tree fndecl, tree arg,
8353                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8354 {
8355   if (validate_arg (arg, REAL_TYPE))
8356     {
8357       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8358       tree res;
8359       const enum built_in_function fcode = builtin_mathfn_code (arg);
8360
8361       /* Optimize log(e) = 1.0.  We're never passed an exact 'e',
8362          instead we'll look for 'e' truncated to MODE.  So only do
8363          this if flag_unsafe_math_optimizations is set.  */
8364       if (flag_unsafe_math_optimizations && func == mpfr_log)
8365         {
8366           const REAL_VALUE_TYPE e_truncated =
8367             real_value_truncate (TYPE_MODE (type), dconst_e ());
8368           if (real_dconstp (arg, &e_truncated))
8369             return build_real (type, dconst1);
8370         }
8371
8372       /* Calculate the result when the argument is a constant.  */
8373       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
8374         return res;
8375
8376       /* Special case, optimize logN(expN(x)) = x.  */
8377       if (flag_unsafe_math_optimizations
8378           && ((func == mpfr_log
8379                && (fcode == BUILT_IN_EXP
8380                    || fcode == BUILT_IN_EXPF
8381                    || fcode == BUILT_IN_EXPL))
8382               || (func == mpfr_log2
8383                   && (fcode == BUILT_IN_EXP2
8384                       || fcode == BUILT_IN_EXP2F
8385                       || fcode == BUILT_IN_EXP2L))
8386               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
8387         return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8388
8389       /* Optimize logN(func()) for various exponential functions.  We
8390          want to determine the value "x" and the power "exponent" in
8391          order to transform logN(x**exponent) into exponent*logN(x).  */
8392       if (flag_unsafe_math_optimizations)
8393         {
8394           tree exponent = 0, x = 0;
8395
8396           switch (fcode)
8397           {
8398           CASE_FLT_FN (BUILT_IN_EXP):
8399             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8400             x = build_real (type, real_value_truncate (TYPE_MODE (type), 
8401                                                        dconst_e ()));
8402             exponent = CALL_EXPR_ARG (arg, 0);
8403             break;
8404           CASE_FLT_FN (BUILT_IN_EXP2):
8405             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8406             x = build_real (type, dconst2);
8407             exponent = CALL_EXPR_ARG (arg, 0);
8408             break;
8409           CASE_FLT_FN (BUILT_IN_EXP10):
8410           CASE_FLT_FN (BUILT_IN_POW10):
8411             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8412             {
8413               REAL_VALUE_TYPE dconst10;
8414               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8415               x = build_real (type, dconst10);
8416             }
8417             exponent = CALL_EXPR_ARG (arg, 0);
8418             break;
8419           CASE_FLT_FN (BUILT_IN_SQRT):
8420             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8421             x = CALL_EXPR_ARG (arg, 0);
8422             exponent = build_real (type, dconsthalf);
8423             break;
8424           CASE_FLT_FN (BUILT_IN_CBRT):
8425             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8426             x = CALL_EXPR_ARG (arg, 0);
8427             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8428                                                               dconst_third ()));
8429             break;
8430           CASE_FLT_FN (BUILT_IN_POW):
8431             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8432             x = CALL_EXPR_ARG (arg, 0);
8433             exponent = CALL_EXPR_ARG (arg, 1);
8434             break;
8435           default:
8436             break;
8437           }
8438
8439           /* Now perform the optimization.  */
8440           if (x && exponent)
8441             {
8442               tree logfn = build_call_expr (fndecl, 1, x);
8443               return fold_build2 (MULT_EXPR, type, exponent, logfn);
8444             }
8445         }
8446     }
8447
8448   return NULL_TREE;
8449 }
8450
8451 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8452    NULL_TREE if no simplification can be made.  */
8453
8454 static tree
8455 fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type)
8456 {
8457   tree res, narg0, narg1;
8458
8459   if (!validate_arg (arg0, REAL_TYPE)
8460       || !validate_arg (arg1, REAL_TYPE))
8461     return NULL_TREE;
8462
8463   /* Calculate the result when the argument is a constant.  */
8464   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8465     return res;
8466   
8467   /* If either argument to hypot has a negate or abs, strip that off.
8468      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8469   narg0 = fold_strip_sign_ops (arg0);
8470   narg1 = fold_strip_sign_ops (arg1);
8471   if (narg0 || narg1)
8472     {
8473       return build_call_expr (fndecl, 2, narg0 ? narg0 : arg0, 
8474                               narg1 ? narg1 : arg1);
8475     }
8476   
8477   /* If either argument is zero, hypot is fabs of the other.  */
8478   if (real_zerop (arg0))
8479     return fold_build1 (ABS_EXPR, type, arg1);
8480   else if (real_zerop (arg1))
8481     return fold_build1 (ABS_EXPR, type, arg0);
8482       
8483   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8484   if (flag_unsafe_math_optimizations
8485       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8486     {
8487       const REAL_VALUE_TYPE sqrt2_trunc
8488         = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8489       return fold_build2 (MULT_EXPR, type,
8490                           fold_build1 (ABS_EXPR, type, arg0),
8491                           build_real (type, sqrt2_trunc));
8492     }
8493
8494   return NULL_TREE;
8495 }
8496
8497
8498 /* Fold a builtin function call to pow, powf, or powl.  Return
8499    NULL_TREE if no simplification can be made.  */
8500 static tree
8501 fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type)
8502 {
8503   tree res;
8504
8505   if (!validate_arg (arg0, REAL_TYPE)
8506        || !validate_arg (arg1, REAL_TYPE))
8507     return NULL_TREE;
8508
8509   /* Calculate the result when the argument is a constant.  */
8510   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8511     return res;
8512
8513   /* Optimize pow(1.0,y) = 1.0.  */
8514   if (real_onep (arg0))
8515     return omit_one_operand (type, build_real (type, dconst1), arg1);
8516
8517   if (TREE_CODE (arg1) == REAL_CST
8518       && !TREE_OVERFLOW (arg1))
8519     {
8520       REAL_VALUE_TYPE cint;
8521       REAL_VALUE_TYPE c;
8522       HOST_WIDE_INT n;
8523
8524       c = TREE_REAL_CST (arg1);
8525
8526       /* Optimize pow(x,0.0) = 1.0.  */
8527       if (REAL_VALUES_EQUAL (c, dconst0))
8528         return omit_one_operand (type, build_real (type, dconst1),
8529                                  arg0);
8530
8531       /* Optimize pow(x,1.0) = x.  */
8532       if (REAL_VALUES_EQUAL (c, dconst1))
8533         return arg0;
8534
8535       /* Optimize pow(x,-1.0) = 1.0/x.  */
8536       if (REAL_VALUES_EQUAL (c, dconstm1))
8537         return fold_build2 (RDIV_EXPR, type,
8538                             build_real (type, dconst1), arg0);
8539
8540       /* Optimize pow(x,0.5) = sqrt(x).  */
8541       if (flag_unsafe_math_optimizations
8542           && REAL_VALUES_EQUAL (c, dconsthalf))
8543         {
8544           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8545
8546           if (sqrtfn != NULL_TREE)
8547             return build_call_expr (sqrtfn, 1, arg0);
8548         }
8549
8550       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8551       if (flag_unsafe_math_optimizations)
8552         {
8553           const REAL_VALUE_TYPE dconstroot
8554             = real_value_truncate (TYPE_MODE (type), dconst_third ());
8555
8556           if (REAL_VALUES_EQUAL (c, dconstroot))
8557             {
8558               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8559               if (cbrtfn != NULL_TREE)
8560                   return build_call_expr (cbrtfn, 1, arg0);
8561             }
8562         }
8563
8564       /* Check for an integer exponent.  */
8565       n = real_to_integer (&c);
8566       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8567       if (real_identical (&c, &cint))
8568         {
8569           /* Attempt to evaluate pow at compile-time, unless this should
8570              raise an exception.  */
8571           if (TREE_CODE (arg0) == REAL_CST
8572               && !TREE_OVERFLOW (arg0)
8573               && (n > 0
8574                   || (!flag_trapping_math && !flag_errno_math)
8575                   || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8576             {
8577               REAL_VALUE_TYPE x;
8578               bool inexact;
8579
8580               x = TREE_REAL_CST (arg0);
8581               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8582               if (flag_unsafe_math_optimizations || !inexact)
8583                 return build_real (type, x);
8584             }
8585
8586           /* Strip sign ops from even integer powers.  */
8587           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8588             {
8589               tree narg0 = fold_strip_sign_ops (arg0);
8590               if (narg0)
8591                 return build_call_expr (fndecl, 2, narg0, arg1);
8592             }
8593         }
8594     }
8595
8596   if (flag_unsafe_math_optimizations)
8597     {
8598       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8599
8600       /* Optimize pow(expN(x),y) = expN(x*y).  */
8601       if (BUILTIN_EXPONENT_P (fcode))
8602         {
8603           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8604           tree arg = CALL_EXPR_ARG (arg0, 0);
8605           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8606           return build_call_expr (expfn, 1, arg);
8607         }
8608
8609       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8610       if (BUILTIN_SQRT_P (fcode))
8611         {
8612           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8613           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8614                                     build_real (type, dconsthalf));
8615           return build_call_expr (fndecl, 2, narg0, narg1);
8616         }
8617
8618       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8619       if (BUILTIN_CBRT_P (fcode))
8620         {
8621           tree arg = CALL_EXPR_ARG (arg0, 0);
8622           if (tree_expr_nonnegative_p (arg))
8623             {
8624               const REAL_VALUE_TYPE dconstroot
8625                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8626               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8627                                         build_real (type, dconstroot));
8628               return build_call_expr (fndecl, 2, arg, narg1);
8629             }
8630         }
8631
8632       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8633       if (fcode == BUILT_IN_POW
8634           || fcode == BUILT_IN_POWF
8635           || fcode == BUILT_IN_POWL)
8636         {
8637           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8638           tree arg01 = CALL_EXPR_ARG (arg0, 1);
8639           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8640           return build_call_expr (fndecl, 2, arg00, narg1);
8641         }
8642     }
8643
8644   return NULL_TREE;
8645 }
8646
8647 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8648    Return NULL_TREE if no simplification can be made.  */
8649 static tree
8650 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED,
8651                    tree arg0, tree arg1, tree type)
8652 {
8653   if (!validate_arg (arg0, REAL_TYPE)
8654       || !validate_arg (arg1, INTEGER_TYPE))
8655     return NULL_TREE;
8656
8657   /* Optimize pow(1.0,y) = 1.0.  */
8658   if (real_onep (arg0))
8659     return omit_one_operand (type, build_real (type, dconst1), arg1);
8660
8661   if (host_integerp (arg1, 0))
8662     {
8663       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8664
8665       /* Evaluate powi at compile-time.  */
8666       if (TREE_CODE (arg0) == REAL_CST
8667           && !TREE_OVERFLOW (arg0))
8668         {
8669           REAL_VALUE_TYPE x;
8670           x = TREE_REAL_CST (arg0);
8671           real_powi (&x, TYPE_MODE (type), &x, c);
8672           return build_real (type, x);
8673         }
8674
8675       /* Optimize pow(x,0) = 1.0.  */
8676       if (c == 0)
8677         return omit_one_operand (type, build_real (type, dconst1),
8678                                  arg0);
8679
8680       /* Optimize pow(x,1) = x.  */
8681       if (c == 1)
8682         return arg0;
8683
8684       /* Optimize pow(x,-1) = 1.0/x.  */
8685       if (c == -1)
8686         return fold_build2 (RDIV_EXPR, type,
8687                            build_real (type, dconst1), arg0);
8688     }
8689
8690   return NULL_TREE;
8691 }
8692
8693 /* A subroutine of fold_builtin to fold the various exponent
8694    functions.  Return NULL_TREE if no simplification can be made.
8695    FUNC is the corresponding MPFR exponent function.  */
8696
8697 static tree
8698 fold_builtin_exponent (tree fndecl, tree arg,
8699                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8700 {
8701   if (validate_arg (arg, REAL_TYPE))
8702     {
8703       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8704       tree res;
8705       
8706       /* Calculate the result when the argument is a constant.  */
8707       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8708         return res;
8709
8710       /* Optimize expN(logN(x)) = x.  */
8711       if (flag_unsafe_math_optimizations)
8712         {
8713           const enum built_in_function fcode = builtin_mathfn_code (arg);
8714
8715           if ((func == mpfr_exp
8716                && (fcode == BUILT_IN_LOG
8717                    || fcode == BUILT_IN_LOGF
8718                    || fcode == BUILT_IN_LOGL))
8719               || (func == mpfr_exp2
8720                   && (fcode == BUILT_IN_LOG2
8721                       || fcode == BUILT_IN_LOG2F
8722                       || fcode == BUILT_IN_LOG2L))
8723               || (func == mpfr_exp10
8724                   && (fcode == BUILT_IN_LOG10
8725                       || fcode == BUILT_IN_LOG10F
8726                       || fcode == BUILT_IN_LOG10L)))
8727             return fold_convert (type, CALL_EXPR_ARG (arg, 0));
8728         }
8729     }
8730
8731   return NULL_TREE;
8732 }
8733
8734 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8735
8736 static bool
8737 var_decl_component_p (tree var)
8738 {
8739   tree inner = var;
8740   while (handled_component_p (inner))
8741     inner = TREE_OPERAND (inner, 0);
8742   return SSA_VAR_P (inner);
8743 }
8744
8745 /* Fold function call to builtin memset.  Return
8746    NULL_TREE if no simplification can be made.  */
8747
8748 static tree
8749 fold_builtin_memset (tree dest, tree c, tree len, tree type, bool ignore)
8750 {
8751   tree var, ret;
8752   unsigned HOST_WIDE_INT length, cval;
8753
8754   if (! validate_arg (dest, POINTER_TYPE)
8755       || ! validate_arg (c, INTEGER_TYPE)
8756       || ! validate_arg (len, INTEGER_TYPE))
8757     return NULL_TREE;
8758
8759   if (! host_integerp (len, 1))
8760     return NULL_TREE;
8761
8762   /* If the LEN parameter is zero, return DEST.  */
8763   if (integer_zerop (len))
8764     return omit_one_operand (type, dest, c);
8765
8766   if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8767     return NULL_TREE;
8768
8769   var = dest;
8770   STRIP_NOPS (var);
8771   if (TREE_CODE (var) != ADDR_EXPR)
8772     return NULL_TREE;
8773
8774   var = TREE_OPERAND (var, 0);
8775   if (TREE_THIS_VOLATILE (var))
8776     return NULL_TREE;
8777
8778   if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8779       && !POINTER_TYPE_P (TREE_TYPE (var)))
8780     return NULL_TREE;
8781
8782   if (! var_decl_component_p (var))
8783     return NULL_TREE;
8784
8785   length = tree_low_cst (len, 1);
8786   if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8787       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8788          < (int) length)
8789     return NULL_TREE;
8790
8791   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8792     return NULL_TREE;
8793
8794   if (integer_zerop (c))
8795     cval = 0;
8796   else
8797     {
8798       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8799         return NULL_TREE;
8800
8801       cval = tree_low_cst (c, 1);
8802       cval &= 0xff;
8803       cval |= cval << 8;
8804       cval |= cval << 16;
8805       cval |= (cval << 31) << 1;
8806     }
8807
8808   ret = build_int_cst_type (TREE_TYPE (var), cval);
8809   ret = build2 (MODIFY_EXPR, TREE_TYPE (var), var, ret);
8810   if (ignore)
8811     return ret;
8812
8813   return omit_one_operand (type, dest, ret);
8814 }
8815
8816 /* Fold function call to builtin memset.  Return
8817    NULL_TREE if no simplification can be made.  */
8818
8819 static tree
8820 fold_builtin_bzero (tree dest, tree size, bool ignore)
8821 {
8822   if (! validate_arg (dest, POINTER_TYPE)
8823       || ! validate_arg (size, INTEGER_TYPE))
8824     return NULL_TREE;
8825
8826   if (!ignore)
8827     return NULL_TREE;
8828
8829   /* New argument list transforming bzero(ptr x, int y) to
8830      memset(ptr x, int 0, size_t y).   This is done this way
8831      so that if it isn't expanded inline, we fallback to
8832      calling bzero instead of memset.  */
8833
8834   return fold_builtin_memset (dest, integer_zero_node,
8835                               fold_convert (sizetype, size),
8836                               void_type_node, ignore);
8837 }
8838
8839 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8840    NULL_TREE if no simplification can be made.
8841    If ENDP is 0, return DEST (like memcpy).
8842    If ENDP is 1, return DEST+LEN (like mempcpy).
8843    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8844    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8845    (memmove).   */
8846
8847 static tree
8848 fold_builtin_memory_op (tree dest, tree src, tree len, tree type, bool ignore, int endp)
8849 {
8850   tree destvar, srcvar, expr;
8851
8852   if (! validate_arg (dest, POINTER_TYPE)
8853       || ! validate_arg (src, POINTER_TYPE)
8854       || ! validate_arg (len, INTEGER_TYPE))
8855     return NULL_TREE;
8856
8857   /* If the LEN parameter is zero, return DEST.  */
8858   if (integer_zerop (len))
8859     return omit_one_operand (type, dest, src);
8860
8861   /* If SRC and DEST are the same (and not volatile), return
8862      DEST{,+LEN,+LEN-1}.  */
8863   if (operand_equal_p (src, dest, 0))
8864     expr = len;
8865   else
8866     {
8867       tree srctype, desttype;
8868       int src_align, dest_align;
8869
8870       if (endp == 3)
8871         {
8872           src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8873           dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8874
8875           /* Both DEST and SRC must be pointer types. 
8876              ??? This is what old code did.  Is the testing for pointer types
8877              really mandatory?
8878
8879              If either SRC is readonly or length is 1, we can use memcpy.  */
8880           if (dest_align && src_align
8881               && (readonly_data_expr (src)
8882                   || (host_integerp (len, 1)
8883                       && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8884                           tree_low_cst (len, 1)))))
8885             {
8886               tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8887               if (!fn)
8888                 return NULL_TREE;
8889               return build_call_expr (fn, 3, dest, src, len);
8890             }
8891           return NULL_TREE;
8892         }
8893
8894       if (!host_integerp (len, 0))
8895         return NULL_TREE;
8896       /* FIXME:
8897          This logic lose for arguments like (type *)malloc (sizeof (type)),
8898          since we strip the casts of up to VOID return value from malloc.
8899          Perhaps we ought to inherit type from non-VOID argument here?  */
8900       STRIP_NOPS (src);
8901       STRIP_NOPS (dest);
8902       srctype = TREE_TYPE (TREE_TYPE (src));
8903       desttype = TREE_TYPE (TREE_TYPE (dest));
8904       if (!srctype || !desttype
8905           || !TYPE_SIZE_UNIT (srctype)
8906           || !TYPE_SIZE_UNIT (desttype)
8907           || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8908           || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST)
8909         return NULL_TREE;
8910
8911       src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8912       dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8913       if (dest_align < (int) TYPE_ALIGN (desttype)
8914           || src_align < (int) TYPE_ALIGN (srctype))
8915         return NULL_TREE;
8916
8917       if (!ignore)
8918         dest = builtin_save_expr (dest);
8919
8920       srcvar = NULL_TREE;
8921       if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8922         {
8923           srcvar = build_fold_indirect_ref (src);
8924           if (TREE_THIS_VOLATILE (srcvar))
8925             srcvar = NULL_TREE;
8926           else if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8927             srcvar = NULL_TREE;
8928           /* With memcpy, it is possible to bypass aliasing rules, so without
8929              this check i.e. execute/20060930-2.c would be misoptimized,
8930              because it use conflicting alias set to hold argument for the
8931              memcpy call.  This check is probably unnecessary with
8932              -fno-strict-aliasing.  Similarly for destvar.  See also
8933              PR29286.  */
8934           else if (!var_decl_component_p (srcvar))
8935             srcvar = NULL_TREE;
8936         }
8937
8938       destvar = NULL_TREE;
8939       if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8940         {
8941           destvar = build_fold_indirect_ref (dest);
8942           if (TREE_THIS_VOLATILE (destvar))
8943             destvar = NULL_TREE;
8944           else if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8945             destvar = NULL_TREE;
8946           else if (!var_decl_component_p (destvar))
8947             destvar = NULL_TREE;
8948         }
8949
8950       if (srcvar == NULL_TREE && destvar == NULL_TREE)
8951         return NULL_TREE;
8952
8953       if (srcvar == NULL_TREE)
8954         {
8955           tree srcptype;
8956           if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
8957             return NULL_TREE;
8958
8959           srctype = desttype;
8960           if (src_align < (int) TYPE_ALIGN (srctype))
8961             {
8962               if (AGGREGATE_TYPE_P (srctype)
8963                   || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
8964                 return NULL_TREE;
8965
8966               srctype = build_variant_type_copy (srctype);
8967               TYPE_ALIGN (srctype) = src_align;
8968               TYPE_USER_ALIGN (srctype) = 1;
8969               TYPE_PACKED (srctype) = 1;
8970             }
8971           srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
8972           src = fold_convert (srcptype, src);
8973           srcvar = build_fold_indirect_ref (src);
8974         }
8975       else if (destvar == NULL_TREE)
8976         {
8977           tree destptype;
8978           if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
8979             return NULL_TREE;
8980
8981           desttype = srctype;
8982           if (dest_align < (int) TYPE_ALIGN (desttype))
8983             {
8984               if (AGGREGATE_TYPE_P (desttype)
8985                   || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
8986                 return NULL_TREE;
8987
8988               desttype = build_variant_type_copy (desttype);
8989               TYPE_ALIGN (desttype) = dest_align;
8990               TYPE_USER_ALIGN (desttype) = 1;
8991               TYPE_PACKED (desttype) = 1;
8992             }
8993           destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
8994           dest = fold_convert (destptype, dest);
8995           destvar = build_fold_indirect_ref (dest);
8996         }
8997
8998       if (srctype == desttype
8999           || (gimple_in_ssa_p (cfun)
9000               && useless_type_conversion_p (desttype, srctype)))
9001         expr = srcvar;
9002       else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
9003            || POINTER_TYPE_P (TREE_TYPE (srcvar)))
9004           && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
9005               || POINTER_TYPE_P (TREE_TYPE (destvar))))
9006         expr = fold_convert (TREE_TYPE (destvar), srcvar);
9007       else
9008         expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
9009       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
9010     }
9011
9012   if (ignore)
9013     return expr;
9014
9015   if (endp == 0 || endp == 3)
9016     return omit_one_operand (type, dest, expr);
9017
9018   if (expr == len)
9019     expr = NULL_TREE;
9020
9021   if (endp == 2)
9022     len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
9023                        ssize_int (1));
9024
9025   len = fold_convert (sizetype, len);
9026   dest = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
9027   dest = fold_convert (type, dest);
9028   if (expr)
9029     dest = omit_one_operand (type, dest, expr);
9030   return dest;
9031 }
9032
9033 /* Fold function call to builtin strcpy with arguments DEST and SRC.
9034    If LEN is not NULL, it represents the length of the string to be
9035    copied.  Return NULL_TREE if no simplification can be made.  */
9036
9037 tree
9038 fold_builtin_strcpy (tree fndecl, tree dest, tree src, tree len)
9039 {
9040   tree fn;
9041
9042   if (!validate_arg (dest, POINTER_TYPE)
9043       || !validate_arg (src, POINTER_TYPE))
9044     return NULL_TREE;
9045
9046   /* If SRC and DEST are the same (and not volatile), return DEST.  */
9047   if (operand_equal_p (src, dest, 0))
9048     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
9049
9050   if (optimize_function_for_size_p (cfun))
9051     return NULL_TREE;
9052
9053   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9054   if (!fn)
9055     return NULL_TREE;
9056
9057   if (!len)
9058     {
9059       len = c_strlen (src, 1);
9060       if (! len || TREE_SIDE_EFFECTS (len))
9061         return NULL_TREE;
9062     }
9063
9064   len = size_binop (PLUS_EXPR, len, ssize_int (1));
9065   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
9066                        build_call_expr (fn, 3, dest, src, len));
9067 }
9068
9069 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
9070    If SLEN is not NULL, it represents the length of the source string.
9071    Return NULL_TREE if no simplification can be made.  */
9072
9073 tree
9074 fold_builtin_strncpy (tree fndecl, tree dest, tree src, tree len, tree slen)
9075 {
9076   tree fn;
9077
9078   if (!validate_arg (dest, POINTER_TYPE)
9079       || !validate_arg (src, POINTER_TYPE)
9080       || !validate_arg (len, INTEGER_TYPE))
9081     return NULL_TREE;
9082
9083   /* If the LEN parameter is zero, return DEST.  */
9084   if (integer_zerop (len))
9085     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
9086
9087   /* We can't compare slen with len as constants below if len is not a
9088      constant.  */
9089   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
9090     return NULL_TREE;
9091
9092   if (!slen)
9093     slen = c_strlen (src, 1);
9094
9095   /* Now, we must be passed a constant src ptr parameter.  */
9096   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
9097     return NULL_TREE;
9098
9099   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
9100
9101   /* We do not support simplification of this case, though we do
9102      support it when expanding trees into RTL.  */
9103   /* FIXME: generate a call to __builtin_memset.  */
9104   if (tree_int_cst_lt (slen, len))
9105     return NULL_TREE;
9106
9107   /* OK transform into builtin memcpy.  */
9108   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
9109   if (!fn)
9110     return NULL_TREE;
9111   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
9112                        build_call_expr (fn, 3, dest, src, len));
9113 }
9114
9115 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
9116    arguments to the call, and TYPE is its return type.
9117    Return NULL_TREE if no simplification can be made.  */
9118
9119 static tree
9120 fold_builtin_memchr (tree arg1, tree arg2, tree len, tree type)
9121 {
9122   if (!validate_arg (arg1, POINTER_TYPE)
9123       || !validate_arg (arg2, INTEGER_TYPE)
9124       || !validate_arg (len, INTEGER_TYPE))
9125     return NULL_TREE;
9126   else
9127     {
9128       const char *p1;
9129
9130       if (TREE_CODE (arg2) != INTEGER_CST
9131           || !host_integerp (len, 1))
9132         return NULL_TREE;
9133
9134       p1 = c_getstr (arg1);
9135       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
9136         {
9137           char c;
9138           const char *r;
9139           tree tem;
9140
9141           if (target_char_cast (arg2, &c))
9142             return NULL_TREE;
9143
9144           r = (char *) memchr (p1, c, tree_low_cst (len, 1));
9145
9146           if (r == NULL)
9147             return build_int_cst (TREE_TYPE (arg1), 0);
9148
9149           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
9150                              size_int (r - p1));
9151           return fold_convert (type, tem);
9152         }
9153       return NULL_TREE;
9154     }
9155 }
9156
9157 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
9158    Return NULL_TREE if no simplification can be made.  */
9159
9160 static tree
9161 fold_builtin_memcmp (tree arg1, tree arg2, tree len)
9162 {
9163   const char *p1, *p2;
9164
9165   if (!validate_arg (arg1, POINTER_TYPE)
9166       || !validate_arg (arg2, POINTER_TYPE)
9167       || !validate_arg (len, INTEGER_TYPE))
9168     return NULL_TREE;
9169
9170   /* If the LEN parameter is zero, return zero.  */
9171   if (integer_zerop (len))
9172     return omit_two_operands (integer_type_node, integer_zero_node,
9173                               arg1, arg2);
9174
9175   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9176   if (operand_equal_p (arg1, arg2, 0))
9177     return omit_one_operand (integer_type_node, integer_zero_node, len);
9178
9179   p1 = c_getstr (arg1);
9180   p2 = c_getstr (arg2);
9181
9182   /* If all arguments are constant, and the value of len is not greater
9183      than the lengths of arg1 and arg2, evaluate at compile-time.  */
9184   if (host_integerp (len, 1) && p1 && p2
9185       && compare_tree_int (len, strlen (p1) + 1) <= 0
9186       && compare_tree_int (len, strlen (p2) + 1) <= 0)
9187     {
9188       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
9189
9190       if (r > 0)
9191         return integer_one_node;
9192       else if (r < 0)
9193         return integer_minus_one_node;
9194       else
9195         return integer_zero_node;
9196     }
9197
9198   /* If len parameter is one, return an expression corresponding to
9199      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9200   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9201     {
9202       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9203       tree cst_uchar_ptr_node
9204         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9205
9206       tree ind1 = fold_convert (integer_type_node,
9207                                 build1 (INDIRECT_REF, cst_uchar_node,
9208                                         fold_convert (cst_uchar_ptr_node,
9209                                                       arg1)));
9210       tree ind2 = fold_convert (integer_type_node,
9211                                 build1 (INDIRECT_REF, cst_uchar_node,
9212                                         fold_convert (cst_uchar_ptr_node,
9213                                                       arg2)));
9214       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9215     }
9216
9217   return NULL_TREE;
9218 }
9219
9220 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
9221    Return NULL_TREE if no simplification can be made.  */
9222
9223 static tree
9224 fold_builtin_strcmp (tree arg1, tree arg2)
9225 {
9226   const char *p1, *p2;
9227
9228   if (!validate_arg (arg1, POINTER_TYPE)
9229       || !validate_arg (arg2, POINTER_TYPE))
9230     return NULL_TREE;
9231
9232   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9233   if (operand_equal_p (arg1, arg2, 0))
9234     return integer_zero_node;
9235
9236   p1 = c_getstr (arg1);
9237   p2 = c_getstr (arg2);
9238
9239   if (p1 && p2)
9240     {
9241       const int i = strcmp (p1, p2);
9242       if (i < 0)
9243         return integer_minus_one_node;
9244       else if (i > 0)
9245         return integer_one_node;
9246       else
9247         return integer_zero_node;
9248     }
9249
9250   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9251   if (p2 && *p2 == '\0')
9252     {
9253       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9254       tree cst_uchar_ptr_node
9255         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9256
9257       return fold_convert (integer_type_node,
9258                            build1 (INDIRECT_REF, cst_uchar_node,
9259                                    fold_convert (cst_uchar_ptr_node,
9260                                                  arg1)));
9261     }
9262
9263   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9264   if (p1 && *p1 == '\0')
9265     {
9266       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9267       tree cst_uchar_ptr_node
9268         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9269
9270       tree temp = fold_convert (integer_type_node,
9271                                 build1 (INDIRECT_REF, cst_uchar_node,
9272                                         fold_convert (cst_uchar_ptr_node,
9273                                                       arg2)));
9274       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9275     }
9276
9277   return NULL_TREE;
9278 }
9279
9280 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9281    Return NULL_TREE if no simplification can be made.  */
9282
9283 static tree
9284 fold_builtin_strncmp (tree arg1, tree arg2, tree len)
9285 {
9286   const char *p1, *p2;
9287
9288   if (!validate_arg (arg1, POINTER_TYPE)
9289       || !validate_arg (arg2, POINTER_TYPE)
9290       || !validate_arg (len, INTEGER_TYPE))
9291     return NULL_TREE;
9292
9293   /* If the LEN parameter is zero, return zero.  */
9294   if (integer_zerop (len))
9295     return omit_two_operands (integer_type_node, integer_zero_node,
9296                               arg1, arg2);
9297
9298   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9299   if (operand_equal_p (arg1, arg2, 0))
9300     return omit_one_operand (integer_type_node, integer_zero_node, len);
9301
9302   p1 = c_getstr (arg1);
9303   p2 = c_getstr (arg2);
9304
9305   if (host_integerp (len, 1) && p1 && p2)
9306     {
9307       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9308       if (i > 0)
9309         return integer_one_node;
9310       else if (i < 0)
9311         return integer_minus_one_node;
9312       else
9313         return integer_zero_node;
9314     }
9315
9316   /* If the second arg is "", and the length is greater than zero,
9317      return *(const unsigned char*)arg1.  */
9318   if (p2 && *p2 == '\0'
9319       && TREE_CODE (len) == INTEGER_CST
9320       && tree_int_cst_sgn (len) == 1)
9321     {
9322       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9323       tree cst_uchar_ptr_node
9324         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9325
9326       return fold_convert (integer_type_node,
9327                            build1 (INDIRECT_REF, cst_uchar_node,
9328                                    fold_convert (cst_uchar_ptr_node,
9329                                                  arg1)));
9330     }
9331
9332   /* If the first arg is "", and the length is greater than zero,
9333      return -*(const unsigned char*)arg2.  */
9334   if (p1 && *p1 == '\0'
9335       && TREE_CODE (len) == INTEGER_CST
9336       && tree_int_cst_sgn (len) == 1)
9337     {
9338       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9339       tree cst_uchar_ptr_node
9340         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9341
9342       tree temp = fold_convert (integer_type_node,
9343                                 build1 (INDIRECT_REF, cst_uchar_node,
9344                                         fold_convert (cst_uchar_ptr_node,
9345                                                       arg2)));
9346       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
9347     }
9348
9349   /* If len parameter is one, return an expression corresponding to
9350      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9351   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9352     {
9353       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9354       tree cst_uchar_ptr_node
9355         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9356
9357       tree ind1 = fold_convert (integer_type_node,
9358                                 build1 (INDIRECT_REF, cst_uchar_node,
9359                                         fold_convert (cst_uchar_ptr_node,
9360                                                       arg1)));
9361       tree ind2 = fold_convert (integer_type_node,
9362                                 build1 (INDIRECT_REF, cst_uchar_node,
9363                                         fold_convert (cst_uchar_ptr_node,
9364                                                       arg2)));
9365       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
9366     }
9367
9368   return NULL_TREE;
9369 }
9370
9371 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9372    ARG.  Return NULL_TREE if no simplification can be made.  */
9373
9374 static tree
9375 fold_builtin_signbit (tree arg, tree type)
9376 {
9377   tree temp;
9378
9379   if (!validate_arg (arg, REAL_TYPE))
9380     return NULL_TREE;
9381
9382   /* If ARG is a compile-time constant, determine the result.  */
9383   if (TREE_CODE (arg) == REAL_CST
9384       && !TREE_OVERFLOW (arg))
9385     {
9386       REAL_VALUE_TYPE c;
9387
9388       c = TREE_REAL_CST (arg);
9389       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
9390       return fold_convert (type, temp);
9391     }
9392
9393   /* If ARG is non-negative, the result is always zero.  */
9394   if (tree_expr_nonnegative_p (arg))
9395     return omit_one_operand (type, integer_zero_node, arg);
9396
9397   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9398   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9399     return fold_build2 (LT_EXPR, type, arg,
9400                         build_real (TREE_TYPE (arg), dconst0));
9401
9402   return NULL_TREE;
9403 }
9404
9405 /* Fold function call to builtin copysign, copysignf or copysignl with
9406    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9407    be made.  */
9408
9409 static tree
9410 fold_builtin_copysign (tree fndecl, tree arg1, tree arg2, tree type)
9411 {
9412   tree tem;
9413
9414   if (!validate_arg (arg1, REAL_TYPE)
9415       || !validate_arg (arg2, REAL_TYPE))
9416     return NULL_TREE;
9417
9418   /* copysign(X,X) is X.  */
9419   if (operand_equal_p (arg1, arg2, 0))
9420     return fold_convert (type, arg1);
9421
9422   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9423   if (TREE_CODE (arg1) == REAL_CST
9424       && TREE_CODE (arg2) == REAL_CST
9425       && !TREE_OVERFLOW (arg1)
9426       && !TREE_OVERFLOW (arg2))
9427     {
9428       REAL_VALUE_TYPE c1, c2;
9429
9430       c1 = TREE_REAL_CST (arg1);
9431       c2 = TREE_REAL_CST (arg2);
9432       /* c1.sign := c2.sign.  */
9433       real_copysign (&c1, &c2);
9434       return build_real (type, c1);
9435     }
9436
9437   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9438      Remember to evaluate Y for side-effects.  */
9439   if (tree_expr_nonnegative_p (arg2))
9440     return omit_one_operand (type,
9441                              fold_build1 (ABS_EXPR, type, arg1),
9442                              arg2);
9443
9444   /* Strip sign changing operations for the first argument.  */
9445   tem = fold_strip_sign_ops (arg1);
9446   if (tem)
9447     return build_call_expr (fndecl, 2, tem, arg2);
9448
9449   return NULL_TREE;
9450 }
9451
9452 /* Fold a call to builtin isascii with argument ARG.  */
9453
9454 static tree
9455 fold_builtin_isascii (tree arg)
9456 {
9457   if (!validate_arg (arg, INTEGER_TYPE))
9458     return NULL_TREE;
9459   else
9460     {
9461       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9462       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
9463                     build_int_cst (NULL_TREE,
9464                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
9465       return fold_build2 (EQ_EXPR, integer_type_node,
9466                           arg, integer_zero_node);
9467     }
9468 }
9469
9470 /* Fold a call to builtin toascii with argument ARG.  */
9471
9472 static tree
9473 fold_builtin_toascii (tree arg)
9474 {
9475   if (!validate_arg (arg, INTEGER_TYPE))
9476     return NULL_TREE;
9477       
9478   /* Transform toascii(c) -> (c & 0x7f).  */
9479   return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9480                       build_int_cst (NULL_TREE, 0x7f));
9481 }
9482
9483 /* Fold a call to builtin isdigit with argument ARG.  */
9484
9485 static tree
9486 fold_builtin_isdigit (tree arg)
9487 {
9488   if (!validate_arg (arg, INTEGER_TYPE))
9489     return NULL_TREE;
9490   else
9491     {
9492       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9493       /* According to the C standard, isdigit is unaffected by locale.
9494          However, it definitely is affected by the target character set.  */
9495       unsigned HOST_WIDE_INT target_digit0
9496         = lang_hooks.to_target_charset ('0');
9497
9498       if (target_digit0 == 0)
9499         return NULL_TREE;
9500
9501       arg = fold_convert (unsigned_type_node, arg);
9502       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
9503                     build_int_cst (unsigned_type_node, target_digit0));
9504       return fold_build2 (LE_EXPR, integer_type_node, arg,
9505                           build_int_cst (unsigned_type_node, 9));
9506     }
9507 }
9508
9509 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9510
9511 static tree
9512 fold_builtin_fabs (tree arg, tree type)
9513 {
9514   if (!validate_arg (arg, REAL_TYPE))
9515     return NULL_TREE;
9516
9517   arg = fold_convert (type, arg);
9518   if (TREE_CODE (arg) == REAL_CST)
9519     return fold_abs_const (arg, type);
9520   return fold_build1 (ABS_EXPR, type, arg);
9521 }
9522
9523 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9524
9525 static tree
9526 fold_builtin_abs (tree arg, tree type)
9527 {
9528   if (!validate_arg (arg, INTEGER_TYPE))
9529     return NULL_TREE;
9530
9531   arg = fold_convert (type, arg);
9532   if (TREE_CODE (arg) == INTEGER_CST)
9533     return fold_abs_const (arg, type);
9534   return fold_build1 (ABS_EXPR, type, arg);
9535 }
9536
9537 /* Fold a call to builtin fmin or fmax.  */
9538
9539 static tree
9540 fold_builtin_fmin_fmax (tree arg0, tree arg1, tree type, bool max)
9541 {
9542   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9543     {
9544       /* Calculate the result when the argument is a constant.  */
9545       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9546
9547       if (res)
9548         return res;
9549
9550       /* If either argument is NaN, return the other one.  Avoid the
9551          transformation if we get (and honor) a signalling NaN.  Using
9552          omit_one_operand() ensures we create a non-lvalue.  */
9553       if (TREE_CODE (arg0) == REAL_CST
9554           && real_isnan (&TREE_REAL_CST (arg0))
9555           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9556               || ! TREE_REAL_CST (arg0).signalling))
9557         return omit_one_operand (type, arg1, arg0);
9558       if (TREE_CODE (arg1) == REAL_CST
9559           && real_isnan (&TREE_REAL_CST (arg1))
9560           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9561               || ! TREE_REAL_CST (arg1).signalling))
9562         return omit_one_operand (type, arg0, arg1);
9563
9564       /* Transform fmin/fmax(x,x) -> x.  */
9565       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9566         return omit_one_operand (type, arg0, arg1);
9567       
9568       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9569          functions to return the numeric arg if the other one is NaN.
9570          These tree codes don't honor that, so only transform if
9571          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9572          handled, so we don't have to worry about it either.  */
9573       if (flag_finite_math_only)
9574         return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9575                             fold_convert (type, arg0),
9576                             fold_convert (type, arg1));
9577     }
9578   return NULL_TREE;
9579 }
9580
9581 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9582
9583 static tree
9584 fold_builtin_carg (tree arg, tree type)
9585 {
9586   if (validate_arg (arg, COMPLEX_TYPE))
9587     {
9588       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9589       
9590       if (atan2_fn)
9591         {
9592           tree new_arg = builtin_save_expr (arg);
9593           tree r_arg = fold_build1 (REALPART_EXPR, type, new_arg);
9594           tree i_arg = fold_build1 (IMAGPART_EXPR, type, new_arg);
9595           return build_call_expr (atan2_fn, 2, i_arg, r_arg);
9596         }
9597     }
9598   
9599   return NULL_TREE;
9600 }
9601
9602 /* Fold a call to builtin logb/ilogb.  */
9603
9604 static tree
9605 fold_builtin_logb (tree arg, tree rettype)
9606 {
9607   if (! validate_arg (arg, REAL_TYPE))
9608     return NULL_TREE;
9609   
9610   STRIP_NOPS (arg);
9611       
9612   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9613     {
9614       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9615           
9616       switch (value->cl)
9617       {
9618       case rvc_nan:
9619       case rvc_inf:
9620         /* If arg is Inf or NaN and we're logb, return it.  */
9621         if (TREE_CODE (rettype) == REAL_TYPE)
9622           return fold_convert (rettype, arg);
9623         /* Fall through... */
9624       case rvc_zero:
9625         /* Zero may set errno and/or raise an exception for logb, also
9626            for ilogb we don't know FP_ILOGB0.  */
9627         return NULL_TREE;
9628       case rvc_normal:
9629         /* For normal numbers, proceed iff radix == 2.  In GCC,
9630            normalized significands are in the range [0.5, 1.0).  We
9631            want the exponent as if they were [1.0, 2.0) so get the
9632            exponent and subtract 1.  */
9633         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9634           return fold_convert (rettype, build_int_cst (NULL_TREE,
9635                                                        REAL_EXP (value)-1));
9636         break;
9637       }
9638     }
9639   
9640   return NULL_TREE;
9641 }
9642
9643 /* Fold a call to builtin significand, if radix == 2.  */
9644
9645 static tree
9646 fold_builtin_significand (tree arg, tree rettype)
9647 {
9648   if (! validate_arg (arg, REAL_TYPE))
9649     return NULL_TREE;
9650   
9651   STRIP_NOPS (arg);
9652       
9653   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9654     {
9655       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9656           
9657       switch (value->cl)
9658       {
9659       case rvc_zero:
9660       case rvc_nan:
9661       case rvc_inf:
9662         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9663         return fold_convert (rettype, arg);
9664       case rvc_normal:
9665         /* For normal numbers, proceed iff radix == 2.  */
9666         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9667           {
9668             REAL_VALUE_TYPE result = *value;
9669             /* In GCC, normalized significands are in the range [0.5,
9670                1.0).  We want them to be [1.0, 2.0) so set the
9671                exponent to 1.  */
9672             SET_REAL_EXP (&result, 1);
9673             return build_real (rettype, result);
9674           }
9675         break;
9676       }
9677     }
9678   
9679   return NULL_TREE;
9680 }
9681
9682 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9683
9684 static tree
9685 fold_builtin_frexp (tree arg0, tree arg1, tree rettype)
9686 {
9687   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9688     return NULL_TREE;
9689   
9690   STRIP_NOPS (arg0);
9691       
9692   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9693     return NULL_TREE;
9694   
9695   arg1 = build_fold_indirect_ref (arg1);
9696
9697   /* Proceed if a valid pointer type was passed in.  */
9698   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9699     {
9700       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9701       tree frac, exp;
9702           
9703       switch (value->cl)
9704       {
9705       case rvc_zero:
9706         /* For +-0, return (*exp = 0, +-0).  */
9707         exp = integer_zero_node;
9708         frac = arg0;
9709         break;
9710       case rvc_nan:
9711       case rvc_inf:
9712         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9713         return omit_one_operand (rettype, arg0, arg1);
9714       case rvc_normal:
9715         {
9716           /* Since the frexp function always expects base 2, and in
9717              GCC normalized significands are already in the range
9718              [0.5, 1.0), we have exactly what frexp wants.  */
9719           REAL_VALUE_TYPE frac_rvt = *value;
9720           SET_REAL_EXP (&frac_rvt, 0);
9721           frac = build_real (rettype, frac_rvt);
9722           exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9723         }
9724         break;
9725       default:
9726         gcc_unreachable ();
9727       }
9728                 
9729       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9730       arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1, exp);
9731       TREE_SIDE_EFFECTS (arg1) = 1;
9732       return fold_build2 (COMPOUND_EXPR, rettype, arg1, frac);
9733     }
9734
9735   return NULL_TREE;
9736 }
9737
9738 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9739    then we can assume the base is two.  If it's false, then we have to
9740    check the mode of the TYPE parameter in certain cases.  */
9741
9742 static tree
9743 fold_builtin_load_exponent (tree arg0, tree arg1, tree type, bool ldexp)
9744 {
9745   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9746     {
9747       STRIP_NOPS (arg0);
9748       STRIP_NOPS (arg1);
9749
9750       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9751       if (real_zerop (arg0) || integer_zerop (arg1)
9752           || (TREE_CODE (arg0) == REAL_CST
9753               && !real_isfinite (&TREE_REAL_CST (arg0))))
9754         return omit_one_operand (type, arg0, arg1);
9755       
9756       /* If both arguments are constant, then try to evaluate it.  */
9757       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9758           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9759           && host_integerp (arg1, 0))
9760         {
9761           /* Bound the maximum adjustment to twice the range of the
9762              mode's valid exponents.  Use abs to ensure the range is
9763              positive as a sanity check.  */
9764           const long max_exp_adj = 2 * 
9765             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9766                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9767
9768           /* Get the user-requested adjustment.  */
9769           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9770           
9771           /* The requested adjustment must be inside this range.  This
9772              is a preliminary cap to avoid things like overflow, we
9773              may still fail to compute the result for other reasons.  */
9774           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9775             {
9776               REAL_VALUE_TYPE initial_result;
9777               
9778               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9779
9780               /* Ensure we didn't overflow.  */
9781               if (! real_isinf (&initial_result))
9782                 {
9783                   const REAL_VALUE_TYPE trunc_result
9784                     = real_value_truncate (TYPE_MODE (type), initial_result);
9785                   
9786                   /* Only proceed if the target mode can hold the
9787                      resulting value.  */
9788                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9789                     return build_real (type, trunc_result);
9790                 }
9791             }
9792         }
9793     }
9794
9795   return NULL_TREE;
9796 }
9797
9798 /* Fold a call to builtin modf.  */
9799
9800 static tree
9801 fold_builtin_modf (tree arg0, tree arg1, tree rettype)
9802 {
9803   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9804     return NULL_TREE;
9805   
9806   STRIP_NOPS (arg0);
9807       
9808   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9809     return NULL_TREE;
9810   
9811   arg1 = build_fold_indirect_ref (arg1);
9812
9813   /* Proceed if a valid pointer type was passed in.  */
9814   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9815     {
9816       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9817       REAL_VALUE_TYPE trunc, frac;
9818
9819       switch (value->cl)
9820       {
9821       case rvc_nan:
9822       case rvc_zero:
9823         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9824         trunc = frac = *value;
9825         break;
9826       case rvc_inf:
9827         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9828         frac = dconst0;
9829         frac.sign = value->sign;
9830         trunc = *value;
9831         break;
9832       case rvc_normal:
9833         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9834         real_trunc (&trunc, VOIDmode, value);
9835         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9836         /* If the original number was negative and already
9837            integral, then the fractional part is -0.0.  */
9838         if (value->sign && frac.cl == rvc_zero)
9839           frac.sign = value->sign;
9840         break;
9841       }
9842               
9843       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9844       arg1 = fold_build2 (MODIFY_EXPR, rettype, arg1,
9845                           build_real (rettype, trunc));
9846       TREE_SIDE_EFFECTS (arg1) = 1;
9847       return fold_build2 (COMPOUND_EXPR, rettype, arg1,
9848                           build_real (rettype, frac));
9849     }
9850   
9851   return NULL_TREE;
9852 }
9853
9854 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9855    ARG is the argument for the call.  */
9856
9857 static tree
9858 fold_builtin_classify (tree fndecl, tree arg, int builtin_index)
9859 {
9860   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9861   REAL_VALUE_TYPE r;
9862
9863   if (!validate_arg (arg, REAL_TYPE))
9864     return NULL_TREE;
9865
9866   switch (builtin_index)
9867     {
9868     case BUILT_IN_ISINF:
9869       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9870         return omit_one_operand (type, integer_zero_node, arg);
9871
9872       if (TREE_CODE (arg) == REAL_CST)
9873         {
9874           r = TREE_REAL_CST (arg);
9875           if (real_isinf (&r))
9876             return real_compare (GT_EXPR, &r, &dconst0)
9877                    ? integer_one_node : integer_minus_one_node;
9878           else
9879             return integer_zero_node;
9880         }
9881
9882       return NULL_TREE;
9883
9884     case BUILT_IN_ISINF_SIGN:
9885       {
9886         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9887         /* In a boolean context, GCC will fold the inner COND_EXPR to
9888            1.  So e.g. "if (isinf_sign(x))" would be folded to just
9889            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9890         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9891         tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9892         tree tmp = NULL_TREE;
9893
9894         arg = builtin_save_expr (arg);
9895
9896         if (signbit_fn && isinf_fn)
9897           {
9898             tree signbit_call = build_call_expr (signbit_fn, 1, arg);
9899             tree isinf_call = build_call_expr (isinf_fn, 1, arg);
9900
9901             signbit_call = fold_build2 (NE_EXPR, integer_type_node,
9902                                         signbit_call, integer_zero_node);
9903             isinf_call = fold_build2 (NE_EXPR, integer_type_node,
9904                                       isinf_call, integer_zero_node);
9905             
9906             tmp = fold_build3 (COND_EXPR, integer_type_node, signbit_call,
9907                                integer_minus_one_node, integer_one_node);
9908             tmp = fold_build3 (COND_EXPR, integer_type_node, isinf_call, tmp,
9909                                integer_zero_node);
9910           }
9911
9912         return tmp;
9913       }
9914
9915     case BUILT_IN_ISFINITE:
9916       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9917           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9918         return omit_one_operand (type, integer_one_node, arg);
9919
9920       if (TREE_CODE (arg) == REAL_CST)
9921         {
9922           r = TREE_REAL_CST (arg);
9923           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
9924         }
9925
9926       return NULL_TREE;
9927
9928     case BUILT_IN_ISNAN:
9929       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9930         return omit_one_operand (type, integer_zero_node, arg);
9931
9932       if (TREE_CODE (arg) == REAL_CST)
9933         {
9934           r = TREE_REAL_CST (arg);
9935           return real_isnan (&r) ? integer_one_node : integer_zero_node;
9936         }
9937
9938       arg = builtin_save_expr (arg);
9939       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9940
9941     default:
9942       gcc_unreachable ();
9943     }
9944 }
9945
9946 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9947    This builtin will generate code to return the appropriate floating
9948    point classification depending on the value of the floating point
9949    number passed in.  The possible return values must be supplied as
9950    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
9951    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
9952    one floating point argument which is "type generic".  */
9953
9954 static tree
9955 fold_builtin_fpclassify (tree exp)
9956 {
9957   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9958     arg, type, res, tmp;
9959   enum machine_mode mode;
9960   REAL_VALUE_TYPE r;
9961   char buf[128];
9962   
9963   /* Verify the required arguments in the original call.  */
9964   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9965                          INTEGER_TYPE, INTEGER_TYPE,
9966                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9967     return NULL_TREE;
9968   
9969   fp_nan = CALL_EXPR_ARG (exp, 0);
9970   fp_infinite = CALL_EXPR_ARG (exp, 1);
9971   fp_normal = CALL_EXPR_ARG (exp, 2);
9972   fp_subnormal = CALL_EXPR_ARG (exp, 3);
9973   fp_zero = CALL_EXPR_ARG (exp, 4);
9974   arg = CALL_EXPR_ARG (exp, 5);
9975   type = TREE_TYPE (arg);
9976   mode = TYPE_MODE (type);
9977   arg = builtin_save_expr (fold_build1 (ABS_EXPR, type, arg));
9978
9979   /* fpclassify(x) -> 
9980        isnan(x) ? FP_NAN :
9981          (fabs(x) == Inf ? FP_INFINITE :
9982            (fabs(x) >= DBL_MIN ? FP_NORMAL :
9983              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
9984   
9985   tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9986                      build_real (type, dconst0));
9987   res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_zero, fp_subnormal);
9988
9989   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9990   real_from_string (&r, buf);
9991   tmp = fold_build2 (GE_EXPR, integer_type_node, arg, build_real (type, r));
9992   res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_normal, res);
9993   
9994   if (HONOR_INFINITIES (mode))
9995     {
9996       real_inf (&r);
9997       tmp = fold_build2 (EQ_EXPR, integer_type_node, arg,
9998                          build_real (type, r));
9999       res = fold_build3 (COND_EXPR, integer_type_node, tmp, fp_infinite, res);
10000     }
10001
10002   if (HONOR_NANS (mode))
10003     {
10004       tmp = fold_build2 (ORDERED_EXPR, integer_type_node, arg, arg);
10005       res = fold_build3 (COND_EXPR, integer_type_node, tmp, res, fp_nan);
10006     }
10007   
10008   return res;
10009 }
10010
10011 /* Fold a call to an unordered comparison function such as
10012    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
10013    being called and ARG0 and ARG1 are the arguments for the call.
10014    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
10015    the opposite of the desired result.  UNORDERED_CODE is used
10016    for modes that can hold NaNs and ORDERED_CODE is used for
10017    the rest.  */
10018
10019 static tree
10020 fold_builtin_unordered_cmp (tree fndecl, tree arg0, tree arg1,
10021                             enum tree_code unordered_code,
10022                             enum tree_code ordered_code)
10023 {
10024   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10025   enum tree_code code;
10026   tree type0, type1;
10027   enum tree_code code0, code1;
10028   tree cmp_type = NULL_TREE;
10029
10030   type0 = TREE_TYPE (arg0);
10031   type1 = TREE_TYPE (arg1);
10032
10033   code0 = TREE_CODE (type0);
10034   code1 = TREE_CODE (type1);
10035
10036   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
10037     /* Choose the wider of two real types.  */
10038     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
10039       ? type0 : type1;
10040   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
10041     cmp_type = type0;
10042   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
10043     cmp_type = type1;
10044
10045   arg0 = fold_convert (cmp_type, arg0);
10046   arg1 = fold_convert (cmp_type, arg1);
10047
10048   if (unordered_code == UNORDERED_EXPR)
10049     {
10050       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
10051         return omit_two_operands (type, integer_zero_node, arg0, arg1);
10052       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
10053     }
10054
10055   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
10056                                                    : ordered_code;
10057   return fold_build1 (TRUTH_NOT_EXPR, type,
10058                       fold_build2 (code, type, arg0, arg1));
10059 }
10060
10061 /* Fold a call to built-in function FNDECL with 0 arguments.
10062    IGNORE is true if the result of the function call is ignored.  This
10063    function returns NULL_TREE if no simplification was possible.  */
10064
10065 static tree
10066 fold_builtin_0 (tree fndecl, bool ignore ATTRIBUTE_UNUSED)
10067 {
10068   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10069   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10070   switch (fcode)
10071     {
10072     CASE_FLT_FN (BUILT_IN_INF):
10073     case BUILT_IN_INFD32:
10074     case BUILT_IN_INFD64:
10075     case BUILT_IN_INFD128:
10076       return fold_builtin_inf (type, true);
10077
10078     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
10079       return fold_builtin_inf (type, false);
10080
10081     case BUILT_IN_CLASSIFY_TYPE:
10082       return fold_builtin_classify_type (NULL_TREE);
10083
10084     default:
10085       break;
10086     }
10087   return NULL_TREE;
10088 }
10089
10090 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
10091    IGNORE is true if the result of the function call is ignored.  This
10092    function returns NULL_TREE if no simplification was possible.  */
10093
10094 static tree
10095 fold_builtin_1 (tree fndecl, tree arg0, bool ignore)
10096 {
10097   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10098   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10099   switch (fcode)
10100     {
10101
10102     case BUILT_IN_CONSTANT_P:
10103       {
10104         tree val = fold_builtin_constant_p (arg0);
10105
10106         /* Gimplification will pull the CALL_EXPR for the builtin out of
10107            an if condition.  When not optimizing, we'll not CSE it back.
10108            To avoid link error types of regressions, return false now.  */
10109         if (!val && !optimize)
10110           val = integer_zero_node;
10111
10112         return val;
10113       }
10114
10115     case BUILT_IN_CLASSIFY_TYPE:
10116       return fold_builtin_classify_type (arg0);
10117
10118     case BUILT_IN_STRLEN:
10119       return fold_builtin_strlen (arg0);
10120
10121     CASE_FLT_FN (BUILT_IN_FABS):
10122       return fold_builtin_fabs (arg0, type);
10123
10124     case BUILT_IN_ABS:
10125     case BUILT_IN_LABS:
10126     case BUILT_IN_LLABS:
10127     case BUILT_IN_IMAXABS:
10128       return fold_builtin_abs (arg0, type);
10129
10130     CASE_FLT_FN (BUILT_IN_CONJ):
10131       if (validate_arg (arg0, COMPLEX_TYPE))
10132         return fold_build1 (CONJ_EXPR, type, arg0);
10133     break;
10134
10135     CASE_FLT_FN (BUILT_IN_CREAL):
10136       if (validate_arg (arg0, COMPLEX_TYPE))
10137         return non_lvalue (fold_build1 (REALPART_EXPR, type, arg0));;
10138     break;
10139
10140     CASE_FLT_FN (BUILT_IN_CIMAG):
10141       if (validate_arg (arg0, COMPLEX_TYPE))
10142         return non_lvalue (fold_build1 (IMAGPART_EXPR, type, arg0));
10143     break;
10144
10145     CASE_FLT_FN (BUILT_IN_CCOS):
10146     CASE_FLT_FN (BUILT_IN_CCOSH):
10147       /* These functions are "even", i.e. f(x) == f(-x).  */
10148       if (validate_arg (arg0, COMPLEX_TYPE))
10149         {
10150           tree narg = fold_strip_sign_ops (arg0);
10151           if (narg)
10152             return build_call_expr (fndecl, 1, narg);
10153         }
10154     break;
10155
10156     CASE_FLT_FN (BUILT_IN_CABS):
10157       return fold_builtin_cabs (arg0, type, fndecl);
10158
10159     CASE_FLT_FN (BUILT_IN_CARG):
10160       return fold_builtin_carg (arg0, type);
10161
10162     CASE_FLT_FN (BUILT_IN_SQRT):
10163       return fold_builtin_sqrt (arg0, type);
10164
10165     CASE_FLT_FN (BUILT_IN_CBRT):
10166       return fold_builtin_cbrt (arg0, type);
10167
10168     CASE_FLT_FN (BUILT_IN_ASIN):
10169       if (validate_arg (arg0, REAL_TYPE))
10170         return do_mpfr_arg1 (arg0, type, mpfr_asin,
10171                              &dconstm1, &dconst1, true);
10172     break;
10173
10174     CASE_FLT_FN (BUILT_IN_ACOS):
10175       if (validate_arg (arg0, REAL_TYPE))
10176         return do_mpfr_arg1 (arg0, type, mpfr_acos,
10177                              &dconstm1, &dconst1, true);
10178     break;
10179
10180     CASE_FLT_FN (BUILT_IN_ATAN):
10181       if (validate_arg (arg0, REAL_TYPE))
10182         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10183     break;
10184
10185     CASE_FLT_FN (BUILT_IN_ASINH):
10186       if (validate_arg (arg0, REAL_TYPE))
10187         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10188     break;
10189
10190     CASE_FLT_FN (BUILT_IN_ACOSH):
10191       if (validate_arg (arg0, REAL_TYPE))
10192         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10193                              &dconst1, NULL, true);
10194     break;
10195
10196     CASE_FLT_FN (BUILT_IN_ATANH):
10197       if (validate_arg (arg0, REAL_TYPE))
10198         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10199                              &dconstm1, &dconst1, false);
10200     break;
10201
10202     CASE_FLT_FN (BUILT_IN_SIN):
10203       if (validate_arg (arg0, REAL_TYPE))
10204         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10205     break;
10206
10207     CASE_FLT_FN (BUILT_IN_COS):
10208       return fold_builtin_cos (arg0, type, fndecl);
10209     break;
10210
10211     CASE_FLT_FN (BUILT_IN_TAN):
10212       return fold_builtin_tan (arg0, type);
10213
10214     CASE_FLT_FN (BUILT_IN_CEXP):
10215       return fold_builtin_cexp (arg0, type);
10216
10217     CASE_FLT_FN (BUILT_IN_CEXPI):
10218       if (validate_arg (arg0, REAL_TYPE))
10219         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10220     break;
10221
10222     CASE_FLT_FN (BUILT_IN_SINH):
10223       if (validate_arg (arg0, REAL_TYPE))
10224         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10225     break;
10226
10227     CASE_FLT_FN (BUILT_IN_COSH):
10228       return fold_builtin_cosh (arg0, type, fndecl);
10229
10230     CASE_FLT_FN (BUILT_IN_TANH):
10231       if (validate_arg (arg0, REAL_TYPE))
10232         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10233     break;
10234
10235     CASE_FLT_FN (BUILT_IN_ERF):
10236       if (validate_arg (arg0, REAL_TYPE))
10237         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10238     break;
10239
10240     CASE_FLT_FN (BUILT_IN_ERFC):
10241       if (validate_arg (arg0, REAL_TYPE))
10242         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10243     break;
10244
10245     CASE_FLT_FN (BUILT_IN_TGAMMA):
10246       if (validate_arg (arg0, REAL_TYPE))
10247         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10248     break;
10249  
10250     CASE_FLT_FN (BUILT_IN_EXP):
10251       return fold_builtin_exponent (fndecl, arg0, mpfr_exp);
10252
10253     CASE_FLT_FN (BUILT_IN_EXP2):
10254       return fold_builtin_exponent (fndecl, arg0, mpfr_exp2);
10255
10256     CASE_FLT_FN (BUILT_IN_EXP10):
10257     CASE_FLT_FN (BUILT_IN_POW10):
10258       return fold_builtin_exponent (fndecl, arg0, mpfr_exp10);
10259
10260     CASE_FLT_FN (BUILT_IN_EXPM1):
10261       if (validate_arg (arg0, REAL_TYPE))
10262         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10263     break;
10264  
10265     CASE_FLT_FN (BUILT_IN_LOG):
10266       return fold_builtin_logarithm (fndecl, arg0, mpfr_log);
10267
10268     CASE_FLT_FN (BUILT_IN_LOG2):
10269       return fold_builtin_logarithm (fndecl, arg0, mpfr_log2);
10270
10271     CASE_FLT_FN (BUILT_IN_LOG10):
10272       return fold_builtin_logarithm (fndecl, arg0, mpfr_log10);
10273
10274     CASE_FLT_FN (BUILT_IN_LOG1P):
10275       if (validate_arg (arg0, REAL_TYPE))
10276         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10277                              &dconstm1, NULL, false);
10278     break;
10279
10280     CASE_FLT_FN (BUILT_IN_J0):
10281       if (validate_arg (arg0, REAL_TYPE))
10282         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10283                              NULL, NULL, 0);
10284     break;
10285
10286     CASE_FLT_FN (BUILT_IN_J1):
10287       if (validate_arg (arg0, REAL_TYPE))
10288         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10289                              NULL, NULL, 0);
10290     break;
10291
10292     CASE_FLT_FN (BUILT_IN_Y0):
10293       if (validate_arg (arg0, REAL_TYPE))
10294         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10295                              &dconst0, NULL, false);
10296     break;
10297
10298     CASE_FLT_FN (BUILT_IN_Y1):
10299       if (validate_arg (arg0, REAL_TYPE))
10300         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10301                              &dconst0, NULL, false);
10302     break;
10303
10304     CASE_FLT_FN (BUILT_IN_NAN):
10305     case BUILT_IN_NAND32:
10306     case BUILT_IN_NAND64:
10307     case BUILT_IN_NAND128:
10308       return fold_builtin_nan (arg0, type, true);
10309
10310     CASE_FLT_FN (BUILT_IN_NANS):
10311       return fold_builtin_nan (arg0, type, false);
10312
10313     CASE_FLT_FN (BUILT_IN_FLOOR):
10314       return fold_builtin_floor (fndecl, arg0);
10315
10316     CASE_FLT_FN (BUILT_IN_CEIL):
10317       return fold_builtin_ceil (fndecl, arg0);
10318
10319     CASE_FLT_FN (BUILT_IN_TRUNC):
10320       return fold_builtin_trunc (fndecl, arg0);
10321
10322     CASE_FLT_FN (BUILT_IN_ROUND):
10323       return fold_builtin_round (fndecl, arg0);
10324
10325     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10326     CASE_FLT_FN (BUILT_IN_RINT):
10327       return fold_trunc_transparent_mathfn (fndecl, arg0);
10328
10329     CASE_FLT_FN (BUILT_IN_LCEIL):
10330     CASE_FLT_FN (BUILT_IN_LLCEIL):
10331     CASE_FLT_FN (BUILT_IN_LFLOOR):
10332     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10333     CASE_FLT_FN (BUILT_IN_LROUND):
10334     CASE_FLT_FN (BUILT_IN_LLROUND):
10335       return fold_builtin_int_roundingfn (fndecl, arg0);
10336
10337     CASE_FLT_FN (BUILT_IN_LRINT):
10338     CASE_FLT_FN (BUILT_IN_LLRINT):
10339       return fold_fixed_mathfn (fndecl, arg0);
10340
10341     case BUILT_IN_BSWAP32:
10342     case BUILT_IN_BSWAP64:
10343       return fold_builtin_bswap (fndecl, arg0);
10344
10345     CASE_INT_FN (BUILT_IN_FFS):
10346     CASE_INT_FN (BUILT_IN_CLZ):
10347     CASE_INT_FN (BUILT_IN_CTZ):
10348     CASE_INT_FN (BUILT_IN_POPCOUNT):
10349     CASE_INT_FN (BUILT_IN_PARITY):
10350       return fold_builtin_bitop (fndecl, arg0);
10351
10352     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10353       return fold_builtin_signbit (arg0, type);
10354
10355     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10356       return fold_builtin_significand (arg0, type);
10357
10358     CASE_FLT_FN (BUILT_IN_ILOGB):
10359     CASE_FLT_FN (BUILT_IN_LOGB):
10360       return fold_builtin_logb (arg0, type);
10361
10362     case BUILT_IN_ISASCII:
10363       return fold_builtin_isascii (arg0);
10364
10365     case BUILT_IN_TOASCII:
10366       return fold_builtin_toascii (arg0);
10367
10368     case BUILT_IN_ISDIGIT:
10369       return fold_builtin_isdigit (arg0);
10370
10371     CASE_FLT_FN (BUILT_IN_FINITE):
10372     case BUILT_IN_FINITED32:
10373     case BUILT_IN_FINITED64:
10374     case BUILT_IN_FINITED128:
10375     case BUILT_IN_ISFINITE:
10376       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISFINITE);
10377
10378     CASE_FLT_FN (BUILT_IN_ISINF):
10379     case BUILT_IN_ISINFD32:
10380     case BUILT_IN_ISINFD64:
10381     case BUILT_IN_ISINFD128:
10382       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF);
10383
10384     case BUILT_IN_ISINF_SIGN:
10385       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISINF_SIGN);
10386
10387     CASE_FLT_FN (BUILT_IN_ISNAN):
10388     case BUILT_IN_ISNAND32:
10389     case BUILT_IN_ISNAND64:
10390     case BUILT_IN_ISNAND128:
10391       return fold_builtin_classify (fndecl, arg0, BUILT_IN_ISNAN);
10392
10393     case BUILT_IN_PRINTF:
10394     case BUILT_IN_PRINTF_UNLOCKED:
10395     case BUILT_IN_VPRINTF:
10396       return fold_builtin_printf (fndecl, arg0, NULL_TREE, ignore, fcode);
10397
10398     default:
10399       break;
10400     }
10401
10402   return NULL_TREE;
10403
10404 }
10405
10406 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10407    IGNORE is true if the result of the function call is ignored.  This
10408    function returns NULL_TREE if no simplification was possible.  */
10409
10410 static tree
10411 fold_builtin_2 (tree fndecl, tree arg0, tree arg1, bool ignore)
10412 {
10413   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10414   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10415
10416   switch (fcode)
10417     {
10418     CASE_FLT_FN (BUILT_IN_JN):
10419       if (validate_arg (arg0, INTEGER_TYPE)
10420           && validate_arg (arg1, REAL_TYPE))
10421         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10422     break;
10423
10424     CASE_FLT_FN (BUILT_IN_YN):
10425       if (validate_arg (arg0, INTEGER_TYPE)
10426           && validate_arg (arg1, REAL_TYPE))
10427         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10428                                  &dconst0, false);
10429     break;
10430
10431     CASE_FLT_FN (BUILT_IN_DREM):
10432     CASE_FLT_FN (BUILT_IN_REMAINDER):
10433       if (validate_arg (arg0, REAL_TYPE)
10434           && validate_arg(arg1, REAL_TYPE))
10435         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10436     break;
10437
10438     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10439     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10440       if (validate_arg (arg0, REAL_TYPE)
10441           && validate_arg(arg1, POINTER_TYPE))
10442         return do_mpfr_lgamma_r (arg0, arg1, type);
10443     break;
10444
10445     CASE_FLT_FN (BUILT_IN_ATAN2):
10446       if (validate_arg (arg0, REAL_TYPE)
10447           && validate_arg(arg1, REAL_TYPE))
10448         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10449     break;
10450
10451     CASE_FLT_FN (BUILT_IN_FDIM):
10452       if (validate_arg (arg0, REAL_TYPE)
10453           && validate_arg(arg1, REAL_TYPE))
10454         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10455     break;
10456
10457     CASE_FLT_FN (BUILT_IN_HYPOT):
10458       return fold_builtin_hypot (fndecl, arg0, arg1, type);
10459
10460     CASE_FLT_FN (BUILT_IN_LDEXP):
10461       return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/true);
10462     CASE_FLT_FN (BUILT_IN_SCALBN):
10463     CASE_FLT_FN (BUILT_IN_SCALBLN):
10464       return fold_builtin_load_exponent (arg0, arg1, type, /*ldexp=*/false);
10465
10466     CASE_FLT_FN (BUILT_IN_FREXP):
10467       return fold_builtin_frexp (arg0, arg1, type);
10468
10469     CASE_FLT_FN (BUILT_IN_MODF):
10470       return fold_builtin_modf (arg0, arg1, type);
10471
10472     case BUILT_IN_BZERO:
10473       return fold_builtin_bzero (arg0, arg1, ignore);
10474
10475     case BUILT_IN_FPUTS:
10476       return fold_builtin_fputs (arg0, arg1, ignore, false, NULL_TREE);
10477
10478     case BUILT_IN_FPUTS_UNLOCKED:
10479       return fold_builtin_fputs (arg0, arg1, ignore, true, NULL_TREE);
10480
10481     case BUILT_IN_STRSTR:
10482       return fold_builtin_strstr (arg0, arg1, type);
10483
10484     case BUILT_IN_STRCAT:
10485       return fold_builtin_strcat (arg0, arg1);
10486
10487     case BUILT_IN_STRSPN:
10488       return fold_builtin_strspn (arg0, arg1);
10489
10490     case BUILT_IN_STRCSPN:
10491       return fold_builtin_strcspn (arg0, arg1);
10492
10493     case BUILT_IN_STRCHR:
10494     case BUILT_IN_INDEX:
10495       return fold_builtin_strchr (arg0, arg1, type);
10496
10497     case BUILT_IN_STRRCHR:
10498     case BUILT_IN_RINDEX:
10499       return fold_builtin_strrchr (arg0, arg1, type);
10500
10501     case BUILT_IN_STRCPY:
10502       return fold_builtin_strcpy (fndecl, arg0, arg1, NULL_TREE);
10503
10504     case BUILT_IN_STPCPY:
10505       if (ignore)
10506         {
10507           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10508           if (!fn)
10509             break;
10510
10511           return build_call_expr (fn, 2, arg0, arg1);
10512         }
10513       break;
10514
10515     case BUILT_IN_STRCMP:
10516       return fold_builtin_strcmp (arg0, arg1);
10517
10518     case BUILT_IN_STRPBRK:
10519       return fold_builtin_strpbrk (arg0, arg1, type);
10520
10521     case BUILT_IN_EXPECT:
10522       return fold_builtin_expect (arg0, arg1);
10523
10524     CASE_FLT_FN (BUILT_IN_POW):
10525       return fold_builtin_pow (fndecl, arg0, arg1, type);
10526
10527     CASE_FLT_FN (BUILT_IN_POWI):
10528       return fold_builtin_powi (fndecl, arg0, arg1, type);
10529
10530     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10531       return fold_builtin_copysign (fndecl, arg0, arg1, type);
10532
10533     CASE_FLT_FN (BUILT_IN_FMIN):
10534       return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/false);
10535
10536     CASE_FLT_FN (BUILT_IN_FMAX):
10537       return fold_builtin_fmin_fmax (arg0, arg1, type, /*max=*/true);
10538
10539     case BUILT_IN_ISGREATER:
10540       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLE_EXPR, LE_EXPR);
10541     case BUILT_IN_ISGREATEREQUAL:
10542       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNLT_EXPR, LT_EXPR);
10543     case BUILT_IN_ISLESS:
10544       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGE_EXPR, GE_EXPR);
10545     case BUILT_IN_ISLESSEQUAL:
10546       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNGT_EXPR, GT_EXPR);
10547     case BUILT_IN_ISLESSGREATER:
10548       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10549     case BUILT_IN_ISUNORDERED:
10550       return fold_builtin_unordered_cmp (fndecl, arg0, arg1, UNORDERED_EXPR,
10551                                          NOP_EXPR);
10552
10553       /* We do the folding for va_start in the expander.  */
10554     case BUILT_IN_VA_START:
10555       break;
10556
10557     case BUILT_IN_SPRINTF:
10558       return fold_builtin_sprintf (arg0, arg1, NULL_TREE, ignore);
10559
10560     case BUILT_IN_OBJECT_SIZE:
10561       return fold_builtin_object_size (arg0, arg1);
10562
10563     case BUILT_IN_PRINTF:
10564     case BUILT_IN_PRINTF_UNLOCKED:
10565     case BUILT_IN_VPRINTF:
10566       return fold_builtin_printf (fndecl, arg0, arg1, ignore, fcode);
10567
10568     case BUILT_IN_PRINTF_CHK:
10569     case BUILT_IN_VPRINTF_CHK:
10570       if (!validate_arg (arg0, INTEGER_TYPE)
10571           || TREE_SIDE_EFFECTS (arg0))
10572         return NULL_TREE;
10573       else
10574         return fold_builtin_printf (fndecl, arg1, NULL_TREE, ignore, fcode);
10575     break;
10576
10577     case BUILT_IN_FPRINTF:
10578     case BUILT_IN_FPRINTF_UNLOCKED:
10579     case BUILT_IN_VFPRINTF:
10580       return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
10581                                    ignore, fcode);
10582
10583     default:
10584       break;
10585     }
10586   return NULL_TREE;
10587 }
10588
10589 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10590    and ARG2.  IGNORE is true if the result of the function call is ignored.
10591    This function returns NULL_TREE if no simplification was possible.  */
10592
10593 static tree
10594 fold_builtin_3 (tree fndecl, tree arg0, tree arg1, tree arg2, bool ignore)
10595 {
10596   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10597   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10598   switch (fcode)
10599     {
10600
10601     CASE_FLT_FN (BUILT_IN_SINCOS):
10602       return fold_builtin_sincos (arg0, arg1, arg2);
10603
10604     CASE_FLT_FN (BUILT_IN_FMA):
10605       if (validate_arg (arg0, REAL_TYPE)
10606           && validate_arg(arg1, REAL_TYPE)
10607           && validate_arg(arg2, REAL_TYPE))
10608         return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10609     break;
10610
10611     CASE_FLT_FN (BUILT_IN_REMQUO):
10612       if (validate_arg (arg0, REAL_TYPE)
10613           && validate_arg(arg1, REAL_TYPE)
10614           && validate_arg(arg2, POINTER_TYPE))
10615         return do_mpfr_remquo (arg0, arg1, arg2);
10616     break;
10617
10618     case BUILT_IN_MEMSET:
10619       return fold_builtin_memset (arg0, arg1, arg2, type, ignore);
10620
10621     case BUILT_IN_BCOPY:
10622         return fold_builtin_memory_op (arg1, arg0, arg2, void_type_node, true, /*endp=*/3);
10623
10624     case BUILT_IN_MEMCPY:
10625       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/0);
10626
10627     case BUILT_IN_MEMPCPY:
10628       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/1);
10629
10630     case BUILT_IN_MEMMOVE:
10631       return fold_builtin_memory_op (arg0, arg1, arg2, type, ignore, /*endp=*/3);
10632
10633     case BUILT_IN_STRNCAT:
10634       return fold_builtin_strncat (arg0, arg1, arg2);
10635
10636     case BUILT_IN_STRNCPY:
10637       return fold_builtin_strncpy (fndecl, arg0, arg1, arg2, NULL_TREE);
10638
10639     case BUILT_IN_STRNCMP:
10640       return fold_builtin_strncmp (arg0, arg1, arg2);
10641
10642     case BUILT_IN_MEMCHR:
10643       return fold_builtin_memchr (arg0, arg1, arg2, type);
10644
10645     case BUILT_IN_BCMP:
10646     case BUILT_IN_MEMCMP:
10647       return fold_builtin_memcmp (arg0, arg1, arg2);;
10648
10649     case BUILT_IN_SPRINTF:
10650       return fold_builtin_sprintf (arg0, arg1, arg2, ignore);
10651
10652     case BUILT_IN_STRCPY_CHK:
10653     case BUILT_IN_STPCPY_CHK:
10654       return fold_builtin_stxcpy_chk (fndecl, arg0, arg1, arg2, NULL_TREE,
10655                                       ignore, fcode);
10656
10657     case BUILT_IN_STRCAT_CHK:
10658       return fold_builtin_strcat_chk (fndecl, arg0, arg1, arg2);
10659
10660     case BUILT_IN_PRINTF_CHK:
10661     case BUILT_IN_VPRINTF_CHK:
10662       if (!validate_arg (arg0, INTEGER_TYPE)
10663           || TREE_SIDE_EFFECTS (arg0))
10664         return NULL_TREE;
10665       else
10666         return fold_builtin_printf (fndecl, arg1, arg2, ignore, fcode);
10667     break;
10668
10669     case BUILT_IN_FPRINTF:
10670     case BUILT_IN_FPRINTF_UNLOCKED:
10671     case BUILT_IN_VFPRINTF:
10672       return fold_builtin_fprintf (fndecl, arg0, arg1, arg2, ignore, fcode);
10673
10674     case BUILT_IN_FPRINTF_CHK:
10675     case BUILT_IN_VFPRINTF_CHK:
10676       if (!validate_arg (arg1, INTEGER_TYPE)
10677           || TREE_SIDE_EFFECTS (arg1))
10678         return NULL_TREE;
10679       else
10680         return fold_builtin_fprintf (fndecl, arg0, arg2, NULL_TREE,
10681                                      ignore, fcode);
10682
10683     default:
10684       break;
10685     }
10686   return NULL_TREE;
10687 }
10688
10689 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10690    ARG2, and ARG3.  IGNORE is true if the result of the function call is
10691    ignored.  This function returns NULL_TREE if no simplification was
10692    possible.  */
10693  
10694 static tree
10695 fold_builtin_4 (tree fndecl, tree arg0, tree arg1, tree arg2, tree arg3,
10696                 bool ignore)
10697 {
10698   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10699
10700   switch (fcode)
10701     {
10702     case BUILT_IN_MEMCPY_CHK:
10703     case BUILT_IN_MEMPCPY_CHK:
10704     case BUILT_IN_MEMMOVE_CHK:
10705     case BUILT_IN_MEMSET_CHK:
10706       return fold_builtin_memory_chk (fndecl, arg0, arg1, arg2, arg3,
10707                                       NULL_TREE, ignore,
10708                                       DECL_FUNCTION_CODE (fndecl));
10709
10710     case BUILT_IN_STRNCPY_CHK:
10711       return fold_builtin_strncpy_chk (arg0, arg1, arg2, arg3, NULL_TREE);
10712
10713     case BUILT_IN_STRNCAT_CHK:
10714       return fold_builtin_strncat_chk (fndecl, arg0, arg1, arg2, arg3);
10715
10716     case BUILT_IN_FPRINTF_CHK:
10717     case BUILT_IN_VFPRINTF_CHK:
10718       if (!validate_arg (arg1, INTEGER_TYPE)
10719           || TREE_SIDE_EFFECTS (arg1))
10720         return NULL_TREE;
10721       else
10722         return fold_builtin_fprintf (fndecl, arg0, arg2, arg3,
10723                                      ignore, fcode);
10724     break;
10725
10726     default:
10727       break;
10728     }
10729   return NULL_TREE;
10730 }
10731
10732 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
10733     arguments, where NARGS <= 4.  IGNORE is true if the result of the
10734     function call is ignored.  This function returns NULL_TREE if no
10735     simplification was possible.  Note that this only folds builtins with
10736     fixed argument patterns.  Foldings that do varargs-to-varargs
10737     transformations, or that match calls with more than 4 arguments,
10738     need to be handled with fold_builtin_varargs instead.  */
10739  
10740 #define MAX_ARGS_TO_FOLD_BUILTIN 4
10741  
10742 static tree
10743 fold_builtin_n (tree fndecl, tree *args, int nargs, bool ignore)
10744 {
10745   tree ret = NULL_TREE;
10746
10747   switch (nargs)
10748     {
10749     case 0:
10750       ret = fold_builtin_0 (fndecl, ignore);
10751       break;
10752     case 1:
10753       ret = fold_builtin_1 (fndecl, args[0], ignore);
10754       break;
10755     case 2:
10756       ret = fold_builtin_2 (fndecl, args[0], args[1], ignore);
10757       break;
10758     case 3:
10759       ret = fold_builtin_3 (fndecl, args[0], args[1], args[2], ignore);
10760       break;
10761     case 4:
10762       ret = fold_builtin_4 (fndecl, args[0], args[1], args[2], args[3],
10763                             ignore);
10764       break;
10765     default:
10766       break;
10767     }
10768   if (ret)
10769     {
10770       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10771       TREE_NO_WARNING (ret) = 1;
10772       return ret;
10773     }
10774   return NULL_TREE;
10775 }
10776
10777 /* Builtins with folding operations that operate on "..." arguments
10778    need special handling; we need to store the arguments in a convenient
10779    data structure before attempting any folding.  Fortunately there are
10780    only a few builtins that fall into this category.  FNDECL is the
10781    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10782    result of the function call is ignored.  */
10783
10784 static tree
10785 fold_builtin_varargs (tree fndecl, tree exp, bool ignore ATTRIBUTE_UNUSED)
10786 {
10787   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10788   tree ret = NULL_TREE;
10789
10790   switch (fcode)
10791     {
10792     case BUILT_IN_SPRINTF_CHK:
10793     case BUILT_IN_VSPRINTF_CHK:
10794       ret = fold_builtin_sprintf_chk (exp, fcode);
10795       break;
10796
10797     case BUILT_IN_SNPRINTF_CHK:
10798     case BUILT_IN_VSNPRINTF_CHK:
10799       ret = fold_builtin_snprintf_chk (exp, NULL_TREE, fcode);
10800       break;
10801
10802     case BUILT_IN_FPCLASSIFY:
10803       ret = fold_builtin_fpclassify (exp);
10804       break;
10805
10806     default:
10807       break;
10808     }
10809   if (ret)
10810     {
10811       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10812       TREE_NO_WARNING (ret) = 1;
10813       return ret;
10814     }
10815   return NULL_TREE;
10816 }
10817
10818 /* Return true if FNDECL shouldn't be folded right now.
10819    If a built-in function has an inline attribute always_inline
10820    wrapper, defer folding it after always_inline functions have
10821    been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
10822    might not be performed.  */
10823
10824 static bool
10825 avoid_folding_inline_builtin (tree fndecl)
10826 {
10827   return (DECL_DECLARED_INLINE_P (fndecl)
10828           && DECL_DISREGARD_INLINE_LIMITS (fndecl)
10829           && cfun
10830           && !cfun->always_inline_functions_inlined
10831           && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
10832 }
10833
10834 /* A wrapper function for builtin folding that prevents warnings for
10835    "statement without effect" and the like, caused by removing the
10836    call node earlier than the warning is generated.  */
10837
10838 tree
10839 fold_call_expr (tree exp, bool ignore)
10840 {
10841   tree ret = NULL_TREE;
10842   tree fndecl = get_callee_fndecl (exp);
10843   if (fndecl
10844       && TREE_CODE (fndecl) == FUNCTION_DECL
10845       && DECL_BUILT_IN (fndecl)
10846       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10847          yet.  Defer folding until we see all the arguments
10848          (after inlining).  */
10849       && !CALL_EXPR_VA_ARG_PACK (exp))
10850     {
10851       int nargs = call_expr_nargs (exp);
10852
10853       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10854          instead last argument is __builtin_va_arg_pack ().  Defer folding
10855          even in that case, until arguments are finalized.  */
10856       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10857         {
10858           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10859           if (fndecl2
10860               && TREE_CODE (fndecl2) == FUNCTION_DECL
10861               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10862               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10863             return NULL_TREE;
10864         }
10865
10866       if (avoid_folding_inline_builtin (fndecl))
10867         return NULL_TREE;
10868
10869       /* FIXME: Don't use a list in this interface.  */
10870       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10871           return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10872       else
10873         {
10874           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10875             {
10876               tree *args = CALL_EXPR_ARGP (exp);
10877               ret = fold_builtin_n (fndecl, args, nargs, ignore);
10878             }
10879           if (!ret)
10880             ret = fold_builtin_varargs (fndecl, exp, ignore);
10881           if (ret)
10882             {
10883               /* Propagate location information from original call to
10884                  expansion of builtin.  Otherwise things like
10885                  maybe_emit_chk_warning, that operate on the expansion
10886                  of a builtin, will use the wrong location information.  */
10887               if (CAN_HAVE_LOCATION_P (exp) && EXPR_HAS_LOCATION (exp))
10888                 {
10889                   tree realret = ret;
10890                   if (TREE_CODE (ret) == NOP_EXPR)
10891                     realret = TREE_OPERAND (ret, 0);
10892                   if (CAN_HAVE_LOCATION_P (realret)
10893                       && !EXPR_HAS_LOCATION (realret))
10894                     SET_EXPR_LOCATION (realret, EXPR_LOCATION (exp));
10895                   return realret;
10896                 }
10897               return ret;
10898             }
10899         }
10900     }
10901   return NULL_TREE;
10902 }
10903  
10904 /* Conveniently construct a function call expression.  FNDECL names the
10905     function to be called and ARGLIST is a TREE_LIST of arguments.  */
10906  
10907 tree
10908 build_function_call_expr (tree fndecl, tree arglist)
10909 {
10910   tree fntype = TREE_TYPE (fndecl);
10911   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10912   int n = list_length (arglist);
10913   tree *argarray = (tree *) alloca (n * sizeof (tree));
10914   int i;
10915   
10916   for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10917     argarray[i] = TREE_VALUE (arglist);
10918   return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10919 }
10920
10921 /* Conveniently construct a function call expression.  FNDECL names the
10922    function to be called, N is the number of arguments, and the "..."
10923    parameters are the argument expressions.  */
10924  
10925 tree
10926 build_call_expr (tree fndecl, int n, ...)
10927 {
10928   va_list ap;
10929   tree fntype = TREE_TYPE (fndecl);
10930   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10931   tree *argarray = (tree *) alloca (n * sizeof (tree));
10932   int i;
10933
10934   va_start (ap, n);
10935   for (i = 0; i < n; i++)
10936     argarray[i] = va_arg (ap, tree);
10937   va_end (ap);
10938   return fold_builtin_call_array (TREE_TYPE (fntype), fn, n, argarray);
10939 }
10940
10941 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
10942    N arguments are passed in the array ARGARRAY.  */
10943
10944 tree
10945 fold_builtin_call_array (tree type,
10946                          tree fn,
10947                          int n,
10948                          tree *argarray)
10949 {
10950   tree ret = NULL_TREE;
10951   int i;
10952    tree exp;
10953
10954   if (TREE_CODE (fn) == ADDR_EXPR)
10955   {
10956     tree fndecl = TREE_OPERAND (fn, 0);
10957     if (TREE_CODE (fndecl) == FUNCTION_DECL
10958         && DECL_BUILT_IN (fndecl))
10959       {
10960         /* If last argument is __builtin_va_arg_pack (), arguments to this
10961            function are not finalized yet.  Defer folding until they are.  */
10962         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10963           {
10964             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10965             if (fndecl2
10966                 && TREE_CODE (fndecl2) == FUNCTION_DECL
10967                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10968                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10969               return build_call_array (type, fn, n, argarray);
10970           }
10971         if (avoid_folding_inline_builtin (fndecl))
10972           return build_call_array (type, fn, n, argarray);
10973         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10974           {
10975             tree arglist = NULL_TREE;
10976             for (i = n - 1; i >= 0; i--)
10977               arglist = tree_cons (NULL_TREE, argarray[i], arglist);
10978             ret = targetm.fold_builtin (fndecl, arglist, false);
10979             if (ret)
10980               return ret;
10981             return build_call_array (type, fn, n, argarray);
10982           }
10983         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10984           {
10985             /* First try the transformations that don't require consing up
10986                an exp.  */
10987             ret = fold_builtin_n (fndecl, argarray, n, false);
10988             if (ret)
10989               return ret;
10990           }
10991
10992         /* If we got this far, we need to build an exp.  */
10993         exp = build_call_array (type, fn, n, argarray);
10994         ret = fold_builtin_varargs (fndecl, exp, false);
10995         return ret ? ret : exp;
10996       }
10997   }
10998
10999   return build_call_array (type, fn, n, argarray);
11000 }
11001
11002 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
11003    along with N new arguments specified as the "..." parameters.  SKIP
11004    is the number of arguments in EXP to be omitted.  This function is used
11005    to do varargs-to-varargs transformations.  */
11006
11007 static tree
11008 rewrite_call_expr (tree exp, int skip, tree fndecl, int n, ...)
11009 {
11010   int oldnargs = call_expr_nargs (exp);
11011   int nargs = oldnargs - skip + n;
11012   tree fntype = TREE_TYPE (fndecl);
11013   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
11014   tree *buffer;
11015
11016   if (n > 0)
11017     {
11018       int i, j;
11019       va_list ap;
11020
11021       buffer = XALLOCAVEC (tree, nargs);
11022       va_start (ap, n);
11023       for (i = 0; i < n; i++)
11024         buffer[i] = va_arg (ap, tree);
11025       va_end (ap);
11026       for (j = skip; j < oldnargs; j++, i++)
11027         buffer[i] = CALL_EXPR_ARG (exp, j);
11028     }
11029   else 
11030     buffer = CALL_EXPR_ARGP (exp) + skip;
11031
11032   return fold (build_call_array (TREE_TYPE (exp), fn, nargs, buffer));
11033 }
11034
11035 /* Validate a single argument ARG against a tree code CODE representing
11036    a type.  */
11037   
11038 static bool
11039 validate_arg (const_tree arg, enum tree_code code)
11040 {
11041   if (!arg)
11042     return false;
11043   else if (code == POINTER_TYPE)
11044     return POINTER_TYPE_P (TREE_TYPE (arg));
11045   else if (code == INTEGER_TYPE)
11046     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11047   return code == TREE_CODE (TREE_TYPE (arg));
11048 }
11049
11050 /* This function validates the types of a function call argument list
11051    against a specified list of tree_codes.  If the last specifier is a 0,
11052    that represents an ellipses, otherwise the last specifier must be a
11053    VOID_TYPE.
11054
11055    This is the GIMPLE version of validate_arglist.  Eventually we want to
11056    completely convert builtins.c to work from GIMPLEs and the tree based
11057    validate_arglist will then be removed.  */
11058
11059 bool
11060 validate_gimple_arglist (const_gimple call, ...)
11061 {
11062   enum tree_code code;
11063   bool res = 0;
11064   va_list ap;
11065   const_tree arg;
11066   size_t i;
11067
11068   va_start (ap, call);
11069   i = 0;
11070
11071   do
11072     {
11073       code = va_arg (ap, enum tree_code);
11074       switch (code)
11075         {
11076         case 0:
11077           /* This signifies an ellipses, any further arguments are all ok.  */
11078           res = true;
11079           goto end;
11080         case VOID_TYPE:
11081           /* This signifies an endlink, if no arguments remain, return
11082              true, otherwise return false.  */
11083           res = (i == gimple_call_num_args (call));
11084           goto end;
11085         default:
11086           /* If no parameters remain or the parameter's code does not
11087              match the specified code, return false.  Otherwise continue
11088              checking any remaining arguments.  */
11089           arg = gimple_call_arg (call, i++);
11090           if (!validate_arg (arg, code))
11091             goto end;
11092           break;
11093         }
11094     }
11095   while (1);
11096
11097   /* We need gotos here since we can only have one VA_CLOSE in a
11098      function.  */
11099  end: ;
11100   va_end (ap);
11101
11102   return res;
11103 }
11104
11105 /* This function validates the types of a function call argument list
11106    against a specified list of tree_codes.  If the last specifier is a 0,
11107    that represents an ellipses, otherwise the last specifier must be a
11108    VOID_TYPE.  */
11109
11110 bool
11111 validate_arglist (const_tree callexpr, ...)
11112 {
11113   enum tree_code code;
11114   bool res = 0;
11115   va_list ap;
11116   const_call_expr_arg_iterator iter;
11117   const_tree arg;
11118
11119   va_start (ap, callexpr);
11120   init_const_call_expr_arg_iterator (callexpr, &iter);
11121
11122   do
11123     {
11124       code = va_arg (ap, enum tree_code);
11125       switch (code)
11126         {
11127         case 0:
11128           /* This signifies an ellipses, any further arguments are all ok.  */
11129           res = true;
11130           goto end;
11131         case VOID_TYPE:
11132           /* This signifies an endlink, if no arguments remain, return
11133              true, otherwise return false.  */
11134           res = !more_const_call_expr_args_p (&iter);
11135           goto end;
11136         default:
11137           /* If no parameters remain or the parameter's code does not
11138              match the specified code, return false.  Otherwise continue
11139              checking any remaining arguments.  */
11140           arg = next_const_call_expr_arg (&iter);
11141           if (!validate_arg (arg, code))
11142             goto end;
11143           break;
11144         }
11145     }
11146   while (1);
11147
11148   /* We need gotos here since we can only have one VA_CLOSE in a
11149      function.  */
11150  end: ;
11151   va_end (ap);
11152
11153   return res;
11154 }
11155
11156 /* Default target-specific builtin expander that does nothing.  */
11157
11158 rtx
11159 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11160                         rtx target ATTRIBUTE_UNUSED,
11161                         rtx subtarget ATTRIBUTE_UNUSED,
11162                         enum machine_mode mode ATTRIBUTE_UNUSED,
11163                         int ignore ATTRIBUTE_UNUSED)
11164 {
11165   return NULL_RTX;
11166 }
11167
11168 /* Returns true is EXP represents data that would potentially reside
11169    in a readonly section.  */
11170
11171 static bool
11172 readonly_data_expr (tree exp)
11173 {
11174   STRIP_NOPS (exp);
11175
11176   if (TREE_CODE (exp) != ADDR_EXPR)
11177     return false;
11178
11179   exp = get_base_address (TREE_OPERAND (exp, 0));
11180   if (!exp)
11181     return false;
11182
11183   /* Make sure we call decl_readonly_section only for trees it
11184      can handle (since it returns true for everything it doesn't
11185      understand).  */
11186   if (TREE_CODE (exp) == STRING_CST
11187       || TREE_CODE (exp) == CONSTRUCTOR
11188       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11189     return decl_readonly_section (exp, 0);
11190   else
11191     return false;
11192 }
11193
11194 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11195    to the call, and TYPE is its return type.
11196
11197    Return NULL_TREE if no simplification was possible, otherwise return the
11198    simplified form of the call as a tree.
11199
11200    The simplified form may be a constant or other expression which
11201    computes the same value, but in a more efficient manner (including
11202    calls to other builtin functions).
11203
11204    The call may contain arguments which need to be evaluated, but
11205    which are not useful to determine the result of the call.  In
11206    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11207    COMPOUND_EXPR will be an argument which must be evaluated.
11208    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11209    COMPOUND_EXPR in the chain will contain the tree for the simplified
11210    form of the builtin function call.  */
11211
11212 static tree
11213 fold_builtin_strstr (tree s1, tree s2, tree type)
11214 {
11215   if (!validate_arg (s1, POINTER_TYPE)
11216       || !validate_arg (s2, POINTER_TYPE))
11217     return NULL_TREE;
11218   else
11219     {
11220       tree fn;
11221       const char *p1, *p2;
11222
11223       p2 = c_getstr (s2);
11224       if (p2 == NULL)
11225         return NULL_TREE;
11226
11227       p1 = c_getstr (s1);
11228       if (p1 != NULL)
11229         {
11230           const char *r = strstr (p1, p2);
11231           tree tem;
11232
11233           if (r == NULL)
11234             return build_int_cst (TREE_TYPE (s1), 0);
11235
11236           /* Return an offset into the constant string argument.  */
11237           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11238                              s1, size_int (r - p1));
11239           return fold_convert (type, tem);
11240         }
11241
11242       /* The argument is const char *, and the result is char *, so we need
11243          a type conversion here to avoid a warning.  */
11244       if (p2[0] == '\0')
11245         return fold_convert (type, s1);
11246
11247       if (p2[1] != '\0')
11248         return NULL_TREE;
11249
11250       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11251       if (!fn)
11252         return NULL_TREE;
11253
11254       /* New argument list transforming strstr(s1, s2) to
11255          strchr(s1, s2[0]).  */
11256       return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11257     }
11258 }
11259
11260 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11261    the call, and TYPE is its return type.
11262
11263    Return NULL_TREE if no simplification was possible, otherwise return the
11264    simplified form of the call as a tree.
11265
11266    The simplified form may be a constant or other expression which
11267    computes the same value, but in a more efficient manner (including
11268    calls to other builtin functions).
11269
11270    The call may contain arguments which need to be evaluated, but
11271    which are not useful to determine the result of the call.  In
11272    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11273    COMPOUND_EXPR will be an argument which must be evaluated.
11274    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11275    COMPOUND_EXPR in the chain will contain the tree for the simplified
11276    form of the builtin function call.  */
11277
11278 static tree
11279 fold_builtin_strchr (tree s1, tree s2, tree type)
11280 {
11281   if (!validate_arg (s1, POINTER_TYPE)
11282       || !validate_arg (s2, INTEGER_TYPE))
11283     return NULL_TREE;
11284   else
11285     {
11286       const char *p1;
11287
11288       if (TREE_CODE (s2) != INTEGER_CST)
11289         return NULL_TREE;
11290
11291       p1 = c_getstr (s1);
11292       if (p1 != NULL)
11293         {
11294           char c;
11295           const char *r;
11296           tree tem;
11297
11298           if (target_char_cast (s2, &c))
11299             return NULL_TREE;
11300
11301           r = strchr (p1, c);
11302
11303           if (r == NULL)
11304             return build_int_cst (TREE_TYPE (s1), 0);
11305
11306           /* Return an offset into the constant string argument.  */
11307           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11308                              s1, size_int (r - p1));
11309           return fold_convert (type, tem);
11310         }
11311       return NULL_TREE;
11312     }
11313 }
11314
11315 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11316    the call, and TYPE is its return type.
11317
11318    Return NULL_TREE if no simplification was possible, otherwise return the
11319    simplified form of the call as a tree.
11320
11321    The simplified form may be a constant or other expression which
11322    computes the same value, but in a more efficient manner (including
11323    calls to other builtin functions).
11324
11325    The call may contain arguments which need to be evaluated, but
11326    which are not useful to determine the result of the call.  In
11327    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11328    COMPOUND_EXPR will be an argument which must be evaluated.
11329    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11330    COMPOUND_EXPR in the chain will contain the tree for the simplified
11331    form of the builtin function call.  */
11332
11333 static tree
11334 fold_builtin_strrchr (tree s1, tree s2, tree type)
11335 {
11336   if (!validate_arg (s1, POINTER_TYPE)
11337       || !validate_arg (s2, INTEGER_TYPE))
11338     return NULL_TREE;
11339   else
11340     {
11341       tree fn;
11342       const char *p1;
11343
11344       if (TREE_CODE (s2) != INTEGER_CST)
11345         return NULL_TREE;
11346
11347       p1 = c_getstr (s1);
11348       if (p1 != NULL)
11349         {
11350           char c;
11351           const char *r;
11352           tree tem;
11353
11354           if (target_char_cast (s2, &c))
11355             return NULL_TREE;
11356
11357           r = strrchr (p1, c);
11358
11359           if (r == NULL)
11360             return build_int_cst (TREE_TYPE (s1), 0);
11361
11362           /* Return an offset into the constant string argument.  */
11363           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11364                              s1, size_int (r - p1));
11365           return fold_convert (type, tem);
11366         }
11367
11368       if (! integer_zerop (s2))
11369         return NULL_TREE;
11370
11371       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11372       if (!fn)
11373         return NULL_TREE;
11374
11375       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11376       return build_call_expr (fn, 2, s1, s2);
11377     }
11378 }
11379
11380 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11381    to the call, and TYPE is its return type.
11382
11383    Return NULL_TREE if no simplification was possible, otherwise return the
11384    simplified form of the call as a tree.
11385
11386    The simplified form may be a constant or other expression which
11387    computes the same value, but in a more efficient manner (including
11388    calls to other builtin functions).
11389
11390    The call may contain arguments which need to be evaluated, but
11391    which are not useful to determine the result of the call.  In
11392    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11393    COMPOUND_EXPR will be an argument which must be evaluated.
11394    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11395    COMPOUND_EXPR in the chain will contain the tree for the simplified
11396    form of the builtin function call.  */
11397
11398 static tree
11399 fold_builtin_strpbrk (tree s1, tree s2, tree type)
11400 {
11401   if (!validate_arg (s1, POINTER_TYPE)
11402       || !validate_arg (s2, POINTER_TYPE))
11403     return NULL_TREE;
11404   else
11405     {
11406       tree fn;
11407       const char *p1, *p2;
11408
11409       p2 = c_getstr (s2);
11410       if (p2 == NULL)
11411         return NULL_TREE;
11412
11413       p1 = c_getstr (s1);
11414       if (p1 != NULL)
11415         {
11416           const char *r = strpbrk (p1, p2);
11417           tree tem;
11418
11419           if (r == NULL)
11420             return build_int_cst (TREE_TYPE (s1), 0);
11421
11422           /* Return an offset into the constant string argument.  */
11423           tem = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (s1),
11424                              s1, size_int (r - p1));
11425           return fold_convert (type, tem);
11426         }
11427
11428       if (p2[0] == '\0')
11429         /* strpbrk(x, "") == NULL.
11430            Evaluate and ignore s1 in case it had side-effects.  */
11431         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
11432
11433       if (p2[1] != '\0')
11434         return NULL_TREE;  /* Really call strpbrk.  */
11435
11436       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11437       if (!fn)
11438         return NULL_TREE;
11439
11440       /* New argument list transforming strpbrk(s1, s2) to
11441          strchr(s1, s2[0]).  */
11442       return build_call_expr (fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11443     }
11444 }
11445
11446 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11447    to the call.
11448
11449    Return NULL_TREE if no simplification was possible, otherwise return the
11450    simplified form of the call as a tree.
11451
11452    The simplified form may be a constant or other expression which
11453    computes the same value, but in a more efficient manner (including
11454    calls to other builtin functions).
11455
11456    The call may contain arguments which need to be evaluated, but
11457    which are not useful to determine the result of the call.  In
11458    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11459    COMPOUND_EXPR will be an argument which must be evaluated.
11460    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11461    COMPOUND_EXPR in the chain will contain the tree for the simplified
11462    form of the builtin function call.  */
11463
11464 static tree
11465 fold_builtin_strcat (tree dst, tree src)
11466 {
11467   if (!validate_arg (dst, POINTER_TYPE)
11468       || !validate_arg (src, POINTER_TYPE))
11469     return NULL_TREE;
11470   else
11471     {
11472       const char *p = c_getstr (src);
11473
11474       /* If the string length is zero, return the dst parameter.  */
11475       if (p && *p == '\0')
11476         return dst;
11477
11478       return NULL_TREE;
11479     }
11480 }
11481
11482 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11483    arguments to the call.
11484
11485    Return NULL_TREE if no simplification was possible, otherwise return the
11486    simplified form of the call as a tree.
11487
11488    The simplified form may be a constant or other expression which
11489    computes the same value, but in a more efficient manner (including
11490    calls to other builtin functions).
11491
11492    The call may contain arguments which need to be evaluated, but
11493    which are not useful to determine the result of the call.  In
11494    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11495    COMPOUND_EXPR will be an argument which must be evaluated.
11496    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11497    COMPOUND_EXPR in the chain will contain the tree for the simplified
11498    form of the builtin function call.  */
11499
11500 static tree
11501 fold_builtin_strncat (tree dst, tree src, tree len)
11502 {
11503   if (!validate_arg (dst, POINTER_TYPE)
11504       || !validate_arg (src, POINTER_TYPE)
11505       || !validate_arg (len, INTEGER_TYPE))
11506     return NULL_TREE;
11507   else
11508     {
11509       const char *p = c_getstr (src);
11510
11511       /* If the requested length is zero, or the src parameter string
11512          length is zero, return the dst parameter.  */
11513       if (integer_zerop (len) || (p && *p == '\0'))
11514         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
11515
11516       /* If the requested len is greater than or equal to the string
11517          length, call strcat.  */
11518       if (TREE_CODE (len) == INTEGER_CST && p
11519           && compare_tree_int (len, strlen (p)) >= 0)
11520         {
11521           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11522
11523           /* If the replacement _DECL isn't initialized, don't do the
11524              transformation.  */
11525           if (!fn)
11526             return NULL_TREE;
11527
11528           return build_call_expr (fn, 2, dst, src);
11529         }
11530       return NULL_TREE;
11531     }
11532 }
11533
11534 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11535    to the call.
11536
11537    Return NULL_TREE if no simplification was possible, otherwise return the
11538    simplified form of the call as a tree.
11539
11540    The simplified form may be a constant or other expression which
11541    computes the same value, but in a more efficient manner (including
11542    calls to other builtin functions).
11543
11544    The call may contain arguments which need to be evaluated, but
11545    which are not useful to determine the result of the call.  In
11546    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11547    COMPOUND_EXPR will be an argument which must be evaluated.
11548    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11549    COMPOUND_EXPR in the chain will contain the tree for the simplified
11550    form of the builtin function call.  */
11551
11552 static tree
11553 fold_builtin_strspn (tree s1, tree s2)
11554 {
11555   if (!validate_arg (s1, POINTER_TYPE)
11556       || !validate_arg (s2, POINTER_TYPE))
11557     return NULL_TREE;
11558   else
11559     {
11560       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11561
11562       /* If both arguments are constants, evaluate at compile-time.  */
11563       if (p1 && p2)
11564         {
11565           const size_t r = strspn (p1, p2);
11566           return size_int (r);
11567         }
11568
11569       /* If either argument is "", return NULL_TREE.  */
11570       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11571         /* Evaluate and ignore both arguments in case either one has
11572            side-effects.  */
11573         return omit_two_operands (size_type_node, size_zero_node,
11574                                   s1, s2);
11575       return NULL_TREE;
11576     }
11577 }
11578
11579 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11580    to the call.
11581
11582    Return NULL_TREE if no simplification was possible, otherwise return the
11583    simplified form of the call as a tree.
11584
11585    The simplified form may be a constant or other expression which
11586    computes the same value, but in a more efficient manner (including
11587    calls to other builtin functions).
11588
11589    The call may contain arguments which need to be evaluated, but
11590    which are not useful to determine the result of the call.  In
11591    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11592    COMPOUND_EXPR will be an argument which must be evaluated.
11593    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11594    COMPOUND_EXPR in the chain will contain the tree for the simplified
11595    form of the builtin function call.  */
11596
11597 static tree
11598 fold_builtin_strcspn (tree s1, tree s2)
11599 {
11600   if (!validate_arg (s1, POINTER_TYPE)
11601       || !validate_arg (s2, POINTER_TYPE))
11602     return NULL_TREE;
11603   else
11604     {
11605       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11606
11607       /* If both arguments are constants, evaluate at compile-time.  */
11608       if (p1 && p2)
11609         {
11610           const size_t r = strcspn (p1, p2);
11611           return size_int (r);
11612         }
11613
11614       /* If the first argument is "", return NULL_TREE.  */
11615       if (p1 && *p1 == '\0')
11616         {
11617           /* Evaluate and ignore argument s2 in case it has
11618              side-effects.  */
11619           return omit_one_operand (size_type_node,
11620                                    size_zero_node, s2);
11621         }
11622
11623       /* If the second argument is "", return __builtin_strlen(s1).  */
11624       if (p2 && *p2 == '\0')
11625         {
11626           tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11627
11628           /* If the replacement _DECL isn't initialized, don't do the
11629              transformation.  */
11630           if (!fn)
11631             return NULL_TREE;
11632
11633           return build_call_expr (fn, 1, s1);
11634         }
11635       return NULL_TREE;
11636     }
11637 }
11638
11639 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
11640    to the call.  IGNORE is true if the value returned
11641    by the builtin will be ignored.  UNLOCKED is true is true if this
11642    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
11643    the known length of the string.  Return NULL_TREE if no simplification
11644    was possible.  */
11645
11646 tree
11647 fold_builtin_fputs (tree arg0, tree arg1, bool ignore, bool unlocked, tree len)
11648 {
11649   /* If we're using an unlocked function, assume the other unlocked
11650      functions exist explicitly.  */
11651   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
11652     : implicit_built_in_decls[BUILT_IN_FPUTC];
11653   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
11654     : implicit_built_in_decls[BUILT_IN_FWRITE];
11655
11656   /* If the return value is used, don't do the transformation.  */
11657   if (!ignore)
11658     return NULL_TREE;
11659
11660   /* Verify the arguments in the original call.  */
11661   if (!validate_arg (arg0, POINTER_TYPE)
11662       || !validate_arg (arg1, POINTER_TYPE))
11663     return NULL_TREE;
11664
11665   if (! len)
11666     len = c_strlen (arg0, 0);
11667
11668   /* Get the length of the string passed to fputs.  If the length
11669      can't be determined, punt.  */
11670   if (!len
11671       || TREE_CODE (len) != INTEGER_CST)
11672     return NULL_TREE;
11673
11674   switch (compare_tree_int (len, 1))
11675     {
11676     case -1: /* length is 0, delete the call entirely .  */
11677       return omit_one_operand (integer_type_node, integer_zero_node, arg1);;
11678
11679     case 0: /* length is 1, call fputc.  */
11680       {
11681         const char *p = c_getstr (arg0);
11682
11683         if (p != NULL)
11684           {
11685             if (fn_fputc)
11686               return build_call_expr (fn_fputc, 2,
11687                                       build_int_cst (NULL_TREE, p[0]), arg1);
11688             else
11689               return NULL_TREE;
11690           }
11691       }
11692       /* FALLTHROUGH */
11693     case 1: /* length is greater than 1, call fwrite.  */
11694       {
11695         /* If optimizing for size keep fputs.  */
11696         if (optimize_function_for_size_p (cfun))
11697           return NULL_TREE;
11698         /* New argument list transforming fputs(string, stream) to
11699            fwrite(string, 1, len, stream).  */
11700         if (fn_fwrite)
11701           return build_call_expr (fn_fwrite, 4, arg0, size_one_node, len, arg1);
11702         else
11703           return NULL_TREE;
11704       }
11705     default:
11706       gcc_unreachable ();
11707     }
11708   return NULL_TREE;
11709 }
11710
11711 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
11712    produced.  False otherwise.  This is done so that we don't output the error
11713    or warning twice or three times.  */
11714
11715 bool
11716 fold_builtin_next_arg (tree exp, bool va_start_p)
11717 {
11718   tree fntype = TREE_TYPE (current_function_decl);
11719   int nargs = call_expr_nargs (exp);
11720   tree arg;
11721
11722   if (TYPE_ARG_TYPES (fntype) == 0
11723       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11724           == void_type_node))
11725     {
11726       error ("%<va_start%> used in function with fixed args");
11727       return true;
11728     }
11729
11730   if (va_start_p)
11731     {
11732       if (va_start_p && (nargs != 2))
11733         {
11734           error ("wrong number of arguments to function %<va_start%>");
11735           return true;
11736         }
11737       arg = CALL_EXPR_ARG (exp, 1);
11738     }
11739   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11740      when we checked the arguments and if needed issued a warning.  */
11741   else
11742     {
11743       if (nargs == 0)
11744         {
11745           /* Evidently an out of date version of <stdarg.h>; can't validate
11746              va_start's second argument, but can still work as intended.  */
11747           warning (0, "%<__builtin_next_arg%> called without an argument");
11748           return true;
11749         }
11750       else if (nargs > 1)
11751         {
11752           error ("wrong number of arguments to function %<__builtin_next_arg%>");
11753           return true;
11754         }
11755       arg = CALL_EXPR_ARG (exp, 0);
11756     }
11757
11758   /* We destructively modify the call to be __builtin_va_start (ap, 0)
11759      or __builtin_next_arg (0) the first time we see it, after checking 
11760      the arguments and if needed issuing a warning.  */
11761   if (!integer_zerop (arg))
11762     {
11763       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
11764
11765       /* Strip off all nops for the sake of the comparison.  This
11766          is not quite the same as STRIP_NOPS.  It does more.
11767          We must also strip off INDIRECT_EXPR for C++ reference
11768          parameters.  */
11769       while (CONVERT_EXPR_P (arg)
11770              || TREE_CODE (arg) == INDIRECT_REF)
11771         arg = TREE_OPERAND (arg, 0);
11772       if (arg != last_parm)
11773         {
11774           /* FIXME: Sometimes with the tree optimizers we can get the
11775              not the last argument even though the user used the last
11776              argument.  We just warn and set the arg to be the last
11777              argument so that we will get wrong-code because of
11778              it.  */
11779           warning (0, "second parameter of %<va_start%> not last named argument");
11780         }
11781
11782       /* Undefined by C99 7.15.1.4p4 (va_start):
11783          "If the parameter parmN is declared with the register storage
11784          class, with a function or array type, or with a type that is
11785          not compatible with the type that results after application of
11786          the default argument promotions, the behavior is undefined."
11787       */
11788       else if (DECL_REGISTER (arg))
11789         warning (0, "undefined behaviour when second parameter of "
11790                  "%<va_start%> is declared with %<register%> storage");
11791
11792       /* We want to verify the second parameter just once before the tree
11793          optimizers are run and then avoid keeping it in the tree,
11794          as otherwise we could warn even for correct code like:
11795          void foo (int i, ...)
11796          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
11797       if (va_start_p)
11798         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11799       else
11800         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
11801     }
11802   return false;
11803 }
11804
11805
11806 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11807    ORIG may be null if this is a 2-argument call.  We don't attempt to
11808    simplify calls with more than 3 arguments.
11809
11810    Return NULL_TREE if no simplification was possible, otherwise return the
11811    simplified form of the call as a tree.  If IGNORED is true, it means that
11812    the caller does not use the returned value of the function.  */
11813
11814 static tree
11815 fold_builtin_sprintf (tree dest, tree fmt, tree orig, int ignored)
11816 {
11817   tree call, retval;
11818   const char *fmt_str = NULL;
11819
11820   /* Verify the required arguments in the original call.  We deal with two
11821      types of sprintf() calls: 'sprintf (str, fmt)' and
11822      'sprintf (dest, "%s", orig)'.  */
11823   if (!validate_arg (dest, POINTER_TYPE)
11824       || !validate_arg (fmt, POINTER_TYPE))
11825     return NULL_TREE;
11826   if (orig && !validate_arg (orig, POINTER_TYPE))
11827     return NULL_TREE;
11828
11829   /* Check whether the format is a literal string constant.  */
11830   fmt_str = c_getstr (fmt);
11831   if (fmt_str == NULL)
11832     return NULL_TREE;
11833
11834   call = NULL_TREE;
11835   retval = NULL_TREE;
11836
11837   if (!init_target_chars ())
11838     return NULL_TREE;
11839
11840   /* If the format doesn't contain % args or %%, use strcpy.  */
11841   if (strchr (fmt_str, target_percent) == NULL)
11842     {
11843       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11844
11845       if (!fn)
11846         return NULL_TREE;
11847
11848       /* Don't optimize sprintf (buf, "abc", ptr++).  */
11849       if (orig)
11850         return NULL_TREE;
11851
11852       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11853          'format' is known to contain no % formats.  */
11854       call = build_call_expr (fn, 2, dest, fmt);
11855       if (!ignored)
11856         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
11857     }
11858
11859   /* If the format is "%s", use strcpy if the result isn't used.  */
11860   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
11861     {
11862       tree fn;
11863       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11864
11865       if (!fn)
11866         return NULL_TREE;
11867
11868       /* Don't crash on sprintf (str1, "%s").  */
11869       if (!orig)
11870         return NULL_TREE;
11871
11872       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
11873       if (!ignored)
11874         {
11875           retval = c_strlen (orig, 1);
11876           if (!retval || TREE_CODE (retval) != INTEGER_CST)
11877             return NULL_TREE;
11878         }
11879       call = build_call_expr (fn, 2, dest, orig);
11880     }
11881
11882   if (call && retval)
11883     {
11884       retval = fold_convert
11885         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
11886          retval);
11887       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
11888     }
11889   else
11890     return call;
11891 }
11892
11893 /* Expand a call EXP to __builtin_object_size.  */
11894
11895 rtx
11896 expand_builtin_object_size (tree exp)
11897 {
11898   tree ost;
11899   int object_size_type;
11900   tree fndecl = get_callee_fndecl (exp);
11901
11902   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
11903     {
11904       error ("%Kfirst argument of %D must be a pointer, second integer constant",
11905              exp, fndecl);
11906       expand_builtin_trap ();
11907       return const0_rtx;
11908     }
11909
11910   ost = CALL_EXPR_ARG (exp, 1);
11911   STRIP_NOPS (ost);
11912
11913   if (TREE_CODE (ost) != INTEGER_CST
11914       || tree_int_cst_sgn (ost) < 0
11915       || compare_tree_int (ost, 3) > 0)
11916     {
11917       error ("%Klast argument of %D is not integer constant between 0 and 3",
11918              exp, fndecl);
11919       expand_builtin_trap ();
11920       return const0_rtx;
11921     }
11922
11923   object_size_type = tree_low_cst (ost, 0);
11924
11925   return object_size_type < 2 ? constm1_rtx : const0_rtx;
11926 }
11927
11928 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11929    FCODE is the BUILT_IN_* to use.
11930    Return NULL_RTX if we failed; the caller should emit a normal call,
11931    otherwise try to get the result in TARGET, if convenient (and in
11932    mode MODE if that's convenient).  */
11933
11934 static rtx
11935 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11936                            enum built_in_function fcode)
11937 {
11938   tree dest, src, len, size;
11939
11940   if (!validate_arglist (exp,
11941                          POINTER_TYPE,
11942                          fcode == BUILT_IN_MEMSET_CHK
11943                          ? INTEGER_TYPE : POINTER_TYPE,
11944                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
11945     return NULL_RTX;
11946
11947   dest = CALL_EXPR_ARG (exp, 0);
11948   src = CALL_EXPR_ARG (exp, 1);
11949   len = CALL_EXPR_ARG (exp, 2);
11950   size = CALL_EXPR_ARG (exp, 3);
11951
11952   if (! host_integerp (size, 1))
11953     return NULL_RTX;
11954
11955   if (host_integerp (len, 1) || integer_all_onesp (size))
11956     {
11957       tree fn;
11958
11959       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11960         {
11961           warning (0, "%Kcall to %D will always overflow destination buffer",
11962                    exp, get_callee_fndecl (exp));
11963           return NULL_RTX;
11964         }
11965
11966       fn = NULL_TREE;
11967       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11968          mem{cpy,pcpy,move,set} is available.  */
11969       switch (fcode)
11970         {
11971         case BUILT_IN_MEMCPY_CHK:
11972           fn = built_in_decls[BUILT_IN_MEMCPY];
11973           break;
11974         case BUILT_IN_MEMPCPY_CHK:
11975           fn = built_in_decls[BUILT_IN_MEMPCPY];
11976           break;
11977         case BUILT_IN_MEMMOVE_CHK:
11978           fn = built_in_decls[BUILT_IN_MEMMOVE];
11979           break;
11980         case BUILT_IN_MEMSET_CHK:
11981           fn = built_in_decls[BUILT_IN_MEMSET];
11982           break;
11983         default:
11984           break;
11985         }
11986
11987       if (! fn)
11988         return NULL_RTX;
11989
11990       fn = build_call_expr (fn, 3, dest, src, len);
11991       STRIP_TYPE_NOPS (fn);
11992       while (TREE_CODE (fn) == COMPOUND_EXPR)
11993         {
11994           expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
11995                        EXPAND_NORMAL);
11996           fn = TREE_OPERAND (fn, 1);
11997         }
11998       if (TREE_CODE (fn) == CALL_EXPR)
11999         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12000       return expand_expr (fn, target, mode, EXPAND_NORMAL);
12001     }
12002   else if (fcode == BUILT_IN_MEMSET_CHK)
12003     return NULL_RTX;
12004   else
12005     {
12006       unsigned int dest_align
12007         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12008
12009       /* If DEST is not a pointer type, call the normal function.  */
12010       if (dest_align == 0)
12011         return NULL_RTX;
12012
12013       /* If SRC and DEST are the same (and not volatile), do nothing.  */
12014       if (operand_equal_p (src, dest, 0))
12015         {
12016           tree expr;
12017
12018           if (fcode != BUILT_IN_MEMPCPY_CHK)
12019             {
12020               /* Evaluate and ignore LEN in case it has side-effects.  */
12021               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12022               return expand_expr (dest, target, mode, EXPAND_NORMAL);
12023             }
12024
12025           expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
12026           return expand_expr (expr, target, mode, EXPAND_NORMAL);
12027         }
12028
12029       /* __memmove_chk special case.  */
12030       if (fcode == BUILT_IN_MEMMOVE_CHK)
12031         {
12032           unsigned int src_align
12033             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12034
12035           if (src_align == 0)
12036             return NULL_RTX;
12037
12038           /* If src is categorized for a readonly section we can use
12039              normal __memcpy_chk.  */
12040           if (readonly_data_expr (src))
12041             {
12042               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12043               if (!fn)
12044                 return NULL_RTX;
12045               fn = build_call_expr (fn, 4, dest, src, len, size);
12046               STRIP_TYPE_NOPS (fn);
12047               while (TREE_CODE (fn) == COMPOUND_EXPR)
12048                 {
12049                   expand_expr (TREE_OPERAND (fn, 0), const0_rtx, VOIDmode,
12050                                EXPAND_NORMAL);
12051                   fn = TREE_OPERAND (fn, 1);
12052                 }
12053               if (TREE_CODE (fn) == CALL_EXPR)
12054                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12055               return expand_expr (fn, target, mode, EXPAND_NORMAL);
12056             }
12057         }
12058       return NULL_RTX;
12059     }
12060 }
12061
12062 /* Emit warning if a buffer overflow is detected at compile time.  */
12063
12064 static void
12065 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12066 {
12067   int is_strlen = 0;
12068   tree len, size;
12069
12070   switch (fcode)
12071     {
12072     case BUILT_IN_STRCPY_CHK:
12073     case BUILT_IN_STPCPY_CHK:
12074     /* For __strcat_chk the warning will be emitted only if overflowing
12075        by at least strlen (dest) + 1 bytes.  */
12076     case BUILT_IN_STRCAT_CHK:
12077       len = CALL_EXPR_ARG (exp, 1);
12078       size = CALL_EXPR_ARG (exp, 2);
12079       is_strlen = 1;
12080       break;
12081     case BUILT_IN_STRNCAT_CHK:
12082     case BUILT_IN_STRNCPY_CHK:
12083       len = CALL_EXPR_ARG (exp, 2);
12084       size = CALL_EXPR_ARG (exp, 3);
12085       break;
12086     case BUILT_IN_SNPRINTF_CHK:
12087     case BUILT_IN_VSNPRINTF_CHK:
12088       len = CALL_EXPR_ARG (exp, 1);
12089       size = CALL_EXPR_ARG (exp, 3);
12090       break;
12091     default:
12092       gcc_unreachable ();
12093     }
12094
12095   if (!len || !size)
12096     return;
12097
12098   if (! host_integerp (size, 1) || integer_all_onesp (size))
12099     return;
12100
12101   if (is_strlen)
12102     {
12103       len = c_strlen (len, 1);
12104       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12105         return;
12106     }
12107   else if (fcode == BUILT_IN_STRNCAT_CHK)
12108     {
12109       tree src = CALL_EXPR_ARG (exp, 1);
12110       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12111         return;
12112       src = c_strlen (src, 1);
12113       if (! src || ! host_integerp (src, 1))
12114         {
12115           warning (0, "%Kcall to %D might overflow destination buffer",
12116                    exp, get_callee_fndecl (exp));
12117           return;
12118         }
12119       else if (tree_int_cst_lt (src, size))
12120         return;
12121     }
12122   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12123     return;
12124
12125   warning (0, "%Kcall to %D will always overflow destination buffer",
12126            exp, get_callee_fndecl (exp));
12127 }
12128
12129 /* Emit warning if a buffer overflow is detected at compile time
12130    in __sprintf_chk/__vsprintf_chk calls.  */
12131
12132 static void
12133 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12134 {
12135   tree dest, size, len, fmt, flag;
12136   const char *fmt_str;
12137   int nargs = call_expr_nargs (exp);
12138
12139   /* Verify the required arguments in the original call.  */
12140   
12141   if (nargs < 4)
12142     return;
12143   dest = CALL_EXPR_ARG (exp, 0);
12144   flag = CALL_EXPR_ARG (exp, 1);
12145   size = CALL_EXPR_ARG (exp, 2);
12146   fmt = CALL_EXPR_ARG (exp, 3);
12147
12148   if (! host_integerp (size, 1) || integer_all_onesp (size))
12149     return;
12150
12151   /* Check whether the format is a literal string constant.  */
12152   fmt_str = c_getstr (fmt);
12153   if (fmt_str == NULL)
12154     return;
12155
12156   if (!init_target_chars ())
12157     return;
12158
12159   /* If the format doesn't contain % args or %%, we know its size.  */
12160   if (strchr (fmt_str, target_percent) == 0)
12161     len = build_int_cstu (size_type_node, strlen (fmt_str));
12162   /* If the format is "%s" and first ... argument is a string literal,
12163      we know it too.  */
12164   else if (fcode == BUILT_IN_SPRINTF_CHK
12165            && strcmp (fmt_str, target_percent_s) == 0)
12166     {
12167       tree arg;
12168
12169       if (nargs < 5)
12170         return;
12171       arg = CALL_EXPR_ARG (exp, 4);
12172       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12173         return;
12174
12175       len = c_strlen (arg, 1);
12176       if (!len || ! host_integerp (len, 1))
12177         return;
12178     }
12179   else
12180     return;
12181
12182   if (! tree_int_cst_lt (len, size))
12183     {
12184       warning (0, "%Kcall to %D will always overflow destination buffer",
12185                exp, get_callee_fndecl (exp));
12186     }
12187 }
12188
12189 /* Emit warning if a free is called with address of a variable.  */
12190
12191 static void
12192 maybe_emit_free_warning (tree exp)
12193 {
12194   tree arg = CALL_EXPR_ARG (exp, 0);
12195
12196   STRIP_NOPS (arg);
12197   if (TREE_CODE (arg) != ADDR_EXPR)
12198     return;
12199
12200   arg = get_base_address (TREE_OPERAND (arg, 0));
12201   if (arg == NULL || INDIRECT_REF_P (arg))
12202     return;
12203
12204   if (SSA_VAR_P (arg))
12205     warning (0, "%Kattempt to free a non-heap object %qD", exp, arg);
12206   else
12207     warning (0, "%Kattempt to free a non-heap object", exp);
12208 }
12209
12210 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12211    if possible.  */
12212
12213 tree
12214 fold_builtin_object_size (tree ptr, tree ost)
12215 {
12216   tree ret = NULL_TREE;
12217   int object_size_type;
12218
12219   if (!validate_arg (ptr, POINTER_TYPE)
12220       || !validate_arg (ost, INTEGER_TYPE))
12221     return NULL_TREE;
12222
12223   STRIP_NOPS (ost);
12224
12225   if (TREE_CODE (ost) != INTEGER_CST
12226       || tree_int_cst_sgn (ost) < 0
12227       || compare_tree_int (ost, 3) > 0)
12228     return NULL_TREE;
12229
12230   object_size_type = tree_low_cst (ost, 0);
12231
12232   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12233      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12234      and (size_t) 0 for types 2 and 3.  */
12235   if (TREE_SIDE_EFFECTS (ptr))
12236     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12237
12238   if (TREE_CODE (ptr) == ADDR_EXPR)
12239     ret = build_int_cstu (size_type_node,
12240                           compute_builtin_object_size (ptr, object_size_type));
12241
12242   else if (TREE_CODE (ptr) == SSA_NAME)
12243     {
12244       unsigned HOST_WIDE_INT bytes;
12245
12246       /* If object size is not known yet, delay folding until
12247        later.  Maybe subsequent passes will help determining
12248        it.  */
12249       bytes = compute_builtin_object_size (ptr, object_size_type);
12250       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12251                                              ? -1 : 0))
12252         ret = build_int_cstu (size_type_node, bytes);
12253     }
12254
12255   if (ret)
12256     {
12257       unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12258       HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12259       if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12260         ret = NULL_TREE;
12261     }
12262
12263   return ret;
12264 }
12265
12266 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12267    DEST, SRC, LEN, and SIZE are the arguments to the call.
12268    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12269    code of the builtin.  If MAXLEN is not NULL, it is maximum length
12270    passed as third argument.  */
12271
12272 tree
12273 fold_builtin_memory_chk (tree fndecl,
12274                          tree dest, tree src, tree len, tree size,
12275                          tree maxlen, bool ignore,
12276                          enum built_in_function fcode)
12277 {
12278   tree fn;
12279
12280   if (!validate_arg (dest, POINTER_TYPE)
12281       || !validate_arg (src,
12282                         (fcode == BUILT_IN_MEMSET_CHK
12283                          ? INTEGER_TYPE : POINTER_TYPE))
12284       || !validate_arg (len, INTEGER_TYPE)
12285       || !validate_arg (size, INTEGER_TYPE))
12286     return NULL_TREE;
12287
12288   /* If SRC and DEST are the same (and not volatile), return DEST
12289      (resp. DEST+LEN for __mempcpy_chk).  */
12290   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12291     {
12292       if (fcode != BUILT_IN_MEMPCPY_CHK)
12293         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12294       else
12295         {
12296           tree temp = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
12297           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
12298         }
12299     }
12300
12301   if (! host_integerp (size, 1))
12302     return NULL_TREE;
12303
12304   if (! integer_all_onesp (size))
12305     {
12306       if (! host_integerp (len, 1))
12307         {
12308           /* If LEN is not constant, try MAXLEN too.
12309              For MAXLEN only allow optimizing into non-_ocs function
12310              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12311           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12312             {
12313               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12314                 {
12315                   /* (void) __mempcpy_chk () can be optimized into
12316                      (void) __memcpy_chk ().  */
12317                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12318                   if (!fn)
12319                     return NULL_TREE;
12320
12321                   return build_call_expr (fn, 4, dest, src, len, size);
12322                 }
12323               return NULL_TREE;
12324             }
12325         }
12326       else
12327         maxlen = len;
12328
12329       if (tree_int_cst_lt (size, maxlen))
12330         return NULL_TREE;
12331     }
12332
12333   fn = NULL_TREE;
12334   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12335      mem{cpy,pcpy,move,set} is available.  */
12336   switch (fcode)
12337     {
12338     case BUILT_IN_MEMCPY_CHK:
12339       fn = built_in_decls[BUILT_IN_MEMCPY];
12340       break;
12341     case BUILT_IN_MEMPCPY_CHK:
12342       fn = built_in_decls[BUILT_IN_MEMPCPY];
12343       break;
12344     case BUILT_IN_MEMMOVE_CHK:
12345       fn = built_in_decls[BUILT_IN_MEMMOVE];
12346       break;
12347     case BUILT_IN_MEMSET_CHK:
12348       fn = built_in_decls[BUILT_IN_MEMSET];
12349       break;
12350     default:
12351       break;
12352     }
12353
12354   if (!fn)
12355     return NULL_TREE;
12356
12357   return build_call_expr (fn, 3, dest, src, len);
12358 }
12359
12360 /* Fold a call to the __st[rp]cpy_chk builtin.
12361    DEST, SRC, and SIZE are the arguments to the call.
12362    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12363    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12364    strings passed as second argument.  */
12365
12366 tree
12367 fold_builtin_stxcpy_chk (tree fndecl, tree dest, tree src, tree size,
12368                          tree maxlen, bool ignore,
12369                          enum built_in_function fcode)
12370 {
12371   tree len, fn;
12372
12373   if (!validate_arg (dest, POINTER_TYPE)
12374       || !validate_arg (src, POINTER_TYPE)
12375       || !validate_arg (size, INTEGER_TYPE))
12376     return NULL_TREE;
12377
12378   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12379   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12380     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
12381
12382   if (! host_integerp (size, 1))
12383     return NULL_TREE;
12384
12385   if (! integer_all_onesp (size))
12386     {
12387       len = c_strlen (src, 1);
12388       if (! len || ! host_integerp (len, 1))
12389         {
12390           /* If LEN is not constant, try MAXLEN too.
12391              For MAXLEN only allow optimizing into non-_ocs function
12392              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12393           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12394             {
12395               if (fcode == BUILT_IN_STPCPY_CHK)
12396                 {
12397                   if (! ignore)
12398                     return NULL_TREE;
12399
12400                   /* If return value of __stpcpy_chk is ignored,
12401                      optimize into __strcpy_chk.  */
12402                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12403                   if (!fn)
12404                     return NULL_TREE;
12405
12406                   return build_call_expr (fn, 3, dest, src, size);
12407                 }
12408
12409               if (! len || TREE_SIDE_EFFECTS (len))
12410                 return NULL_TREE;
12411
12412               /* If c_strlen returned something, but not a constant,
12413                  transform __strcpy_chk into __memcpy_chk.  */
12414               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12415               if (!fn)
12416                 return NULL_TREE;
12417
12418               len = size_binop (PLUS_EXPR, len, ssize_int (1));
12419               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
12420                                    build_call_expr (fn, 4,
12421                                                     dest, src, len, size));
12422             }
12423         }
12424       else
12425         maxlen = len;
12426
12427       if (! tree_int_cst_lt (maxlen, size))
12428         return NULL_TREE;
12429     }
12430
12431   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12432   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12433                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12434   if (!fn)
12435     return NULL_TREE;
12436
12437   return build_call_expr (fn, 2, dest, src);
12438 }
12439
12440 /* Fold a call to the __strncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12441    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12442    length passed as third argument.  */
12443
12444 tree
12445 fold_builtin_strncpy_chk (tree dest, tree src, tree len, tree size,
12446                           tree maxlen)
12447 {
12448   tree fn;
12449
12450   if (!validate_arg (dest, POINTER_TYPE)
12451       || !validate_arg (src, POINTER_TYPE)
12452       || !validate_arg (len, INTEGER_TYPE)
12453       || !validate_arg (size, INTEGER_TYPE))
12454     return NULL_TREE;
12455
12456   if (! host_integerp (size, 1))
12457     return NULL_TREE;
12458
12459   if (! integer_all_onesp (size))
12460     {
12461       if (! host_integerp (len, 1))
12462         {
12463           /* If LEN is not constant, try MAXLEN too.
12464              For MAXLEN only allow optimizing into non-_ocs function
12465              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12466           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12467             return NULL_TREE;
12468         }
12469       else
12470         maxlen = len;
12471
12472       if (tree_int_cst_lt (size, maxlen))
12473         return NULL_TREE;
12474     }
12475
12476   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
12477   fn = built_in_decls[BUILT_IN_STRNCPY];
12478   if (!fn)
12479     return NULL_TREE;
12480
12481   return build_call_expr (fn, 3, dest, src, len);
12482 }
12483
12484 /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
12485    are the arguments to the call.  */
12486
12487 static tree
12488 fold_builtin_strcat_chk (tree fndecl, tree dest, tree src, tree size)
12489 {
12490   tree fn;
12491   const char *p;
12492
12493   if (!validate_arg (dest, POINTER_TYPE)
12494       || !validate_arg (src, POINTER_TYPE)
12495       || !validate_arg (size, INTEGER_TYPE))
12496     return NULL_TREE;
12497
12498   p = c_getstr (src);
12499   /* If the SRC parameter is "", return DEST.  */
12500   if (p && *p == '\0')
12501     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12502
12503   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12504     return NULL_TREE;
12505
12506   /* If __builtin_strcat_chk is used, assume strcat is available.  */
12507   fn = built_in_decls[BUILT_IN_STRCAT];
12508   if (!fn)
12509     return NULL_TREE;
12510
12511   return build_call_expr (fn, 2, dest, src);
12512 }
12513
12514 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12515    LEN, and SIZE.  */
12516
12517 static tree
12518 fold_builtin_strncat_chk (tree fndecl,
12519                           tree dest, tree src, tree len, tree size)
12520 {
12521   tree fn;
12522   const char *p;
12523
12524   if (!validate_arg (dest, POINTER_TYPE)
12525       || !validate_arg (src, POINTER_TYPE)
12526       || !validate_arg (size, INTEGER_TYPE)
12527       || !validate_arg (size, INTEGER_TYPE))
12528     return NULL_TREE;
12529
12530   p = c_getstr (src);
12531   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
12532   if (p && *p == '\0')
12533     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12534   else if (integer_zerop (len))
12535     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12536
12537   if (! host_integerp (size, 1))
12538     return NULL_TREE;
12539
12540   if (! integer_all_onesp (size))
12541     {
12542       tree src_len = c_strlen (src, 1);
12543       if (src_len
12544           && host_integerp (src_len, 1)
12545           && host_integerp (len, 1)
12546           && ! tree_int_cst_lt (len, src_len))
12547         {
12548           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
12549           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12550           if (!fn)
12551             return NULL_TREE;
12552
12553           return build_call_expr (fn, 3, dest, src, size);
12554         }
12555       return NULL_TREE;
12556     }
12557
12558   /* If __builtin_strncat_chk is used, assume strncat is available.  */
12559   fn = built_in_decls[BUILT_IN_STRNCAT];
12560   if (!fn)
12561     return NULL_TREE;
12562
12563   return build_call_expr (fn, 3, dest, src, len);
12564 }
12565
12566 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
12567    a normal call should be emitted rather than expanding the function
12568    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
12569
12570 static tree
12571 fold_builtin_sprintf_chk (tree exp, enum built_in_function fcode)
12572 {
12573   tree dest, size, len, fn, fmt, flag;
12574   const char *fmt_str;
12575   int nargs = call_expr_nargs (exp);
12576
12577   /* Verify the required arguments in the original call.  */
12578   if (nargs < 4)
12579     return NULL_TREE;
12580   dest = CALL_EXPR_ARG (exp, 0);
12581   if (!validate_arg (dest, POINTER_TYPE))
12582     return NULL_TREE;
12583   flag = CALL_EXPR_ARG (exp, 1);
12584   if (!validate_arg (flag, INTEGER_TYPE))
12585     return NULL_TREE;
12586   size = CALL_EXPR_ARG (exp, 2);
12587   if (!validate_arg (size, INTEGER_TYPE))
12588     return NULL_TREE;
12589   fmt = CALL_EXPR_ARG (exp, 3);
12590   if (!validate_arg (fmt, POINTER_TYPE))
12591     return NULL_TREE;
12592
12593   if (! host_integerp (size, 1))
12594     return NULL_TREE;
12595
12596   len = NULL_TREE;
12597
12598   if (!init_target_chars ())
12599     return NULL_TREE;
12600
12601   /* Check whether the format is a literal string constant.  */
12602   fmt_str = c_getstr (fmt);
12603   if (fmt_str != NULL)
12604     {
12605       /* If the format doesn't contain % args or %%, we know the size.  */
12606       if (strchr (fmt_str, target_percent) == 0)
12607         {
12608           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
12609             len = build_int_cstu (size_type_node, strlen (fmt_str));
12610         }
12611       /* If the format is "%s" and first ... argument is a string literal,
12612          we know the size too.  */
12613       else if (fcode == BUILT_IN_SPRINTF_CHK
12614                && strcmp (fmt_str, target_percent_s) == 0)
12615         {
12616           tree arg;
12617
12618           if (nargs == 5)
12619             {
12620               arg = CALL_EXPR_ARG (exp, 4);
12621               if (validate_arg (arg, POINTER_TYPE))
12622                 {
12623                   len = c_strlen (arg, 1);
12624                   if (! len || ! host_integerp (len, 1))
12625                     len = NULL_TREE;
12626                 }
12627             }
12628         }
12629     }
12630
12631   if (! integer_all_onesp (size))
12632     {
12633       if (! len || ! tree_int_cst_lt (len, size))
12634         return NULL_TREE;
12635     }
12636
12637   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12638      or if format doesn't contain % chars or is "%s".  */
12639   if (! integer_zerop (flag))
12640     {
12641       if (fmt_str == NULL)
12642         return NULL_TREE;
12643       if (strchr (fmt_str, target_percent) != NULL
12644           && strcmp (fmt_str, target_percent_s))
12645         return NULL_TREE;
12646     }
12647
12648   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
12649   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12650                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12651   if (!fn)
12652     return NULL_TREE;
12653
12654   return rewrite_call_expr (exp, 4, fn, 2, dest, fmt);
12655 }
12656
12657 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
12658    a normal call should be emitted rather than expanding the function
12659    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
12660    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
12661    passed as second argument.  */
12662
12663 tree
12664 fold_builtin_snprintf_chk (tree exp, tree maxlen,
12665                            enum built_in_function fcode)
12666 {
12667   tree dest, size, len, fn, fmt, flag;
12668   const char *fmt_str;
12669
12670   /* Verify the required arguments in the original call.  */
12671   if (call_expr_nargs (exp) < 5)
12672     return NULL_TREE;
12673   dest = CALL_EXPR_ARG (exp, 0);
12674   if (!validate_arg (dest, POINTER_TYPE))
12675     return NULL_TREE;
12676   len = CALL_EXPR_ARG (exp, 1);
12677   if (!validate_arg (len, INTEGER_TYPE))
12678     return NULL_TREE;
12679   flag = CALL_EXPR_ARG (exp, 2);
12680   if (!validate_arg (flag, INTEGER_TYPE))
12681     return NULL_TREE;
12682   size = CALL_EXPR_ARG (exp, 3);
12683   if (!validate_arg (size, INTEGER_TYPE))
12684     return NULL_TREE;
12685   fmt = CALL_EXPR_ARG (exp, 4);
12686   if (!validate_arg (fmt, POINTER_TYPE))
12687     return NULL_TREE;
12688
12689   if (! host_integerp (size, 1))
12690     return NULL_TREE;
12691
12692   if (! integer_all_onesp (size))
12693     {
12694       if (! host_integerp (len, 1))
12695         {
12696           /* If LEN is not constant, try MAXLEN too.
12697              For MAXLEN only allow optimizing into non-_ocs function
12698              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12699           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12700             return NULL_TREE;
12701         }
12702       else
12703         maxlen = len;
12704
12705       if (tree_int_cst_lt (size, maxlen))
12706         return NULL_TREE;
12707     }
12708
12709   if (!init_target_chars ())
12710     return NULL_TREE;
12711
12712   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12713      or if format doesn't contain % chars or is "%s".  */
12714   if (! integer_zerop (flag))
12715     {
12716       fmt_str = c_getstr (fmt);
12717       if (fmt_str == NULL)
12718         return NULL_TREE;
12719       if (strchr (fmt_str, target_percent) != NULL
12720           && strcmp (fmt_str, target_percent_s))
12721         return NULL_TREE;
12722     }
12723
12724   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12725      available.  */
12726   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12727                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12728   if (!fn)
12729     return NULL_TREE;
12730
12731   return rewrite_call_expr (exp, 5, fn, 3, dest, len, fmt);
12732 }
12733
12734 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
12735    FMT and ARG are the arguments to the call; we don't fold cases with
12736    more than 2 arguments, and ARG may be null if this is a 1-argument case.
12737
12738    Return NULL_TREE if no simplification was possible, otherwise return the
12739    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12740    code of the function to be simplified.  */
12741
12742 static tree
12743 fold_builtin_printf (tree fndecl, tree fmt, tree arg, bool ignore,
12744                      enum built_in_function fcode)
12745 {
12746   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
12747   const char *fmt_str = NULL;
12748
12749   /* If the return value is used, don't do the transformation.  */
12750   if (! ignore)
12751     return NULL_TREE;
12752
12753   /* Verify the required arguments in the original call.  */
12754   if (!validate_arg (fmt, POINTER_TYPE))
12755     return NULL_TREE;
12756
12757   /* Check whether the format is a literal string constant.  */
12758   fmt_str = c_getstr (fmt);
12759   if (fmt_str == NULL)
12760     return NULL_TREE;
12761
12762   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12763     {
12764       /* If we're using an unlocked function, assume the other
12765          unlocked functions exist explicitly.  */
12766       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12767       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
12768     }
12769   else
12770     {
12771       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12772       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12773     }
12774
12775   if (!init_target_chars ())
12776     return NULL_TREE;
12777
12778   if (strcmp (fmt_str, target_percent_s) == 0
12779       || strchr (fmt_str, target_percent) == NULL)
12780     {
12781       const char *str;
12782
12783       if (strcmp (fmt_str, target_percent_s) == 0)
12784         {
12785           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12786             return NULL_TREE;
12787
12788           if (!arg || !validate_arg (arg, POINTER_TYPE))
12789             return NULL_TREE;
12790
12791           str = c_getstr (arg);
12792           if (str == NULL)
12793             return NULL_TREE;
12794         }
12795       else
12796         {
12797           /* The format specifier doesn't contain any '%' characters.  */
12798           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
12799               && arg)
12800             return NULL_TREE;
12801           str = fmt_str;
12802         }
12803
12804       /* If the string was "", printf does nothing.  */
12805       if (str[0] == '\0')
12806         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12807
12808       /* If the string has length of 1, call putchar.  */
12809       if (str[1] == '\0')
12810         {
12811           /* Given printf("c"), (where c is any one character,)
12812              convert "c"[0] to an int and pass that to the replacement
12813              function.  */
12814           newarg = build_int_cst (NULL_TREE, str[0]);
12815           if (fn_putchar)
12816             call = build_call_expr (fn_putchar, 1, newarg);
12817         }
12818       else
12819         {
12820           /* If the string was "string\n", call puts("string").  */
12821           size_t len = strlen (str);
12822           if ((unsigned char)str[len - 1] == target_newline)
12823             {
12824               /* Create a NUL-terminated string that's one char shorter
12825                  than the original, stripping off the trailing '\n'.  */
12826               char *newstr = XALLOCAVEC (char, len);
12827               memcpy (newstr, str, len - 1);
12828               newstr[len - 1] = 0;
12829
12830               newarg = build_string_literal (len, newstr);
12831               if (fn_puts)
12832                 call = build_call_expr (fn_puts, 1, newarg);
12833             }
12834           else
12835             /* We'd like to arrange to call fputs(string,stdout) here,
12836                but we need stdout and don't have a way to get it yet.  */
12837             return NULL_TREE;
12838         }
12839     }
12840
12841   /* The other optimizations can be done only on the non-va_list variants.  */
12842   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12843     return NULL_TREE;
12844
12845   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
12846   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
12847     {
12848       if (!arg || !validate_arg (arg, POINTER_TYPE))
12849         return NULL_TREE;
12850       if (fn_puts)
12851         call = build_call_expr (fn_puts, 1, arg);
12852     }
12853
12854   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
12855   else if (strcmp (fmt_str, target_percent_c) == 0)
12856     {
12857       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12858         return NULL_TREE;
12859       if (fn_putchar)
12860         call = build_call_expr (fn_putchar, 1, arg);
12861     }
12862
12863   if (!call)
12864     return NULL_TREE;
12865
12866   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12867 }
12868
12869 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
12870    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
12871    more than 3 arguments, and ARG may be null in the 2-argument case.
12872
12873    Return NULL_TREE if no simplification was possible, otherwise return the
12874    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12875    code of the function to be simplified.  */
12876
12877 static tree
12878 fold_builtin_fprintf (tree fndecl, tree fp, tree fmt, tree arg, bool ignore,
12879                       enum built_in_function fcode)
12880 {
12881   tree fn_fputc, fn_fputs, call = NULL_TREE;
12882   const char *fmt_str = NULL;
12883
12884   /* If the return value is used, don't do the transformation.  */
12885   if (! ignore)
12886     return NULL_TREE;
12887
12888   /* Verify the required arguments in the original call.  */
12889   if (!validate_arg (fp, POINTER_TYPE))
12890     return NULL_TREE;
12891   if (!validate_arg (fmt, POINTER_TYPE))
12892     return NULL_TREE;
12893
12894   /* Check whether the format is a literal string constant.  */
12895   fmt_str = c_getstr (fmt);
12896   if (fmt_str == NULL)
12897     return NULL_TREE;
12898
12899   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12900     {
12901       /* If we're using an unlocked function, assume the other
12902          unlocked functions exist explicitly.  */
12903       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12904       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
12905     }
12906   else
12907     {
12908       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12909       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12910     }
12911
12912   if (!init_target_chars ())
12913     return NULL_TREE;
12914
12915   /* If the format doesn't contain % args or %%, use strcpy.  */
12916   if (strchr (fmt_str, target_percent) == NULL)
12917     {
12918       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
12919           && arg)
12920         return NULL_TREE;
12921
12922       /* If the format specifier was "", fprintf does nothing.  */
12923       if (fmt_str[0] == '\0')
12924         {
12925           /* If FP has side-effects, just wait until gimplification is
12926              done.  */
12927           if (TREE_SIDE_EFFECTS (fp))
12928             return NULL_TREE;
12929
12930           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12931         }
12932
12933       /* When "string" doesn't contain %, replace all cases of
12934          fprintf (fp, string) with fputs (string, fp).  The fputs
12935          builtin will take care of special cases like length == 1.  */
12936       if (fn_fputs)
12937         call = build_call_expr (fn_fputs, 2, fmt, fp);
12938     }
12939
12940   /* The other optimizations can be done only on the non-va_list variants.  */
12941   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
12942     return NULL_TREE;
12943
12944   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
12945   else if (strcmp (fmt_str, target_percent_s) == 0)
12946     {
12947       if (!arg || !validate_arg (arg, POINTER_TYPE))
12948         return NULL_TREE;
12949       if (fn_fputs)
12950         call = build_call_expr (fn_fputs, 2, arg, fp);
12951     }
12952
12953   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
12954   else if (strcmp (fmt_str, target_percent_c) == 0)
12955     {
12956       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12957         return NULL_TREE;
12958       if (fn_fputc)
12959         call = build_call_expr (fn_fputc, 2, arg, fp);
12960     }
12961
12962   if (!call)
12963     return NULL_TREE;
12964   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
12965 }
12966
12967 /* Initialize format string characters in the target charset.  */
12968
12969 static bool
12970 init_target_chars (void)
12971 {
12972   static bool init;
12973   if (!init)
12974     {
12975       target_newline = lang_hooks.to_target_charset ('\n');
12976       target_percent = lang_hooks.to_target_charset ('%');
12977       target_c = lang_hooks.to_target_charset ('c');
12978       target_s = lang_hooks.to_target_charset ('s');
12979       if (target_newline == 0 || target_percent == 0 || target_c == 0
12980           || target_s == 0)
12981         return false;
12982
12983       target_percent_c[0] = target_percent;
12984       target_percent_c[1] = target_c;
12985       target_percent_c[2] = '\0';
12986
12987       target_percent_s[0] = target_percent;
12988       target_percent_s[1] = target_s;
12989       target_percent_s[2] = '\0';
12990
12991       target_percent_s_newline[0] = target_percent;
12992       target_percent_s_newline[1] = target_s;
12993       target_percent_s_newline[2] = target_newline;
12994       target_percent_s_newline[3] = '\0';
12995
12996       init = true;
12997     }
12998   return true;
12999 }
13000
13001 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13002    and no overflow/underflow occurred.  INEXACT is true if M was not
13003    exactly calculated.  TYPE is the tree type for the result.  This
13004    function assumes that you cleared the MPFR flags and then
13005    calculated M to see if anything subsequently set a flag prior to
13006    entering this function.  Return NULL_TREE if any checks fail.  */
13007
13008 static tree
13009 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13010 {
13011   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13012      overflow/underflow occurred.  If -frounding-math, proceed iff the
13013      result of calling FUNC was exact.  */
13014   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13015       && (!flag_rounding_math || !inexact))
13016     {
13017       REAL_VALUE_TYPE rr;
13018
13019       real_from_mpfr (&rr, m, type, GMP_RNDN);
13020       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13021          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13022          but the mpft_t is not, then we underflowed in the
13023          conversion.  */
13024       if (real_isfinite (&rr)
13025           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13026         {
13027           REAL_VALUE_TYPE rmode;
13028
13029           real_convert (&rmode, TYPE_MODE (type), &rr);
13030           /* Proceed iff the specified mode can hold the value.  */
13031           if (real_identical (&rmode, &rr))
13032             return build_real (type, rmode);
13033         }
13034     }
13035   return NULL_TREE;
13036 }
13037
13038 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13039    FUNC on it and return the resulting value as a tree with type TYPE.
13040    If MIN and/or MAX are not NULL, then the supplied ARG must be
13041    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13042    acceptable values, otherwise they are not.  The mpfr precision is
13043    set to the precision of TYPE.  We assume that function FUNC returns
13044    zero if the result could be calculated exactly within the requested
13045    precision.  */
13046
13047 static tree
13048 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13049               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13050               bool inclusive)
13051 {
13052   tree result = NULL_TREE;
13053   
13054   STRIP_NOPS (arg);
13055
13056   /* To proceed, MPFR must exactly represent the target floating point
13057      format, which only happens when the target base equals two.  */
13058   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13059       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13060     {
13061       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13062
13063       if (real_isfinite (ra)
13064           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13065           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13066         {
13067           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13068           const int prec = fmt->p;
13069           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13070           int inexact;
13071           mpfr_t m;
13072
13073           mpfr_init2 (m, prec);
13074           mpfr_from_real (m, ra, GMP_RNDN);
13075           mpfr_clear_flags ();
13076           inexact = func (m, m, rnd);
13077           result = do_mpfr_ckconv (m, type, inexact);
13078           mpfr_clear (m);
13079         }
13080     }
13081   
13082   return result;
13083 }
13084
13085 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13086    FUNC on it and return the resulting value as a tree with type TYPE.
13087    The mpfr precision is set to the precision of TYPE.  We assume that
13088    function FUNC returns zero if the result could be calculated
13089    exactly within the requested precision.  */
13090
13091 static tree
13092 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13093               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13094 {
13095   tree result = NULL_TREE;
13096   
13097   STRIP_NOPS (arg1);
13098   STRIP_NOPS (arg2);
13099
13100   /* To proceed, MPFR must exactly represent the target floating point
13101      format, which only happens when the target base equals two.  */
13102   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13103       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13104       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13105     {
13106       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13107       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13108
13109       if (real_isfinite (ra1) && real_isfinite (ra2))
13110         {
13111           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13112           const int prec = fmt->p;
13113           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13114           int inexact;
13115           mpfr_t m1, m2;
13116
13117           mpfr_inits2 (prec, m1, m2, NULL);
13118           mpfr_from_real (m1, ra1, GMP_RNDN);
13119           mpfr_from_real (m2, ra2, GMP_RNDN);
13120           mpfr_clear_flags ();
13121           inexact = func (m1, m1, m2, rnd);
13122           result = do_mpfr_ckconv (m1, type, inexact);
13123           mpfr_clears (m1, m2, NULL);
13124         }
13125     }
13126   
13127   return result;
13128 }
13129
13130 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13131    FUNC on it and return the resulting value as a tree with type TYPE.
13132    The mpfr precision is set to the precision of TYPE.  We assume that
13133    function FUNC returns zero if the result could be calculated
13134    exactly within the requested precision.  */
13135
13136 static tree
13137 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13138               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13139 {
13140   tree result = NULL_TREE;
13141   
13142   STRIP_NOPS (arg1);
13143   STRIP_NOPS (arg2);
13144   STRIP_NOPS (arg3);
13145
13146   /* To proceed, MPFR must exactly represent the target floating point
13147      format, which only happens when the target base equals two.  */
13148   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13149       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13150       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13151       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13152     {
13153       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13154       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13155       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13156
13157       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13158         {
13159           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13160           const int prec = fmt->p;
13161           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13162           int inexact;
13163           mpfr_t m1, m2, m3;
13164
13165           mpfr_inits2 (prec, m1, m2, m3, NULL);
13166           mpfr_from_real (m1, ra1, GMP_RNDN);
13167           mpfr_from_real (m2, ra2, GMP_RNDN);
13168           mpfr_from_real (m3, ra3, GMP_RNDN);
13169           mpfr_clear_flags ();
13170           inexact = func (m1, m1, m2, m3, rnd);
13171           result = do_mpfr_ckconv (m1, type, inexact);
13172           mpfr_clears (m1, m2, m3, NULL);
13173         }
13174     }
13175   
13176   return result;
13177 }
13178
13179 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13180    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13181    If ARG_SINP and ARG_COSP are NULL then the result is returned
13182    as a complex value.
13183    The type is taken from the type of ARG and is used for setting the
13184    precision of the calculation and results.  */
13185
13186 static tree
13187 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13188 {
13189   tree const type = TREE_TYPE (arg);
13190   tree result = NULL_TREE;
13191   
13192   STRIP_NOPS (arg);
13193   
13194   /* To proceed, MPFR must exactly represent the target floating point
13195      format, which only happens when the target base equals two.  */
13196   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13197       && TREE_CODE (arg) == REAL_CST
13198       && !TREE_OVERFLOW (arg))
13199     {
13200       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13201
13202       if (real_isfinite (ra))
13203         {
13204           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13205           const int prec = fmt->p;
13206           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13207           tree result_s, result_c;
13208           int inexact;
13209           mpfr_t m, ms, mc;
13210
13211           mpfr_inits2 (prec, m, ms, mc, NULL);
13212           mpfr_from_real (m, ra, GMP_RNDN);
13213           mpfr_clear_flags ();
13214           inexact = mpfr_sin_cos (ms, mc, m, rnd);
13215           result_s = do_mpfr_ckconv (ms, type, inexact);
13216           result_c = do_mpfr_ckconv (mc, type, inexact);
13217           mpfr_clears (m, ms, mc, NULL);
13218           if (result_s && result_c)
13219             {
13220               /* If we are to return in a complex value do so.  */
13221               if (!arg_sinp && !arg_cosp)
13222                 return build_complex (build_complex_type (type),
13223                                       result_c, result_s);
13224
13225               /* Dereference the sin/cos pointer arguments.  */
13226               arg_sinp = build_fold_indirect_ref (arg_sinp);
13227               arg_cosp = build_fold_indirect_ref (arg_cosp);
13228               /* Proceed if valid pointer type were passed in.  */
13229               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13230                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13231                 {
13232                   /* Set the values. */
13233                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13234                                           result_s);
13235                   TREE_SIDE_EFFECTS (result_s) = 1;
13236                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13237                                           result_c);
13238                   TREE_SIDE_EFFECTS (result_c) = 1;
13239                   /* Combine the assignments into a compound expr.  */
13240                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13241                                                     result_s, result_c));
13242                 }
13243             }
13244         }
13245     }
13246   return result;
13247 }
13248
13249 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13250    two-argument mpfr order N Bessel function FUNC on them and return
13251    the resulting value as a tree with type TYPE.  The mpfr precision
13252    is set to the precision of TYPE.  We assume that function FUNC
13253    returns zero if the result could be calculated exactly within the
13254    requested precision.  */
13255 static tree
13256 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13257                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13258                   const REAL_VALUE_TYPE *min, bool inclusive)
13259 {
13260   tree result = NULL_TREE;
13261
13262   STRIP_NOPS (arg1);
13263   STRIP_NOPS (arg2);
13264
13265   /* To proceed, MPFR must exactly represent the target floating point
13266      format, which only happens when the target base equals two.  */
13267   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13268       && host_integerp (arg1, 0)
13269       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13270     {
13271       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13272       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13273
13274       if (n == (long)n
13275           && real_isfinite (ra)
13276           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13277         {
13278           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13279           const int prec = fmt->p;
13280           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13281           int inexact;
13282           mpfr_t m;
13283
13284           mpfr_init2 (m, prec);
13285           mpfr_from_real (m, ra, GMP_RNDN);
13286           mpfr_clear_flags ();
13287           inexact = func (m, n, m, rnd);
13288           result = do_mpfr_ckconv (m, type, inexact);
13289           mpfr_clear (m);
13290         }
13291     }
13292   
13293   return result;
13294 }
13295
13296 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13297    the pointer *(ARG_QUO) and return the result.  The type is taken
13298    from the type of ARG0 and is used for setting the precision of the
13299    calculation and results.  */
13300
13301 static tree
13302 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13303 {
13304   tree const type = TREE_TYPE (arg0);
13305   tree result = NULL_TREE;
13306   
13307   STRIP_NOPS (arg0);
13308   STRIP_NOPS (arg1);
13309   
13310   /* To proceed, MPFR must exactly represent the target floating point
13311      format, which only happens when the target base equals two.  */
13312   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13313       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13314       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13315     {
13316       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13317       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13318
13319       if (real_isfinite (ra0) && real_isfinite (ra1))
13320         {
13321           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13322           const int prec = fmt->p;
13323           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13324           tree result_rem;
13325           long integer_quo;
13326           mpfr_t m0, m1;
13327
13328           mpfr_inits2 (prec, m0, m1, NULL);
13329           mpfr_from_real (m0, ra0, GMP_RNDN);
13330           mpfr_from_real (m1, ra1, GMP_RNDN);
13331           mpfr_clear_flags ();
13332           mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13333           /* Remquo is independent of the rounding mode, so pass
13334              inexact=0 to do_mpfr_ckconv().  */
13335           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13336           mpfr_clears (m0, m1, NULL);
13337           if (result_rem)
13338             {
13339               /* MPFR calculates quo in the host's long so it may
13340                  return more bits in quo than the target int can hold
13341                  if sizeof(host long) > sizeof(target int).  This can
13342                  happen even for native compilers in LP64 mode.  In
13343                  these cases, modulo the quo value with the largest
13344                  number that the target int can hold while leaving one
13345                  bit for the sign.  */
13346               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13347                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13348
13349               /* Dereference the quo pointer argument.  */
13350               arg_quo = build_fold_indirect_ref (arg_quo);
13351               /* Proceed iff a valid pointer type was passed in.  */
13352               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13353                 {
13354                   /* Set the value. */
13355                   tree result_quo = fold_build2 (MODIFY_EXPR,
13356                                                  TREE_TYPE (arg_quo), arg_quo,
13357                                                  build_int_cst (NULL, integer_quo));
13358                   TREE_SIDE_EFFECTS (result_quo) = 1;
13359                   /* Combine the quo assignment with the rem.  */
13360                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13361                                                     result_quo, result_rem));
13362                 }
13363             }
13364         }
13365     }
13366   return result;
13367 }
13368
13369 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13370    resulting value as a tree with type TYPE.  The mpfr precision is
13371    set to the precision of TYPE.  We assume that this mpfr function
13372    returns zero if the result could be calculated exactly within the
13373    requested precision.  In addition, the integer pointer represented
13374    by ARG_SG will be dereferenced and set to the appropriate signgam
13375    (-1,1) value.  */
13376
13377 static tree
13378 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13379 {
13380   tree result = NULL_TREE;
13381
13382   STRIP_NOPS (arg);
13383   
13384   /* To proceed, MPFR must exactly represent the target floating point
13385      format, which only happens when the target base equals two.  Also
13386      verify ARG is a constant and that ARG_SG is an int pointer.  */
13387   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13388       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13389       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13390       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13391     {
13392       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13393
13394       /* In addition to NaN and Inf, the argument cannot be zero or a
13395          negative integer.  */
13396       if (real_isfinite (ra)
13397           && ra->cl != rvc_zero
13398           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13399         {
13400           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13401           const int prec = fmt->p;
13402           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13403           int inexact, sg;
13404           mpfr_t m;
13405           tree result_lg;
13406
13407           mpfr_init2 (m, prec);
13408           mpfr_from_real (m, ra, GMP_RNDN);
13409           mpfr_clear_flags ();
13410           inexact = mpfr_lgamma (m, &sg, m, rnd);
13411           result_lg = do_mpfr_ckconv (m, type, inexact);
13412           mpfr_clear (m);
13413           if (result_lg)
13414             {
13415               tree result_sg;
13416
13417               /* Dereference the arg_sg pointer argument.  */
13418               arg_sg = build_fold_indirect_ref (arg_sg);
13419               /* Assign the signgam value into *arg_sg. */
13420               result_sg = fold_build2 (MODIFY_EXPR,
13421                                        TREE_TYPE (arg_sg), arg_sg,
13422                                        build_int_cst (NULL, sg));
13423               TREE_SIDE_EFFECTS (result_sg) = 1;
13424               /* Combine the signgam assignment with the lgamma result.  */
13425               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13426                                                 result_sg, result_lg));
13427             }
13428         }
13429     }
13430
13431   return result;
13432 }
13433
13434 /* FIXME tuples.
13435    The functions below provide an alternate interface for folding
13436    builtin function calls presented as GIMPLE_CALL statements rather
13437    than as CALL_EXPRs.  The folded result is still expressed as a
13438    tree.  There is too much code duplication in the handling of
13439    varargs functions, and a more intrusive re-factoring would permit
13440    better sharing of code between the tree and statement-based
13441    versions of these functions.  */
13442
13443 /* Construct a new CALL_EXPR using the tail of the argument list of STMT
13444    along with N new arguments specified as the "..." parameters.  SKIP
13445    is the number of arguments in STMT to be omitted.  This function is used
13446    to do varargs-to-varargs transformations.  */
13447
13448 static tree
13449 gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13450 {
13451   int oldnargs = gimple_call_num_args (stmt);
13452   int nargs = oldnargs - skip + n;
13453   tree fntype = TREE_TYPE (fndecl);
13454   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13455   tree *buffer;
13456   int i, j;
13457   va_list ap;
13458
13459   buffer = XALLOCAVEC (tree, nargs);
13460   va_start (ap, n);
13461   for (i = 0; i < n; i++)
13462     buffer[i] = va_arg (ap, tree);
13463   va_end (ap);
13464   for (j = skip; j < oldnargs; j++, i++)
13465     buffer[i] = gimple_call_arg (stmt, j);
13466
13467   return fold (build_call_array (TREE_TYPE (fntype), fn, nargs, buffer));
13468 }
13469
13470 /* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
13471    a normal call should be emitted rather than expanding the function
13472    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13473
13474 static tree
13475 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13476 {
13477   tree dest, size, len, fn, fmt, flag;
13478   const char *fmt_str;
13479   int nargs = gimple_call_num_args (stmt);
13480
13481   /* Verify the required arguments in the original call.  */
13482   if (nargs < 4)
13483     return NULL_TREE;
13484   dest = gimple_call_arg (stmt, 0);
13485   if (!validate_arg (dest, POINTER_TYPE))
13486     return NULL_TREE;
13487   flag = gimple_call_arg (stmt, 1);
13488   if (!validate_arg (flag, INTEGER_TYPE))
13489     return NULL_TREE;
13490   size = gimple_call_arg (stmt, 2);
13491   if (!validate_arg (size, INTEGER_TYPE))
13492     return NULL_TREE;
13493   fmt = gimple_call_arg (stmt, 3);
13494   if (!validate_arg (fmt, POINTER_TYPE))
13495     return NULL_TREE;
13496
13497   if (! host_integerp (size, 1))
13498     return NULL_TREE;
13499
13500   len = NULL_TREE;
13501
13502   if (!init_target_chars ())
13503     return NULL_TREE;
13504
13505   /* Check whether the format is a literal string constant.  */
13506   fmt_str = c_getstr (fmt);
13507   if (fmt_str != NULL)
13508     {
13509       /* If the format doesn't contain % args or %%, we know the size.  */
13510       if (strchr (fmt_str, target_percent) == 0)
13511         {
13512           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13513             len = build_int_cstu (size_type_node, strlen (fmt_str));
13514         }
13515       /* If the format is "%s" and first ... argument is a string literal,
13516          we know the size too.  */
13517       else if (fcode == BUILT_IN_SPRINTF_CHK
13518                && strcmp (fmt_str, target_percent_s) == 0)
13519         {
13520           tree arg;
13521
13522           if (nargs == 5)
13523             {
13524               arg = gimple_call_arg (stmt, 4);
13525               if (validate_arg (arg, POINTER_TYPE))
13526                 {
13527                   len = c_strlen (arg, 1);
13528                   if (! len || ! host_integerp (len, 1))
13529                     len = NULL_TREE;
13530                 }
13531             }
13532         }
13533     }
13534
13535   if (! integer_all_onesp (size))
13536     {
13537       if (! len || ! tree_int_cst_lt (len, size))
13538         return NULL_TREE;
13539     }
13540
13541   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13542      or if format doesn't contain % chars or is "%s".  */
13543   if (! integer_zerop (flag))
13544     {
13545       if (fmt_str == NULL)
13546         return NULL_TREE;
13547       if (strchr (fmt_str, target_percent) != NULL
13548           && strcmp (fmt_str, target_percent_s))
13549         return NULL_TREE;
13550     }
13551
13552   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13553   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13554                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13555   if (!fn)
13556     return NULL_TREE;
13557
13558   return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13559 }
13560
13561 /* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
13562    a normal call should be emitted rather than expanding the function
13563    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13564    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13565    passed as second argument.  */
13566
13567 tree
13568 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13569                                   enum built_in_function fcode)
13570 {
13571   tree dest, size, len, fn, fmt, flag;
13572   const char *fmt_str;
13573
13574   /* Verify the required arguments in the original call.  */
13575   if (gimple_call_num_args (stmt) < 5)
13576     return NULL_TREE;
13577   dest = gimple_call_arg (stmt, 0);
13578   if (!validate_arg (dest, POINTER_TYPE))
13579     return NULL_TREE;
13580   len = gimple_call_arg (stmt, 1);
13581   if (!validate_arg (len, INTEGER_TYPE))
13582     return NULL_TREE;
13583   flag = gimple_call_arg (stmt, 2);
13584   if (!validate_arg (flag, INTEGER_TYPE))
13585     return NULL_TREE;
13586   size = gimple_call_arg (stmt, 3);
13587   if (!validate_arg (size, INTEGER_TYPE))
13588     return NULL_TREE;
13589   fmt = gimple_call_arg (stmt, 4);
13590   if (!validate_arg (fmt, POINTER_TYPE))
13591     return NULL_TREE;
13592
13593   if (! host_integerp (size, 1))
13594     return NULL_TREE;
13595
13596   if (! integer_all_onesp (size))
13597     {
13598       if (! host_integerp (len, 1))
13599         {
13600           /* If LEN is not constant, try MAXLEN too.
13601              For MAXLEN only allow optimizing into non-_ocs function
13602              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13603           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13604             return NULL_TREE;
13605         }
13606       else
13607         maxlen = len;
13608
13609       if (tree_int_cst_lt (size, maxlen))
13610         return NULL_TREE;
13611     }
13612
13613   if (!init_target_chars ())
13614     return NULL_TREE;
13615
13616   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13617      or if format doesn't contain % chars or is "%s".  */
13618   if (! integer_zerop (flag))
13619     {
13620       fmt_str = c_getstr (fmt);
13621       if (fmt_str == NULL)
13622         return NULL_TREE;
13623       if (strchr (fmt_str, target_percent) != NULL
13624           && strcmp (fmt_str, target_percent_s))
13625         return NULL_TREE;
13626     }
13627
13628   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13629      available.  */
13630   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13631                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13632   if (!fn)
13633     return NULL_TREE;
13634
13635   return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13636 }
13637
13638 /* Builtins with folding operations that operate on "..." arguments
13639    need special handling; we need to store the arguments in a convenient
13640    data structure before attempting any folding.  Fortunately there are
13641    only a few builtins that fall into this category.  FNDECL is the
13642    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13643    result of the function call is ignored.  */
13644
13645 static tree
13646 gimple_fold_builtin_varargs (tree fndecl, gimple stmt, bool ignore ATTRIBUTE_UNUSED)
13647 {
13648   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13649   tree ret = NULL_TREE;
13650
13651   switch (fcode)
13652     {
13653     case BUILT_IN_SPRINTF_CHK:
13654     case BUILT_IN_VSPRINTF_CHK:
13655       ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13656       break;
13657
13658     case BUILT_IN_SNPRINTF_CHK:
13659     case BUILT_IN_VSNPRINTF_CHK:
13660       ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13661
13662     default:
13663       break;
13664     }
13665   if (ret)
13666     {
13667       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13668       TREE_NO_WARNING (ret) = 1;
13669       return ret;
13670     }
13671   return NULL_TREE;
13672 }
13673
13674 /* A wrapper function for builtin folding that prevents warnings for
13675    "statement without effect" and the like, caused by removing the
13676    call node earlier than the warning is generated.  */
13677
13678 tree
13679 fold_call_stmt (gimple stmt, bool ignore)
13680 {
13681   tree ret = NULL_TREE;
13682   tree fndecl = gimple_call_fndecl (stmt);
13683   if (fndecl
13684       && TREE_CODE (fndecl) == FUNCTION_DECL
13685       && DECL_BUILT_IN (fndecl)
13686       && !gimple_call_va_arg_pack_p (stmt))
13687     {
13688       int nargs = gimple_call_num_args (stmt);
13689
13690       if (avoid_folding_inline_builtin (fndecl))
13691         return NULL_TREE;
13692       /* FIXME: Don't use a list in this interface.  */
13693       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13694         {
13695           tree arglist = NULL_TREE;
13696           int i;
13697           for (i = nargs - 1; i >= 0; i--)
13698             arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13699           return targetm.fold_builtin (fndecl, arglist, ignore);
13700         }
13701       else
13702         {
13703           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13704             {
13705               tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13706               int i;
13707               for (i = 0; i < nargs; i++)
13708                 args[i] = gimple_call_arg (stmt, i);
13709               ret = fold_builtin_n (fndecl, args, nargs, ignore);
13710             }
13711           if (!ret)
13712             ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13713           if (ret)
13714             {
13715               /* Propagate location information from original call to
13716                  expansion of builtin.  Otherwise things like
13717                  maybe_emit_chk_warning, that operate on the expansion
13718                  of a builtin, will use the wrong location information.  */
13719               if (gimple_has_location (stmt))
13720                 {
13721                   tree realret = ret;
13722                   if (TREE_CODE (ret) == NOP_EXPR)
13723                     realret = TREE_OPERAND (ret, 0);
13724                   if (CAN_HAVE_LOCATION_P (realret)
13725                       && !EXPR_HAS_LOCATION (realret))
13726                     SET_EXPR_LOCATION (realret, gimple_location (stmt));
13727                   return realret;
13728                 }
13729               return ret;
13730             }
13731         }
13732     }
13733   return NULL_TREE;
13734 }