OSDN Git Service

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