OSDN Git Service

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