OSDN Git Service

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