OSDN Git Service

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