OSDN Git Service

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