OSDN Git Service

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