OSDN Git Service

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