OSDN Git Service

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