OSDN Git Service

2009-11-08 Paolo Carlini <paolo.carlini@oracle.com>
[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, 2008, 2009
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 "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 SLOW_UNALIGNED_ACCESS
55 #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
56 #endif
57
58 #ifndef PAD_VARARGS_DOWN
59 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
60 #endif
61 #ifdef HAVE_mpc
62 static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
63 #endif
64
65 /* Define the names of the builtin function types and codes.  */
66 const char *const built_in_class_names[4]
67   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
68
69 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
70 const char * built_in_names[(int) END_BUILTINS] =
71 {
72 #include "builtins.def"
73 };
74 #undef DEF_BUILTIN
75
76 /* Setup an array of _DECL trees, make sure each element is
77    initialized to NULL_TREE.  */
78 tree built_in_decls[(int) END_BUILTINS];
79 /* Declarations used when constructing the builtin implicitly in the compiler.
80    It may be NULL_TREE when this is invalid (for instance runtime is not
81    required to implement the function call in all cases).  */
82 tree implicit_built_in_decls[(int) END_BUILTINS];
83
84 static const char *c_getstr (tree);
85 static rtx c_readstr (const char *, enum machine_mode);
86 static int target_char_cast (tree, char *);
87 static rtx get_memory_rtx (tree, tree);
88 static int apply_args_size (void);
89 static int apply_result_size (void);
90 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
91 static rtx result_vector (int, rtx);
92 #endif
93 static void expand_builtin_update_setjmp_buf (rtx);
94 static void expand_builtin_prefetch (tree);
95 static rtx expand_builtin_apply_args (void);
96 static rtx expand_builtin_apply_args_1 (void);
97 static rtx expand_builtin_apply (rtx, rtx, rtx);
98 static void expand_builtin_return (rtx);
99 static enum type_class type_to_class (tree);
100 static rtx expand_builtin_classify_type (tree);
101 static void expand_errno_check (tree, rtx);
102 static rtx expand_builtin_mathfn (tree, rtx, rtx);
103 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
104 static rtx expand_builtin_mathfn_3 (tree, rtx, rtx);
105 static rtx expand_builtin_interclass_mathfn (tree, rtx, rtx);
106 static rtx expand_builtin_sincos (tree);
107 static rtx expand_builtin_cexpi (tree, rtx, rtx);
108 static rtx expand_builtin_int_roundingfn (tree, rtx);
109 static rtx expand_builtin_int_roundingfn_2 (tree, rtx);
110 static rtx expand_builtin_args_info (tree);
111 static rtx expand_builtin_next_arg (void);
112 static rtx expand_builtin_va_start (tree);
113 static rtx expand_builtin_va_end (tree);
114 static rtx expand_builtin_va_copy (tree);
115 static rtx expand_builtin_memcmp (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strcmp (tree, rtx);
117 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
118 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
119 static rtx expand_builtin_memcpy (tree, rtx);
120 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode);
121 static rtx expand_builtin_mempcpy_args (tree, tree, tree, rtx, 
122                                         enum machine_mode, int);
123 static rtx expand_builtin_strcpy (tree, rtx);
124 static rtx expand_builtin_strcpy_args (tree, tree, rtx);
125 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
126 static rtx expand_builtin_strncpy (tree, rtx);
127 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
128 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
129 static rtx expand_builtin_memset_args (tree, tree, tree, rtx, enum machine_mode, tree);
130 static rtx expand_builtin_bzero (tree);
131 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
132 static rtx expand_builtin_alloca (tree, rtx);
133 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
134 static rtx expand_builtin_frame_address (tree, tree);
135 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
136 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
137 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
138 static tree stabilize_va_list_loc (location_t, tree, int);
139 static rtx expand_builtin_expect (tree, rtx);
140 static tree fold_builtin_constant_p (tree);
141 static tree fold_builtin_expect (location_t, tree, tree);
142 static tree fold_builtin_classify_type (tree);
143 static tree fold_builtin_strlen (location_t, tree);
144 static tree fold_builtin_inf (location_t, tree, int);
145 static tree fold_builtin_nan (tree, tree, int);
146 static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
147 static bool validate_arg (const_tree, enum tree_code code);
148 static bool integer_valued_real_p (tree);
149 static tree fold_trunc_transparent_mathfn (location_t, tree, tree);
150 static bool readonly_data_expr (tree);
151 static rtx expand_builtin_fabs (tree, rtx, rtx);
152 static rtx expand_builtin_signbit (tree, rtx);
153 static tree fold_builtin_sqrt (location_t, tree, tree);
154 static tree fold_builtin_cbrt (location_t, tree, tree);
155 static tree fold_builtin_pow (location_t, tree, tree, tree, tree);
156 static tree fold_builtin_powi (location_t, tree, tree, tree, tree);
157 static tree fold_builtin_cos (location_t, tree, tree, tree);
158 static tree fold_builtin_cosh (location_t, tree, tree, tree);
159 static tree fold_builtin_tan (tree, tree);
160 static tree fold_builtin_trunc (location_t, tree, tree);
161 static tree fold_builtin_floor (location_t, tree, tree);
162 static tree fold_builtin_ceil (location_t, tree, tree);
163 static tree fold_builtin_round (location_t, tree, tree);
164 static tree fold_builtin_int_roundingfn (location_t, tree, tree);
165 static tree fold_builtin_bitop (tree, tree);
166 static tree fold_builtin_memory_op (location_t, tree, tree, tree, tree, bool, int);
167 static tree fold_builtin_strchr (location_t, tree, tree, tree);
168 static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
169 static tree fold_builtin_memcmp (location_t, tree, tree, tree);
170 static tree fold_builtin_strcmp (location_t, tree, tree);
171 static tree fold_builtin_strncmp (location_t, tree, tree, tree);
172 static tree fold_builtin_signbit (location_t, tree, tree);
173 static tree fold_builtin_copysign (location_t, tree, tree, tree, tree);
174 static tree fold_builtin_isascii (location_t, tree);
175 static tree fold_builtin_toascii (location_t, tree);
176 static tree fold_builtin_isdigit (location_t, tree);
177 static tree fold_builtin_fabs (location_t, tree, tree);
178 static tree fold_builtin_abs (location_t, tree, tree);
179 static tree fold_builtin_unordered_cmp (location_t, tree, tree, tree, enum tree_code,
180                                         enum tree_code);
181 static tree fold_builtin_n (location_t, tree, tree *, int, bool);
182 static tree fold_builtin_0 (location_t, tree, bool);
183 static tree fold_builtin_1 (location_t, tree, tree, bool);
184 static tree fold_builtin_2 (location_t, tree, tree, tree, bool);
185 static tree fold_builtin_3 (location_t, tree, tree, tree, tree, bool);
186 static tree fold_builtin_4 (location_t, tree, tree, tree, tree, tree, bool);
187 static tree fold_builtin_varargs (location_t, tree, tree, bool);
188
189 static tree fold_builtin_strpbrk (location_t, tree, tree, tree);
190 static tree fold_builtin_strstr (location_t, tree, tree, tree);
191 static tree fold_builtin_strrchr (location_t, tree, tree, tree);
192 static tree fold_builtin_strcat (location_t, tree, tree);
193 static tree fold_builtin_strncat (location_t, tree, tree, tree);
194 static tree fold_builtin_strspn (location_t, tree, tree);
195 static tree fold_builtin_strcspn (location_t, tree, tree);
196 static tree fold_builtin_sprintf (location_t, tree, tree, tree, int);
197
198 static rtx expand_builtin_object_size (tree);
199 static rtx expand_builtin_memory_chk (tree, rtx, enum machine_mode,
200                                       enum built_in_function);
201 static void maybe_emit_chk_warning (tree, enum built_in_function);
202 static void maybe_emit_sprintf_chk_warning (tree, enum built_in_function);
203 static void maybe_emit_free_warning (tree);
204 static tree fold_builtin_object_size (tree, tree);
205 static tree fold_builtin_strcat_chk (location_t, tree, tree, tree, tree);
206 static tree fold_builtin_strncat_chk (location_t, tree, tree, tree, tree, tree);
207 static tree fold_builtin_sprintf_chk (location_t, tree, enum built_in_function);
208 static tree fold_builtin_printf (location_t, tree, tree, tree, bool, enum built_in_function);
209 static tree fold_builtin_fprintf (location_t, tree, tree, tree, tree, bool,
210                                   enum built_in_function);
211 static bool init_target_chars (void);
212
213 static unsigned HOST_WIDE_INT target_newline;
214 static unsigned HOST_WIDE_INT target_percent;
215 static unsigned HOST_WIDE_INT target_c;
216 static unsigned HOST_WIDE_INT target_s;
217 static char target_percent_c[3];
218 static char target_percent_s[3];
219 static char target_percent_s_newline[4];
220 static tree do_mpfr_arg1 (tree, tree, int (*)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
221                           const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, bool);
222 static tree do_mpfr_arg2 (tree, tree, tree,
223                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
224 static tree do_mpfr_arg3 (tree, tree, tree, tree,
225                           int (*)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t));
226 static tree do_mpfr_sincos (tree, tree, tree);
227 static tree do_mpfr_bessel_n (tree, tree, tree,
228                               int (*)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
229                               const REAL_VALUE_TYPE *, bool);
230 static tree do_mpfr_remquo (tree, tree, tree);
231 static tree do_mpfr_lgamma_r (tree, tree, tree);
232
233 /* Return true if NAME starts with __builtin_ or __sync_.  */
234
235 bool
236 is_builtin_name (const char *name)
237 {
238   if (strncmp (name, "__builtin_", 10) == 0)
239     return true;
240   if (strncmp (name, "__sync_", 7) == 0)
241     return true;
242   return false;
243 }
244
245
246 /* Return true if DECL is a function symbol representing a built-in.  */
247
248 bool
249 is_builtin_fn (tree decl)
250 {
251   return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
252 }
253
254
255 /* Return true if NODE should be considered for inline expansion regardless
256    of the optimization level.  This means whenever a function is invoked with
257    its "internal" name, which normally contains the prefix "__builtin".  */
258
259 static bool
260 called_as_built_in (tree node)
261 {
262   /* Note that we must use DECL_NAME, not DECL_ASSEMBLER_NAME_SET_P since
263      we want the name used to call the function, not the name it
264      will have. */
265   const char *name = IDENTIFIER_POINTER (DECL_NAME (node));
266   return is_builtin_name (name);
267 }
268
269 /* Return the alignment in bits of EXP, an object.
270    Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
271    guessed alignment e.g. from type alignment.  */
272
273 int
274 get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
275 {
276   unsigned int inner;
277
278   inner = max_align;
279   if (handled_component_p (exp))
280    {
281       HOST_WIDE_INT bitsize, bitpos;
282       tree offset;
283       enum machine_mode mode; 
284       int unsignedp, volatilep;
285
286       exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
287                                  &mode, &unsignedp, &volatilep, true);
288       if (bitpos)
289         inner = MIN (inner, (unsigned) (bitpos & -bitpos));
290       while (offset)
291         {
292           tree next_offset;
293
294           if (TREE_CODE (offset) == PLUS_EXPR)
295             {
296               next_offset = TREE_OPERAND (offset, 0);
297               offset = TREE_OPERAND (offset, 1);
298             }
299           else
300             next_offset = NULL;
301           if (host_integerp (offset, 1))
302             {
303               /* Any overflow in calculating offset_bits won't change
304                  the alignment.  */
305               unsigned offset_bits
306                 = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
307
308               if (offset_bits)
309                 inner = MIN (inner, (offset_bits & -offset_bits));
310             }
311           else if (TREE_CODE (offset) == MULT_EXPR
312                    && host_integerp (TREE_OPERAND (offset, 1), 1))
313             {
314               /* Any overflow in calculating offset_factor won't change
315                  the alignment.  */
316               unsigned offset_factor
317                 = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
318                    * BITS_PER_UNIT);
319
320               if (offset_factor)
321                 inner = MIN (inner, (offset_factor & -offset_factor));
322             }
323           else
324             {
325               inner = MIN (inner, BITS_PER_UNIT);
326               break;
327             }
328           offset = next_offset;
329         }
330     }
331   if (DECL_P (exp))
332     align = MIN (inner, DECL_ALIGN (exp));
333 #ifdef CONSTANT_ALIGNMENT
334   else if (CONSTANT_CLASS_P (exp))
335     align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
336 #endif
337   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
338            || TREE_CODE (exp) == INDIRECT_REF)
339     align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
340   else
341     align = MIN (align, inner);
342   return MIN (align, max_align);
343 }
344
345 /* Returns true iff we can trust that alignment information has been
346    calculated properly.  */
347
348 bool
349 can_trust_pointer_alignment (void)
350 {
351   /* We rely on TER to compute accurate alignment information.  */
352   return (optimize && flag_tree_ter);
353 }
354
355 /* Return the alignment in bits of EXP, a pointer valued expression.
356    But don't return more than MAX_ALIGN no matter what.
357    The alignment returned is, by default, the alignment of the thing that
358    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
359
360    Otherwise, look at the expression to see if we can do better, i.e., if the
361    expression is actually pointing at an object whose alignment is tighter.  */
362
363 int
364 get_pointer_alignment (tree exp, unsigned int max_align)
365 {
366   unsigned int align, inner;
367
368   if (!can_trust_pointer_alignment ())
369     return 0;
370
371   if (!POINTER_TYPE_P (TREE_TYPE (exp)))
372     return 0;
373
374   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
375   align = MIN (align, max_align);
376
377   while (1)
378     {
379       switch (TREE_CODE (exp))
380         {
381         CASE_CONVERT:
382           exp = TREE_OPERAND (exp, 0);
383           if (! POINTER_TYPE_P (TREE_TYPE (exp)))
384             return align;
385
386           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
387           align = MIN (inner, max_align);
388           break;
389
390         case POINTER_PLUS_EXPR:
391           /* If sum of pointer + int, restrict our maximum alignment to that
392              imposed by the integer.  If not, we can't do any better than
393              ALIGN.  */
394           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
395             return align;
396
397           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
398                   & (max_align / BITS_PER_UNIT - 1))
399                  != 0)
400             max_align >>= 1;
401
402           exp = TREE_OPERAND (exp, 0);
403           break;
404
405         case ADDR_EXPR:
406           /* See what we are pointing at and look at its alignment.  */
407           return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
408
409         default:
410           return align;
411         }
412     }
413 }
414
415 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
416    way, because it could contain a zero byte in the middle.
417    TREE_STRING_LENGTH is the size of the character array, not the string.
418
419    ONLY_VALUE should be nonzero if the result is not going to be emitted
420    into the instruction stream and zero if it is going to be expanded.
421    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
422    is returned, otherwise NULL, since
423    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
424    evaluate the side-effects.
425
426    The value returned is of type `ssizetype'.
427
428    Unfortunately, string_constant can't access the values of const char
429    arrays with initializers, so neither can we do so here.  */
430
431 tree
432 c_strlen (tree src, int only_value)
433 {
434   tree offset_node;
435   HOST_WIDE_INT offset;
436   int max;
437   const char *ptr;
438
439   STRIP_NOPS (src);
440   if (TREE_CODE (src) == COND_EXPR
441       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
442     {
443       tree len1, len2;
444
445       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
446       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
447       if (tree_int_cst_equal (len1, len2))
448         return len1;
449     }
450
451   if (TREE_CODE (src) == COMPOUND_EXPR
452       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
453     return c_strlen (TREE_OPERAND (src, 1), only_value);
454
455   src = string_constant (src, &offset_node);
456   if (src == 0)
457     return NULL_TREE;
458
459   max = TREE_STRING_LENGTH (src) - 1;
460   ptr = TREE_STRING_POINTER (src);
461
462   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
463     {
464       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
465          compute the offset to the following null if we don't know where to
466          start searching for it.  */
467       int i;
468
469       for (i = 0; i < max; i++)
470         if (ptr[i] == 0)
471           return NULL_TREE;
472
473       /* We don't know the starting offset, but we do know that the string
474          has no internal zero bytes.  We can assume that the offset falls
475          within the bounds of the string; otherwise, the programmer deserves
476          what he gets.  Subtract the offset from the length of the string,
477          and return that.  This would perhaps not be valid if we were dealing
478          with named arrays in addition to literal string constants.  */
479
480       return size_diffop_loc (input_location, size_int (max), offset_node);
481     }
482
483   /* We have a known offset into the string.  Start searching there for
484      a null character if we can represent it as a single HOST_WIDE_INT.  */
485   if (offset_node == 0)
486     offset = 0;
487   else if (! host_integerp (offset_node, 0))
488     offset = -1;
489   else
490     offset = tree_low_cst (offset_node, 0);
491
492   /* If the offset is known to be out of bounds, warn, and call strlen at
493      runtime.  */
494   if (offset < 0 || offset > max)
495     {
496      /* Suppress multiple warnings for propagated constant strings.  */
497       if (! TREE_NO_WARNING (src))
498         {
499           warning (0, "offset outside bounds of constant string");
500           TREE_NO_WARNING (src) = 1;
501         }
502       return NULL_TREE;
503     }
504
505   /* Use strlen to search for the first zero byte.  Since any strings
506      constructed with build_string will have nulls appended, we win even
507      if we get handed something like (char[4])"abcd".
508
509      Since OFFSET is our starting index into the string, no further
510      calculation is needed.  */
511   return ssize_int (strlen (ptr + offset));
512 }
513
514 /* Return a char pointer for a C string if it is a string constant
515    or sum of string constant and integer constant.  */
516
517 static const char *
518 c_getstr (tree src)
519 {
520   tree offset_node;
521
522   src = string_constant (src, &offset_node);
523   if (src == 0)
524     return 0;
525
526   if (offset_node == 0)
527     return TREE_STRING_POINTER (src);
528   else if (!host_integerp (offset_node, 1)
529            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
530     return 0;
531
532   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
533 }
534
535 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
536    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
537
538 static rtx
539 c_readstr (const char *str, enum machine_mode mode)
540 {
541   HOST_WIDE_INT c[2];
542   HOST_WIDE_INT ch;
543   unsigned int i, j;
544
545   gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
546
547   c[0] = 0;
548   c[1] = 0;
549   ch = 1;
550   for (i = 0; i < GET_MODE_SIZE (mode); i++)
551     {
552       j = i;
553       if (WORDS_BIG_ENDIAN)
554         j = GET_MODE_SIZE (mode) - i - 1;
555       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
556           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
557         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
558       j *= BITS_PER_UNIT;
559       gcc_assert (j <= 2 * HOST_BITS_PER_WIDE_INT);
560
561       if (ch)
562         ch = (unsigned char) str[i];
563       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
564     }
565   return immed_double_const (c[0], c[1], mode);
566 }
567
568 /* Cast a target constant CST to target CHAR and if that value fits into
569    host char type, return zero and put that value into variable pointed to by
570    P.  */
571
572 static int
573 target_char_cast (tree cst, char *p)
574 {
575   unsigned HOST_WIDE_INT val, hostval;
576
577   if (!host_integerp (cst, 1)
578       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
579     return 1;
580
581   val = tree_low_cst (cst, 1);
582   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
583     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
584
585   hostval = val;
586   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
587     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
588
589   if (val != hostval)
590     return 1;
591
592   *p = hostval;
593   return 0;
594 }
595
596 /* Similar to save_expr, but assumes that arbitrary code is not executed
597    in between the multiple evaluations.  In particular, we assume that a
598    non-addressable local variable will not be modified.  */
599
600 static tree
601 builtin_save_expr (tree exp)
602 {
603   if (TREE_ADDRESSABLE (exp) == 0
604       && (TREE_CODE (exp) == PARM_DECL
605           || (TREE_CODE (exp) == VAR_DECL && !TREE_STATIC (exp))))
606     return exp;
607
608   return save_expr (exp);
609 }
610
611 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
612    times to get the address of either a higher stack frame, or a return
613    address located within it (depending on FNDECL_CODE).  */
614
615 static rtx
616 expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
617 {
618   int i;
619
620 #ifdef INITIAL_FRAME_ADDRESS_RTX
621   rtx tem = INITIAL_FRAME_ADDRESS_RTX;
622 #else
623   rtx tem;
624
625   /* For a zero count with __builtin_return_address, we don't care what
626      frame address we return, because target-specific definitions will
627      override us.  Therefore frame pointer elimination is OK, and using
628      the soft frame pointer is OK.
629
630      For a nonzero count, or a zero count with __builtin_frame_address,
631      we require a stable offset from the current frame pointer to the
632      previous one, so we must use the hard frame pointer, and
633      we must disable frame pointer elimination.  */
634   if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
635     tem = frame_pointer_rtx;
636   else
637     {
638       tem = hard_frame_pointer_rtx;
639
640       /* Tell reload not to eliminate the frame pointer.  */
641       crtl->accesses_prior_frames = 1;
642     }
643 #endif
644
645   /* Some machines need special handling before we can access
646      arbitrary frames.  For example, on the SPARC, we must first flush
647      all register windows to the stack.  */
648 #ifdef SETUP_FRAME_ADDRESSES
649   if (count > 0)
650     SETUP_FRAME_ADDRESSES ();
651 #endif
652
653   /* On the SPARC, the return address is not in the frame, it is in a
654      register.  There is no way to access it off of the current frame
655      pointer, but it can be accessed off the previous frame pointer by
656      reading the value from the register window save area.  */
657 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
658   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
659     count--;
660 #endif
661
662   /* Scan back COUNT frames to the specified frame.  */
663   for (i = 0; i < count; i++)
664     {
665       /* Assume the dynamic chain pointer is in the word that the
666          frame address points to, unless otherwise specified.  */
667 #ifdef DYNAMIC_CHAIN_ADDRESS
668       tem = DYNAMIC_CHAIN_ADDRESS (tem);
669 #endif
670       tem = memory_address (Pmode, tem);
671       tem = gen_frame_mem (Pmode, tem);
672       tem = copy_to_reg (tem);
673     }
674
675   /* For __builtin_frame_address, return what we've got.  But, on
676      the SPARC for example, we may have to add a bias.  */
677   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
678 #ifdef FRAME_ADDR_RTX
679     return FRAME_ADDR_RTX (tem);
680 #else
681     return tem;
682 #endif
683
684   /* For __builtin_return_address, get the return address from that frame.  */
685 #ifdef RETURN_ADDR_RTX
686   tem = RETURN_ADDR_RTX (count, tem);
687 #else
688   tem = memory_address (Pmode,
689                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
690   tem = gen_frame_mem (Pmode, tem);
691 #endif
692   return tem;
693 }
694
695 /* Alias set used for setjmp buffer.  */
696 static alias_set_type setjmp_alias_set = -1;
697
698 /* Construct the leading half of a __builtin_setjmp call.  Control will
699    return to RECEIVER_LABEL.  This is also called directly by the SJLJ
700    exception handling code.  */
701
702 void
703 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
704 {
705   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
706   rtx stack_save;
707   rtx mem;
708
709   if (setjmp_alias_set == -1)
710     setjmp_alias_set = new_alias_set ();
711
712   buf_addr = convert_memory_address (Pmode, buf_addr);
713
714   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
715
716   /* We store the frame pointer and the address of receiver_label in
717      the buffer and use the rest of it for the stack save area, which
718      is machine-dependent.  */
719
720   mem = gen_rtx_MEM (Pmode, buf_addr);
721   set_mem_alias_set (mem, setjmp_alias_set);
722   emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());
723
724   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
725   set_mem_alias_set (mem, setjmp_alias_set);
726
727   emit_move_insn (validize_mem (mem),
728                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
729
730   stack_save = gen_rtx_MEM (sa_mode,
731                             plus_constant (buf_addr,
732                                            2 * GET_MODE_SIZE (Pmode)));
733   set_mem_alias_set (stack_save, setjmp_alias_set);
734   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
735
736   /* If there is further processing to do, do it.  */
737 #ifdef HAVE_builtin_setjmp_setup
738   if (HAVE_builtin_setjmp_setup)
739     emit_insn (gen_builtin_setjmp_setup (buf_addr));
740 #endif
741
742   /* Tell optimize_save_area_alloca that extra work is going to
743      need to go on during alloca.  */
744   cfun->calls_setjmp = 1;
745
746   /* We have a nonlocal label.   */
747   cfun->has_nonlocal_label = 1;
748 }
749
750 /* Construct the trailing part of a __builtin_setjmp call.  This is
751    also called directly by the SJLJ exception handling code.  */
752
753 void
754 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
755 {
756   rtx chain;
757
758   /* Clobber the FP when we get here, so we have to make sure it's
759      marked as used by this function.  */
760   emit_use (hard_frame_pointer_rtx);
761
762   /* Mark the static chain as clobbered here so life information
763      doesn't get messed up for it.  */
764   chain = targetm.calls.static_chain (current_function_decl, true);
765   if (chain && REG_P (chain))
766     emit_clobber (chain);
767
768   /* Now put in the code to restore the frame pointer, and argument
769      pointer, if needed.  */
770 #ifdef HAVE_nonlocal_goto
771   if (! HAVE_nonlocal_goto)
772 #endif
773     {
774       emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
775       /* This might change the hard frame pointer in ways that aren't
776          apparent to early optimization passes, so force a clobber.  */
777       emit_clobber (hard_frame_pointer_rtx);
778     }
779
780 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
781   if (fixed_regs[ARG_POINTER_REGNUM])
782     {
783 #ifdef ELIMINABLE_REGS
784       size_t i;
785       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
786
787       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
788         if (elim_regs[i].from == ARG_POINTER_REGNUM
789             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
790           break;
791
792       if (i == ARRAY_SIZE (elim_regs))
793 #endif
794         {
795           /* Now restore our arg pointer from the address at which it
796              was saved in our stack frame.  */
797           emit_move_insn (crtl->args.internal_arg_pointer,
798                           copy_to_reg (get_arg_pointer_save_area ()));
799         }
800     }
801 #endif
802
803 #ifdef HAVE_builtin_setjmp_receiver
804   if (HAVE_builtin_setjmp_receiver)
805     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
806   else
807 #endif
808 #ifdef HAVE_nonlocal_goto_receiver
809     if (HAVE_nonlocal_goto_receiver)
810       emit_insn (gen_nonlocal_goto_receiver ());
811     else
812 #endif
813       { /* Nothing */ }
814
815   /* We must not allow the code we just generated to be reordered by
816      scheduling.  Specifically, the update of the frame pointer must
817      happen immediately, not later.  */
818   emit_insn (gen_blockage ());
819 }
820
821 /* __builtin_longjmp is passed a pointer to an array of five words (not
822    all will be used on all machines).  It operates similarly to the C
823    library function of the same name, but is more efficient.  Much of
824    the code below is copied from the handling of non-local gotos.  */
825
826 static void
827 expand_builtin_longjmp (rtx buf_addr, rtx value)
828 {
829   rtx fp, lab, stack, insn, last;
830   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
831
832   /* DRAP is needed for stack realign if longjmp is expanded to current 
833      function  */
834   if (SUPPORTS_STACK_ALIGNMENT)
835     crtl->need_drap = true;
836
837   if (setjmp_alias_set == -1)
838     setjmp_alias_set = new_alias_set ();
839
840   buf_addr = convert_memory_address (Pmode, buf_addr);
841
842   buf_addr = force_reg (Pmode, buf_addr);
843
844   /* We require that the user must pass a second argument of 1, because
845      that is what builtin_setjmp will return.  */
846   gcc_assert (value == const1_rtx);
847
848   last = get_last_insn ();
849 #ifdef HAVE_builtin_longjmp
850   if (HAVE_builtin_longjmp)
851     emit_insn (gen_builtin_longjmp (buf_addr));
852   else
853 #endif
854     {
855       fp = gen_rtx_MEM (Pmode, buf_addr);
856       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
857                                                GET_MODE_SIZE (Pmode)));
858
859       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
860                                                    2 * GET_MODE_SIZE (Pmode)));
861       set_mem_alias_set (fp, setjmp_alias_set);
862       set_mem_alias_set (lab, setjmp_alias_set);
863       set_mem_alias_set (stack, setjmp_alias_set);
864
865       /* Pick up FP, label, and SP from the block and jump.  This code is
866          from expand_goto in stmt.c; see there for detailed comments.  */
867 #ifdef HAVE_nonlocal_goto
868       if (HAVE_nonlocal_goto)
869         /* We have to pass a value to the nonlocal_goto pattern that will
870            get copied into the static_chain pointer, but it does not matter
871            what that value is, because builtin_setjmp does not use it.  */
872         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
873       else
874 #endif
875         {
876           lab = copy_to_reg (lab);
877
878           emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
879           emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
880
881           emit_move_insn (hard_frame_pointer_rtx, fp);
882           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
883
884           emit_use (hard_frame_pointer_rtx);
885           emit_use (stack_pointer_rtx);
886           emit_indirect_jump (lab);
887         }
888     }
889
890   /* Search backwards and mark the jump insn as a non-local goto.
891      Note that this precludes the use of __builtin_longjmp to a
892      __builtin_setjmp target in the same function.  However, we've
893      already cautioned the user that these functions are for
894      internal exception handling use only.  */
895   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
896     {
897       gcc_assert (insn != last);
898
899       if (JUMP_P (insn))
900         {
901           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
902           break;
903         }
904       else if (CALL_P (insn))
905         break;
906     }
907 }
908
909 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
910    and the address of the save area.  */
911
912 static rtx
913 expand_builtin_nonlocal_goto (tree exp)
914 {
915   tree t_label, t_save_area;
916   rtx r_label, r_save_area, r_fp, r_sp, insn;
917
918   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
919     return NULL_RTX;
920
921   t_label = CALL_EXPR_ARG (exp, 0);
922   t_save_area = CALL_EXPR_ARG (exp, 1);
923
924   r_label = expand_normal (t_label);
925   r_label = convert_memory_address (Pmode, r_label);
926   r_save_area = expand_normal (t_save_area);
927   r_save_area = convert_memory_address (Pmode, r_save_area);
928   /* Copy the address of the save location to a register just in case it was based
929     on the frame pointer.   */
930   r_save_area = copy_to_reg (r_save_area);
931   r_fp = gen_rtx_MEM (Pmode, r_save_area);
932   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
933                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
934
935   crtl->has_nonlocal_goto = 1;
936
937 #ifdef HAVE_nonlocal_goto
938   /* ??? We no longer need to pass the static chain value, afaik.  */
939   if (HAVE_nonlocal_goto)
940     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
941   else
942 #endif
943     {
944       r_label = copy_to_reg (r_label);
945
946       emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
947       emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
948
949       /* Restore frame pointer for containing function.
950          This sets the actual hard register used for the frame pointer
951          to the location of the function's incoming static chain info.
952          The non-local goto handler will then adjust it to contain the
953          proper value and reload the argument pointer, if needed.  */
954       emit_move_insn (hard_frame_pointer_rtx, r_fp);
955       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
956
957       /* USE of hard_frame_pointer_rtx added for consistency;
958          not clear if really needed.  */
959       emit_use (hard_frame_pointer_rtx);
960       emit_use (stack_pointer_rtx);
961
962       /* If the architecture is using a GP register, we must
963          conservatively assume that the target function makes use of it.
964          The prologue of functions with nonlocal gotos must therefore
965          initialize the GP register to the appropriate value, and we
966          must then make sure that this value is live at the point
967          of the jump.  (Note that this doesn't necessarily apply
968          to targets with a nonlocal_goto pattern; they are free
969          to implement it in their own way.  Note also that this is
970          a no-op if the GP register is a global invariant.)  */
971       if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
972           && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
973         emit_use (pic_offset_table_rtx);
974
975       emit_indirect_jump (r_label);
976     }
977
978   /* Search backwards to the jump insn and mark it as a
979      non-local goto.  */
980   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
981     {
982       if (JUMP_P (insn))
983         {
984           add_reg_note (insn, REG_NON_LOCAL_GOTO, const0_rtx);
985           break;
986         }
987       else if (CALL_P (insn))
988         break;
989     }
990
991   return const0_rtx;
992 }
993
994 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
995    (not all will be used on all machines) that was passed to __builtin_setjmp.
996    It updates the stack pointer in that block to correspond to the current
997    stack pointer.  */
998
999 static void
1000 expand_builtin_update_setjmp_buf (rtx buf_addr)
1001 {
1002   enum machine_mode sa_mode = Pmode;
1003   rtx stack_save;
1004
1005
1006 #ifdef HAVE_save_stack_nonlocal
1007   if (HAVE_save_stack_nonlocal)
1008     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
1009 #endif
1010 #ifdef STACK_SAVEAREA_MODE
1011   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
1012 #endif
1013
1014   stack_save
1015     = gen_rtx_MEM (sa_mode,
1016                    memory_address
1017                    (sa_mode,
1018                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
1019
1020 #ifdef HAVE_setjmp
1021   if (HAVE_setjmp)
1022     emit_insn (gen_setjmp ());
1023 #endif
1024
1025   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
1026 }
1027
1028 /* Expand a call to __builtin_prefetch.  For a target that does not support
1029    data prefetch, evaluate the memory address argument in case it has side
1030    effects.  */
1031
1032 static void
1033 expand_builtin_prefetch (tree exp)
1034 {
1035   tree arg0, arg1, arg2;
1036   int nargs;
1037   rtx op0, op1, op2;
1038
1039   if (!validate_arglist (exp, POINTER_TYPE, 0))
1040     return;
1041
1042   arg0 = CALL_EXPR_ARG (exp, 0);
1043
1044   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
1045      zero (read) and argument 2 (locality) defaults to 3 (high degree of
1046      locality).  */
1047   nargs = call_expr_nargs (exp);
1048   if (nargs > 1)
1049     arg1 = CALL_EXPR_ARG (exp, 1);
1050   else
1051     arg1 = integer_zero_node;
1052   if (nargs > 2)
1053     arg2 = CALL_EXPR_ARG (exp, 2);
1054   else
1055     arg2 = build_int_cst (NULL_TREE, 3);
1056
1057   /* Argument 0 is an address.  */
1058   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
1059
1060   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
1061   if (TREE_CODE (arg1) != INTEGER_CST)
1062     {
1063       error ("second argument to %<__builtin_prefetch%> must be a constant");
1064       arg1 = integer_zero_node;
1065     }
1066   op1 = expand_normal (arg1);
1067   /* Argument 1 must be either zero or one.  */
1068   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
1069     {
1070       warning (0, "invalid second argument to %<__builtin_prefetch%>;"
1071                " using zero");
1072       op1 = const0_rtx;
1073     }
1074
1075   /* Argument 2 (locality) must be a compile-time constant int.  */
1076   if (TREE_CODE (arg2) != INTEGER_CST)
1077     {
1078       error ("third argument to %<__builtin_prefetch%> must be a constant");
1079       arg2 = integer_zero_node;
1080     }
1081   op2 = expand_normal (arg2);
1082   /* Argument 2 must be 0, 1, 2, or 3.  */
1083   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
1084     {
1085       warning (0, "invalid third argument to %<__builtin_prefetch%>; using zero");
1086       op2 = const0_rtx;
1087     }
1088
1089 #ifdef HAVE_prefetch
1090   if (HAVE_prefetch)
1091     {
1092       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
1093              (op0,
1094               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
1095           || (GET_MODE (op0) != Pmode))
1096         {
1097           op0 = convert_memory_address (Pmode, op0);
1098           op0 = force_reg (Pmode, op0);
1099         }
1100       emit_insn (gen_prefetch (op0, op1, op2));
1101     }
1102 #endif
1103
1104   /* Don't do anything with direct references to volatile memory, but
1105      generate code to handle other side effects.  */
1106   if (!MEM_P (op0) && side_effects_p (op0))
1107     emit_insn (op0);
1108 }
1109
1110 /* Get a MEM rtx for expression EXP which is the address of an operand
1111    to be used in a string instruction (cmpstrsi, movmemsi, ..).  LEN is
1112    the maximum length of the block of memory that might be accessed or
1113    NULL if unknown.  */
1114
1115 static rtx
1116 get_memory_rtx (tree exp, tree len)
1117 {
1118   tree orig_exp = exp;
1119   rtx addr, mem;
1120   HOST_WIDE_INT off;
1121
1122   /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived
1123      from its expression, for expr->a.b only <variable>.a.b is recorded.  */
1124   if (TREE_CODE (exp) == SAVE_EXPR && !SAVE_EXPR_RESOLVED_P (exp))
1125     exp = TREE_OPERAND (exp, 0);
1126
1127   addr = expand_expr (orig_exp, NULL_RTX, ptr_mode, EXPAND_NORMAL);
1128   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
1129
1130   /* Get an expression we can use to find the attributes to assign to MEM.
1131      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
1132      we can.  First remove any nops.  */
1133   while (CONVERT_EXPR_P (exp)
1134          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
1135     exp = TREE_OPERAND (exp, 0);
1136
1137   off = 0;
1138   if (TREE_CODE (exp) == POINTER_PLUS_EXPR
1139       && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
1140       && host_integerp (TREE_OPERAND (exp, 1), 0)
1141       && (off = tree_low_cst (TREE_OPERAND (exp, 1), 0)) > 0)
1142     exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1143   else if (TREE_CODE (exp) == ADDR_EXPR)
1144     exp = TREE_OPERAND (exp, 0);
1145   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
1146     exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
1147   else
1148     exp = NULL;
1149
1150   /* Honor attributes derived from exp, except for the alias set
1151      (as builtin stringops may alias with anything) and the size
1152      (as stringops may access multiple array elements).  */
1153   if (exp)
1154     {
1155       set_mem_attributes (mem, exp, 0);
1156
1157       if (off)
1158         mem = adjust_automodify_address_nv (mem, BLKmode, NULL, off);
1159
1160       /* Allow the string and memory builtins to overflow from one
1161          field into another, see http://gcc.gnu.org/PR23561.
1162          Thus avoid COMPONENT_REFs in MEM_EXPR unless we know the whole
1163          memory accessed by the string or memory builtin will fit
1164          within the field.  */
1165       if (MEM_EXPR (mem) && TREE_CODE (MEM_EXPR (mem)) == COMPONENT_REF)
1166         {
1167           tree mem_expr = MEM_EXPR (mem);
1168           HOST_WIDE_INT offset = -1, length = -1;
1169           tree inner = exp;
1170
1171           while (TREE_CODE (inner) == ARRAY_REF
1172                  || CONVERT_EXPR_P (inner)
1173                  || TREE_CODE (inner) == VIEW_CONVERT_EXPR
1174                  || TREE_CODE (inner) == SAVE_EXPR)
1175             inner = TREE_OPERAND (inner, 0);
1176
1177           gcc_assert (TREE_CODE (inner) == COMPONENT_REF);
1178
1179           if (MEM_OFFSET (mem)
1180               && CONST_INT_P (MEM_OFFSET (mem)))
1181             offset = INTVAL (MEM_OFFSET (mem));
1182
1183           if (offset >= 0 && len && host_integerp (len, 0))
1184             length = tree_low_cst (len, 0);
1185
1186           while (TREE_CODE (inner) == COMPONENT_REF)
1187             {
1188               tree field = TREE_OPERAND (inner, 1);
1189               gcc_assert (TREE_CODE (mem_expr) == COMPONENT_REF);
1190               gcc_assert (field == TREE_OPERAND (mem_expr, 1));
1191
1192               /* Bitfields are generally not byte-addressable.  */
1193               gcc_assert (!DECL_BIT_FIELD (field)
1194                           || ((tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1195                                % BITS_PER_UNIT) == 0
1196                               && host_integerp (DECL_SIZE (field), 0)
1197                               && (TREE_INT_CST_LOW (DECL_SIZE (field))
1198                                   % BITS_PER_UNIT) == 0));
1199
1200               /* If we can prove that the memory starting at XEXP (mem, 0) and
1201                  ending at XEXP (mem, 0) + LENGTH will fit into this field, we
1202                  can keep the COMPONENT_REF in MEM_EXPR.  But be careful with
1203                  fields without DECL_SIZE_UNIT like flexible array members.  */
1204               if (length >= 0
1205                   && DECL_SIZE_UNIT (field)
1206                   && host_integerp (DECL_SIZE_UNIT (field), 0))
1207                 {
1208                   HOST_WIDE_INT size
1209                     = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
1210                   if (offset <= size
1211                       && length <= size
1212                       && offset + length <= size)
1213                     break;
1214                 }
1215
1216               if (offset >= 0
1217                   && host_integerp (DECL_FIELD_OFFSET (field), 0))
1218                 offset += TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
1219                           + tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
1220                             / BITS_PER_UNIT;
1221               else
1222                 {
1223                   offset = -1;
1224                   length = -1;
1225                 }
1226
1227               mem_expr = TREE_OPERAND (mem_expr, 0);
1228               inner = TREE_OPERAND (inner, 0);
1229             }
1230
1231           if (mem_expr == NULL)
1232             offset = -1;
1233           if (mem_expr != MEM_EXPR (mem))
1234             {
1235               set_mem_expr (mem, mem_expr);
1236               set_mem_offset (mem, offset >= 0 ? GEN_INT (offset) : NULL_RTX);
1237             }
1238         }
1239       set_mem_alias_set (mem, 0);
1240       set_mem_size (mem, NULL_RTX);
1241     }
1242
1243   return mem;
1244 }
1245 \f
1246 /* Built-in functions to perform an untyped call and return.  */
1247
1248 /* For each register that may be used for calling a function, this
1249    gives a mode used to copy the register's value.  VOIDmode indicates
1250    the register is not used for calling a function.  If the machine
1251    has register windows, this gives only the outbound registers.
1252    INCOMING_REGNO gives the corresponding inbound register.  */
1253 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1254
1255 /* For each register that may be used for returning values, this gives
1256    a mode used to copy the register's value.  VOIDmode indicates the
1257    register is not used for returning values.  If the machine has
1258    register windows, this gives only the outbound registers.
1259    INCOMING_REGNO gives the corresponding inbound register.  */
1260 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1261
1262 /* Return the size required for the block returned by __builtin_apply_args,
1263    and initialize apply_args_mode.  */
1264
1265 static int
1266 apply_args_size (void)
1267 {
1268   static int size = -1;
1269   int align;
1270   unsigned int regno;
1271   enum machine_mode mode;
1272
1273   /* The values computed by this function never change.  */
1274   if (size < 0)
1275     {
1276       /* The first value is the incoming arg-pointer.  */
1277       size = GET_MODE_SIZE (Pmode);
1278
1279       /* The second value is the structure value address unless this is
1280          passed as an "invisible" first argument.  */
1281       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1282         size += GET_MODE_SIZE (Pmode);
1283
1284       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1285         if (FUNCTION_ARG_REGNO_P (regno))
1286           {
1287             mode = reg_raw_mode[regno];
1288
1289             gcc_assert (mode != VOIDmode);
1290
1291             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1292             if (size % align != 0)
1293               size = CEIL (size, align) * align;
1294             size += GET_MODE_SIZE (mode);
1295             apply_args_mode[regno] = mode;
1296           }
1297         else
1298           {
1299             apply_args_mode[regno] = VOIDmode;
1300           }
1301     }
1302   return size;
1303 }
1304
1305 /* Return the size required for the block returned by __builtin_apply,
1306    and initialize apply_result_mode.  */
1307
1308 static int
1309 apply_result_size (void)
1310 {
1311   static int size = -1;
1312   int align, regno;
1313   enum machine_mode mode;
1314
1315   /* The values computed by this function never change.  */
1316   if (size < 0)
1317     {
1318       size = 0;
1319
1320       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1321         if (FUNCTION_VALUE_REGNO_P (regno))
1322           {
1323             mode = reg_raw_mode[regno];
1324
1325             gcc_assert (mode != VOIDmode);
1326
1327             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1328             if (size % align != 0)
1329               size = CEIL (size, align) * align;
1330             size += GET_MODE_SIZE (mode);
1331             apply_result_mode[regno] = mode;
1332           }
1333         else
1334           apply_result_mode[regno] = VOIDmode;
1335
1336       /* Allow targets that use untyped_call and untyped_return to override
1337          the size so that machine-specific information can be stored here.  */
1338 #ifdef APPLY_RESULT_SIZE
1339       size = APPLY_RESULT_SIZE;
1340 #endif
1341     }
1342   return size;
1343 }
1344
1345 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1346 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1347    the result block is used to save the values; otherwise it is used to
1348    restore the values.  */
1349
1350 static rtx
1351 result_vector (int savep, rtx result)
1352 {
1353   int regno, size, align, nelts;
1354   enum machine_mode mode;
1355   rtx reg, mem;
1356   rtx *savevec = XALLOCAVEC (rtx, FIRST_PSEUDO_REGISTER);
1357
1358   size = nelts = 0;
1359   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1360     if ((mode = apply_result_mode[regno]) != VOIDmode)
1361       {
1362         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1363         if (size % align != 0)
1364           size = CEIL (size, align) * align;
1365         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1366         mem = adjust_address (result, mode, size);
1367         savevec[nelts++] = (savep
1368                             ? gen_rtx_SET (VOIDmode, mem, reg)
1369                             : gen_rtx_SET (VOIDmode, reg, mem));
1370         size += GET_MODE_SIZE (mode);
1371       }
1372   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1373 }
1374 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1375
1376 /* Save the state required to perform an untyped call with the same
1377    arguments as were passed to the current function.  */
1378
1379 static rtx
1380 expand_builtin_apply_args_1 (void)
1381 {
1382   rtx registers, tem;
1383   int size, align, regno;
1384   enum machine_mode mode;
1385   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1386
1387   /* Create a block where the arg-pointer, structure value address,
1388      and argument registers can be saved.  */
1389   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1390
1391   /* Walk past the arg-pointer and structure value address.  */
1392   size = GET_MODE_SIZE (Pmode);
1393   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1394     size += GET_MODE_SIZE (Pmode);
1395
1396   /* Save each register used in calling a function to the block.  */
1397   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1398     if ((mode = apply_args_mode[regno]) != VOIDmode)
1399       {
1400         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1401         if (size % align != 0)
1402           size = CEIL (size, align) * align;
1403
1404         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1405
1406         emit_move_insn (adjust_address (registers, mode, size), tem);
1407         size += GET_MODE_SIZE (mode);
1408       }
1409
1410   /* Save the arg pointer to the block.  */
1411   tem = copy_to_reg (crtl->args.internal_arg_pointer);
1412 #ifdef STACK_GROWS_DOWNWARD
1413   /* We need the pointer as the caller actually passed them to us, not
1414      as we might have pretended they were passed.  Make sure it's a valid
1415      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1416   tem
1417     = force_operand (plus_constant (tem, crtl->args.pretend_args_size),
1418                      NULL_RTX);
1419 #endif
1420   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1421
1422   size = GET_MODE_SIZE (Pmode);
1423
1424   /* Save the structure value address unless this is passed as an
1425      "invisible" first argument.  */
1426   if (struct_incoming_value)
1427     {
1428       emit_move_insn (adjust_address (registers, Pmode, size),
1429                       copy_to_reg (struct_incoming_value));
1430       size += GET_MODE_SIZE (Pmode);
1431     }
1432
1433   /* Return the address of the block.  */
1434   return copy_addr_to_reg (XEXP (registers, 0));
1435 }
1436
1437 /* __builtin_apply_args returns block of memory allocated on
1438    the stack into which is stored the arg pointer, structure
1439    value address, static chain, and all the registers that might
1440    possibly be used in performing a function call.  The code is
1441    moved to the start of the function so the incoming values are
1442    saved.  */
1443
1444 static rtx
1445 expand_builtin_apply_args (void)
1446 {
1447   /* Don't do __builtin_apply_args more than once in a function.
1448      Save the result of the first call and reuse it.  */
1449   if (apply_args_value != 0)
1450     return apply_args_value;
1451   {
1452     /* When this function is called, it means that registers must be
1453        saved on entry to this function.  So we migrate the
1454        call to the first insn of this function.  */
1455     rtx temp;
1456     rtx seq;
1457
1458     start_sequence ();
1459     temp = expand_builtin_apply_args_1 ();
1460     seq = get_insns ();
1461     end_sequence ();
1462
1463     apply_args_value = temp;
1464
1465     /* Put the insns after the NOTE that starts the function.
1466        If this is inside a start_sequence, make the outer-level insn
1467        chain current, so the code is placed at the start of the
1468        function.  If internal_arg_pointer is a non-virtual pseudo,
1469        it needs to be placed after the function that initializes
1470        that pseudo.  */
1471     push_topmost_sequence ();
1472     if (REG_P (crtl->args.internal_arg_pointer)
1473         && REGNO (crtl->args.internal_arg_pointer) > LAST_VIRTUAL_REGISTER)
1474       emit_insn_before (seq, parm_birth_insn);
1475     else
1476       emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1477     pop_topmost_sequence ();
1478     return temp;
1479   }
1480 }
1481
1482 /* Perform an untyped call and save the state required to perform an
1483    untyped return of whatever value was returned by the given function.  */
1484
1485 static rtx
1486 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1487 {
1488   int size, align, regno;
1489   enum machine_mode mode;
1490   rtx incoming_args, result, reg, dest, src, call_insn;
1491   rtx old_stack_level = 0;
1492   rtx call_fusage = 0;
1493   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1494
1495   arguments = convert_memory_address (Pmode, arguments);
1496
1497   /* Create a block where the return registers can be saved.  */
1498   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1499
1500   /* Fetch the arg pointer from the ARGUMENTS block.  */
1501   incoming_args = gen_reg_rtx (Pmode);
1502   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1503 #ifndef STACK_GROWS_DOWNWARD
1504   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1505                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1506 #endif
1507
1508   /* Push a new argument block and copy the arguments.  Do not allow
1509      the (potential) memcpy call below to interfere with our stack
1510      manipulations.  */
1511   do_pending_stack_adjust ();
1512   NO_DEFER_POP;
1513
1514   /* Save the stack with nonlocal if available.  */
1515 #ifdef HAVE_save_stack_nonlocal
1516   if (HAVE_save_stack_nonlocal)
1517     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1518   else
1519 #endif
1520     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1521
1522   /* Allocate a block of memory onto the stack and copy the memory
1523      arguments to the outgoing arguments address.  */
1524   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1525
1526   /* Set DRAP flag to true, even though allocate_dynamic_stack_space
1527      may have already set current_function_calls_alloca to true.
1528      current_function_calls_alloca won't be set if argsize is zero,
1529      so we have to guarantee need_drap is true here.  */
1530   if (SUPPORTS_STACK_ALIGNMENT)
1531     crtl->need_drap = true;
1532
1533   dest = virtual_outgoing_args_rtx;
1534 #ifndef STACK_GROWS_DOWNWARD
1535   if (CONST_INT_P (argsize))
1536     dest = plus_constant (dest, -INTVAL (argsize));
1537   else
1538     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1539 #endif
1540   dest = gen_rtx_MEM (BLKmode, dest);
1541   set_mem_align (dest, PARM_BOUNDARY);
1542   src = gen_rtx_MEM (BLKmode, incoming_args);
1543   set_mem_align (src, PARM_BOUNDARY);
1544   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1545
1546   /* Refer to the argument block.  */
1547   apply_args_size ();
1548   arguments = gen_rtx_MEM (BLKmode, arguments);
1549   set_mem_align (arguments, PARM_BOUNDARY);
1550
1551   /* Walk past the arg-pointer and structure value address.  */
1552   size = GET_MODE_SIZE (Pmode);
1553   if (struct_value)
1554     size += GET_MODE_SIZE (Pmode);
1555
1556   /* Restore each of the registers previously saved.  Make USE insns
1557      for each of these registers for use in making the call.  */
1558   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1559     if ((mode = apply_args_mode[regno]) != VOIDmode)
1560       {
1561         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1562         if (size % align != 0)
1563           size = CEIL (size, align) * align;
1564         reg = gen_rtx_REG (mode, regno);
1565         emit_move_insn (reg, adjust_address (arguments, mode, size));
1566         use_reg (&call_fusage, reg);
1567         size += GET_MODE_SIZE (mode);
1568       }
1569
1570   /* Restore the structure value address unless this is passed as an
1571      "invisible" first argument.  */
1572   size = GET_MODE_SIZE (Pmode);
1573   if (struct_value)
1574     {
1575       rtx value = gen_reg_rtx (Pmode);
1576       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1577       emit_move_insn (struct_value, value);
1578       if (REG_P (struct_value))
1579         use_reg (&call_fusage, struct_value);
1580       size += GET_MODE_SIZE (Pmode);
1581     }
1582
1583   /* All arguments and registers used for the call are set up by now!  */
1584   function = prepare_call_address (NULL, function, NULL, &call_fusage, 0, 0);
1585
1586   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1587      and we don't want to load it into a register as an optimization,
1588      because prepare_call_address already did it if it should be done.  */
1589   if (GET_CODE (function) != SYMBOL_REF)
1590     function = memory_address (FUNCTION_MODE, function);
1591
1592   /* Generate the actual call instruction and save the return value.  */
1593 #ifdef HAVE_untyped_call
1594   if (HAVE_untyped_call)
1595     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1596                                       result, result_vector (1, result)));
1597   else
1598 #endif
1599 #ifdef HAVE_call_value
1600   if (HAVE_call_value)
1601     {
1602       rtx valreg = 0;
1603
1604       /* Locate the unique return register.  It is not possible to
1605          express a call that sets more than one return register using
1606          call_value; use untyped_call for that.  In fact, untyped_call
1607          only needs to save the return registers in the given block.  */
1608       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1609         if ((mode = apply_result_mode[regno]) != VOIDmode)
1610           {
1611             gcc_assert (!valreg); /* HAVE_untyped_call required.  */
1612
1613             valreg = gen_rtx_REG (mode, regno);
1614           }
1615
1616       emit_call_insn (GEN_CALL_VALUE (valreg,
1617                                       gen_rtx_MEM (FUNCTION_MODE, function),
1618                                       const0_rtx, NULL_RTX, const0_rtx));
1619
1620       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1621     }
1622   else
1623 #endif
1624     gcc_unreachable ();
1625
1626   /* Find the CALL insn we just emitted, and attach the register usage
1627      information.  */
1628   call_insn = last_call_insn ();
1629   add_function_usage_to (call_insn, call_fusage);
1630
1631   /* Restore the stack.  */
1632 #ifdef HAVE_save_stack_nonlocal
1633   if (HAVE_save_stack_nonlocal)
1634     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1635   else
1636 #endif
1637     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1638
1639   OK_DEFER_POP;
1640
1641   /* Return the address of the result block.  */
1642   result = copy_addr_to_reg (XEXP (result, 0));
1643   return convert_memory_address (ptr_mode, result);
1644 }
1645
1646 /* Perform an untyped return.  */
1647
1648 static void
1649 expand_builtin_return (rtx result)
1650 {
1651   int size, align, regno;
1652   enum machine_mode mode;
1653   rtx reg;
1654   rtx call_fusage = 0;
1655
1656   result = convert_memory_address (Pmode, result);
1657
1658   apply_result_size ();
1659   result = gen_rtx_MEM (BLKmode, result);
1660
1661 #ifdef HAVE_untyped_return
1662   if (HAVE_untyped_return)
1663     {
1664       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1665       emit_barrier ();
1666       return;
1667     }
1668 #endif
1669
1670   /* Restore the return value and note that each value is used.  */
1671   size = 0;
1672   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1673     if ((mode = apply_result_mode[regno]) != VOIDmode)
1674       {
1675         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1676         if (size % align != 0)
1677           size = CEIL (size, align) * align;
1678         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1679         emit_move_insn (reg, adjust_address (result, mode, size));
1680
1681         push_to_sequence (call_fusage);
1682         emit_use (reg);
1683         call_fusage = get_insns ();
1684         end_sequence ();
1685         size += GET_MODE_SIZE (mode);
1686       }
1687
1688   /* Put the USE insns before the return.  */
1689   emit_insn (call_fusage);
1690
1691   /* Return whatever values was restored by jumping directly to the end
1692      of the function.  */
1693   expand_naked_return ();
1694 }
1695
1696 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1697
1698 static enum type_class
1699 type_to_class (tree type)
1700 {
1701   switch (TREE_CODE (type))
1702     {
1703     case VOID_TYPE:        return void_type_class;
1704     case INTEGER_TYPE:     return integer_type_class;
1705     case ENUMERAL_TYPE:    return enumeral_type_class;
1706     case BOOLEAN_TYPE:     return boolean_type_class;
1707     case POINTER_TYPE:     return pointer_type_class;
1708     case REFERENCE_TYPE:   return reference_type_class;
1709     case OFFSET_TYPE:      return offset_type_class;
1710     case REAL_TYPE:        return real_type_class;
1711     case COMPLEX_TYPE:     return complex_type_class;
1712     case FUNCTION_TYPE:    return function_type_class;
1713     case METHOD_TYPE:      return method_type_class;
1714     case RECORD_TYPE:      return record_type_class;
1715     case UNION_TYPE:
1716     case QUAL_UNION_TYPE:  return union_type_class;
1717     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1718                                    ? string_type_class : array_type_class);
1719     case LANG_TYPE:        return lang_type_class;
1720     default:               return no_type_class;
1721     }
1722 }
1723
1724 /* Expand a call EXP to __builtin_classify_type.  */
1725
1726 static rtx
1727 expand_builtin_classify_type (tree exp)
1728 {
1729   if (call_expr_nargs (exp))
1730     return GEN_INT (type_to_class (TREE_TYPE (CALL_EXPR_ARG (exp, 0))));
1731   return GEN_INT (no_type_class);
1732 }
1733
1734 /* This helper macro, meant to be used in mathfn_built_in below,
1735    determines which among a set of three builtin math functions is
1736    appropriate for a given type mode.  The `F' and `L' cases are
1737    automatically generated from the `double' case.  */
1738 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1739   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1740   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1741   fcodel = BUILT_IN_MATHFN##L ; break;
1742 /* Similar to above, but appends _R after any F/L suffix.  */
1743 #define CASE_MATHFN_REENT(BUILT_IN_MATHFN) \
1744   case BUILT_IN_MATHFN##_R: case BUILT_IN_MATHFN##F_R: case BUILT_IN_MATHFN##L_R: \
1745   fcode = BUILT_IN_MATHFN##_R; fcodef = BUILT_IN_MATHFN##F_R ; \
1746   fcodel = BUILT_IN_MATHFN##L_R ; break;
1747
1748 /* Return mathematic function equivalent to FN but operating directly
1749    on TYPE, if available.  If IMPLICIT is true find the function in
1750    implicit_built_in_decls[], otherwise use built_in_decls[].  If we
1751    can't do the conversion, return zero.  */
1752
1753 static tree
1754 mathfn_built_in_1 (tree type, enum built_in_function fn, bool implicit)
1755 {
1756   tree const *const fn_arr
1757     = implicit ? implicit_built_in_decls : built_in_decls;
1758   enum built_in_function fcode, fcodef, fcodel;
1759
1760   switch (fn)
1761     {
1762       CASE_MATHFN (BUILT_IN_ACOS)
1763       CASE_MATHFN (BUILT_IN_ACOSH)
1764       CASE_MATHFN (BUILT_IN_ASIN)
1765       CASE_MATHFN (BUILT_IN_ASINH)
1766       CASE_MATHFN (BUILT_IN_ATAN)
1767       CASE_MATHFN (BUILT_IN_ATAN2)
1768       CASE_MATHFN (BUILT_IN_ATANH)
1769       CASE_MATHFN (BUILT_IN_CBRT)
1770       CASE_MATHFN (BUILT_IN_CEIL)
1771       CASE_MATHFN (BUILT_IN_CEXPI)
1772       CASE_MATHFN (BUILT_IN_COPYSIGN)
1773       CASE_MATHFN (BUILT_IN_COS)
1774       CASE_MATHFN (BUILT_IN_COSH)
1775       CASE_MATHFN (BUILT_IN_DREM)
1776       CASE_MATHFN (BUILT_IN_ERF)
1777       CASE_MATHFN (BUILT_IN_ERFC)
1778       CASE_MATHFN (BUILT_IN_EXP)
1779       CASE_MATHFN (BUILT_IN_EXP10)
1780       CASE_MATHFN (BUILT_IN_EXP2)
1781       CASE_MATHFN (BUILT_IN_EXPM1)
1782       CASE_MATHFN (BUILT_IN_FABS)
1783       CASE_MATHFN (BUILT_IN_FDIM)
1784       CASE_MATHFN (BUILT_IN_FLOOR)
1785       CASE_MATHFN (BUILT_IN_FMA)
1786       CASE_MATHFN (BUILT_IN_FMAX)
1787       CASE_MATHFN (BUILT_IN_FMIN)
1788       CASE_MATHFN (BUILT_IN_FMOD)
1789       CASE_MATHFN (BUILT_IN_FREXP)
1790       CASE_MATHFN (BUILT_IN_GAMMA)
1791       CASE_MATHFN_REENT (BUILT_IN_GAMMA) /* GAMMA_R */
1792       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1793       CASE_MATHFN (BUILT_IN_HYPOT)
1794       CASE_MATHFN (BUILT_IN_ILOGB)
1795       CASE_MATHFN (BUILT_IN_INF)
1796       CASE_MATHFN (BUILT_IN_ISINF)
1797       CASE_MATHFN (BUILT_IN_J0)
1798       CASE_MATHFN (BUILT_IN_J1)
1799       CASE_MATHFN (BUILT_IN_JN)
1800       CASE_MATHFN (BUILT_IN_LCEIL)
1801       CASE_MATHFN (BUILT_IN_LDEXP)
1802       CASE_MATHFN (BUILT_IN_LFLOOR)
1803       CASE_MATHFN (BUILT_IN_LGAMMA)
1804       CASE_MATHFN_REENT (BUILT_IN_LGAMMA) /* LGAMMA_R */
1805       CASE_MATHFN (BUILT_IN_LLCEIL)
1806       CASE_MATHFN (BUILT_IN_LLFLOOR)
1807       CASE_MATHFN (BUILT_IN_LLRINT)
1808       CASE_MATHFN (BUILT_IN_LLROUND)
1809       CASE_MATHFN (BUILT_IN_LOG)
1810       CASE_MATHFN (BUILT_IN_LOG10)
1811       CASE_MATHFN (BUILT_IN_LOG1P)
1812       CASE_MATHFN (BUILT_IN_LOG2)
1813       CASE_MATHFN (BUILT_IN_LOGB)
1814       CASE_MATHFN (BUILT_IN_LRINT)
1815       CASE_MATHFN (BUILT_IN_LROUND)
1816       CASE_MATHFN (BUILT_IN_MODF)
1817       CASE_MATHFN (BUILT_IN_NAN)
1818       CASE_MATHFN (BUILT_IN_NANS)
1819       CASE_MATHFN (BUILT_IN_NEARBYINT)
1820       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1821       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1822       CASE_MATHFN (BUILT_IN_POW)
1823       CASE_MATHFN (BUILT_IN_POWI)
1824       CASE_MATHFN (BUILT_IN_POW10)
1825       CASE_MATHFN (BUILT_IN_REMAINDER)
1826       CASE_MATHFN (BUILT_IN_REMQUO)
1827       CASE_MATHFN (BUILT_IN_RINT)
1828       CASE_MATHFN (BUILT_IN_ROUND)
1829       CASE_MATHFN (BUILT_IN_SCALB)
1830       CASE_MATHFN (BUILT_IN_SCALBLN)
1831       CASE_MATHFN (BUILT_IN_SCALBN)
1832       CASE_MATHFN (BUILT_IN_SIGNBIT)
1833       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1834       CASE_MATHFN (BUILT_IN_SIN)
1835       CASE_MATHFN (BUILT_IN_SINCOS)
1836       CASE_MATHFN (BUILT_IN_SINH)
1837       CASE_MATHFN (BUILT_IN_SQRT)
1838       CASE_MATHFN (BUILT_IN_TAN)
1839       CASE_MATHFN (BUILT_IN_TANH)
1840       CASE_MATHFN (BUILT_IN_TGAMMA)
1841       CASE_MATHFN (BUILT_IN_TRUNC)
1842       CASE_MATHFN (BUILT_IN_Y0)
1843       CASE_MATHFN (BUILT_IN_Y1)
1844       CASE_MATHFN (BUILT_IN_YN)
1845
1846       default:
1847         return NULL_TREE;
1848       }
1849
1850   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1851     return fn_arr[fcode];
1852   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1853     return fn_arr[fcodef];
1854   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1855     return fn_arr[fcodel];
1856   else
1857     return NULL_TREE;
1858 }
1859
1860 /* Like mathfn_built_in_1(), but always use the implicit array.  */
1861
1862 tree
1863 mathfn_built_in (tree type, enum built_in_function fn)
1864 {
1865   return mathfn_built_in_1 (type, fn, /*implicit=*/ 1);
1866 }
1867
1868 /* If errno must be maintained, expand the RTL to check if the result,
1869    TARGET, of a built-in function call, EXP, is NaN, and if so set
1870    errno to EDOM.  */
1871
1872 static void
1873 expand_errno_check (tree exp, rtx target)
1874 {
1875   rtx lab = gen_label_rtx ();
1876
1877   /* Test the result; if it is NaN, set errno=EDOM because
1878      the argument was not in the domain.  */
1879   do_compare_rtx_and_jump (target, target, EQ, 0, GET_MODE (target),
1880                            NULL_RTX, NULL_RTX, lab);
1881
1882 #ifdef TARGET_EDOM
1883   /* If this built-in doesn't throw an exception, set errno directly.  */
1884   if (TREE_NOTHROW (TREE_OPERAND (CALL_EXPR_FN (exp), 0)))
1885     {
1886 #ifdef GEN_ERRNO_RTX
1887       rtx errno_rtx = GEN_ERRNO_RTX;
1888 #else
1889       rtx errno_rtx
1890           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1891 #endif
1892       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1893       emit_label (lab);
1894       return;
1895     }
1896 #endif
1897
1898   /* Make sure the library call isn't expanded as a tail call.  */
1899   CALL_EXPR_TAILCALL (exp) = 0;
1900
1901   /* We can't set errno=EDOM directly; let the library call do it.
1902      Pop the arguments right away in case the call gets deleted.  */
1903   NO_DEFER_POP;
1904   expand_call (exp, target, 0);
1905   OK_DEFER_POP;
1906   emit_label (lab);
1907 }
1908
1909 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1910    Return NULL_RTX if a normal call should be emitted rather than expanding
1911    the function in-line.  EXP is the expression that is a call to the builtin
1912    function; if convenient, the result should be placed in TARGET.
1913    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1914
1915 static rtx
1916 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1917 {
1918   optab builtin_optab;
1919   rtx op0, insns;
1920   tree fndecl = get_callee_fndecl (exp);
1921   enum machine_mode mode;
1922   bool errno_set = false;
1923   tree arg;
1924
1925   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
1926     return NULL_RTX;
1927
1928   arg = CALL_EXPR_ARG (exp, 0);
1929
1930   switch (DECL_FUNCTION_CODE (fndecl))
1931     {
1932     CASE_FLT_FN (BUILT_IN_SQRT):
1933       errno_set = ! tree_expr_nonnegative_p (arg);
1934       builtin_optab = sqrt_optab;
1935       break;
1936     CASE_FLT_FN (BUILT_IN_EXP):
1937       errno_set = true; builtin_optab = exp_optab; break;
1938     CASE_FLT_FN (BUILT_IN_EXP10):
1939     CASE_FLT_FN (BUILT_IN_POW10):
1940       errno_set = true; builtin_optab = exp10_optab; break;
1941     CASE_FLT_FN (BUILT_IN_EXP2):
1942       errno_set = true; builtin_optab = exp2_optab; break;
1943     CASE_FLT_FN (BUILT_IN_EXPM1):
1944       errno_set = true; builtin_optab = expm1_optab; break;
1945     CASE_FLT_FN (BUILT_IN_LOGB):
1946       errno_set = true; builtin_optab = logb_optab; break;
1947     CASE_FLT_FN (BUILT_IN_LOG):
1948       errno_set = true; builtin_optab = log_optab; break;
1949     CASE_FLT_FN (BUILT_IN_LOG10):
1950       errno_set = true; builtin_optab = log10_optab; break;
1951     CASE_FLT_FN (BUILT_IN_LOG2):
1952       errno_set = true; builtin_optab = log2_optab; break;
1953     CASE_FLT_FN (BUILT_IN_LOG1P):
1954       errno_set = true; builtin_optab = log1p_optab; break;
1955     CASE_FLT_FN (BUILT_IN_ASIN):
1956       builtin_optab = asin_optab; break;
1957     CASE_FLT_FN (BUILT_IN_ACOS):
1958       builtin_optab = acos_optab; break;
1959     CASE_FLT_FN (BUILT_IN_TAN):
1960       builtin_optab = tan_optab; break;
1961     CASE_FLT_FN (BUILT_IN_ATAN):
1962       builtin_optab = atan_optab; break;
1963     CASE_FLT_FN (BUILT_IN_FLOOR):
1964       builtin_optab = floor_optab; break;
1965     CASE_FLT_FN (BUILT_IN_CEIL):
1966       builtin_optab = ceil_optab; break;
1967     CASE_FLT_FN (BUILT_IN_TRUNC):
1968       builtin_optab = btrunc_optab; break;
1969     CASE_FLT_FN (BUILT_IN_ROUND):
1970       builtin_optab = round_optab; break;
1971     CASE_FLT_FN (BUILT_IN_NEARBYINT):
1972       builtin_optab = nearbyint_optab;
1973       if (flag_trapping_math)
1974         break;
1975       /* Else fallthrough and expand as rint.  */
1976     CASE_FLT_FN (BUILT_IN_RINT):
1977       builtin_optab = rint_optab; break;
1978     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
1979       builtin_optab = significand_optab; break;
1980     default:
1981       gcc_unreachable ();
1982     }
1983
1984   /* Make a suitable register to place result in.  */
1985   mode = TYPE_MODE (TREE_TYPE (exp));
1986
1987   if (! flag_errno_math || ! HONOR_NANS (mode))
1988     errno_set = false;
1989
1990   /* Before working hard, check whether the instruction is available.  */
1991   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
1992     {
1993       target = gen_reg_rtx (mode);
1994
1995       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1996          need to expand the argument again.  This way, we will not perform
1997          side-effects more the once.  */
1998       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
1999
2000       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2001
2002       start_sequence ();
2003
2004       /* Compute into TARGET.
2005          Set TARGET to wherever the result comes back.  */
2006       target = expand_unop (mode, builtin_optab, op0, target, 0);
2007
2008       if (target != 0)
2009         {
2010           if (errno_set)
2011             expand_errno_check (exp, target);
2012
2013           /* Output the entire sequence.  */
2014           insns = get_insns ();
2015           end_sequence ();
2016           emit_insn (insns);
2017           return target;
2018         }
2019
2020       /* If we were unable to expand via the builtin, stop the sequence
2021          (without outputting the insns) and call to the library function
2022          with the stabilized argument list.  */
2023       end_sequence ();
2024     }
2025
2026   return expand_call (exp, target, target == const0_rtx);
2027 }
2028
2029 /* Expand a call to the builtin binary math functions (pow and atan2).
2030    Return NULL_RTX if a normal call should be emitted rather than expanding the
2031    function in-line.  EXP is the expression that is a call to the builtin
2032    function; if convenient, the result should be placed in TARGET.
2033    SUBTARGET may be used as the target for computing one of EXP's
2034    operands.  */
2035
2036 static rtx
2037 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
2038 {
2039   optab builtin_optab;
2040   rtx op0, op1, insns;
2041   int op1_type = REAL_TYPE;
2042   tree fndecl = get_callee_fndecl (exp);
2043   tree arg0, arg1;
2044   enum machine_mode mode;
2045   bool errno_set = true;
2046
2047   switch (DECL_FUNCTION_CODE (fndecl))
2048     {
2049     CASE_FLT_FN (BUILT_IN_SCALBN):
2050     CASE_FLT_FN (BUILT_IN_SCALBLN):
2051     CASE_FLT_FN (BUILT_IN_LDEXP):
2052       op1_type = INTEGER_TYPE;
2053     default:
2054       break;
2055     }
2056
2057   if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
2058     return NULL_RTX;
2059
2060   arg0 = CALL_EXPR_ARG (exp, 0);
2061   arg1 = CALL_EXPR_ARG (exp, 1);
2062
2063   switch (DECL_FUNCTION_CODE (fndecl))
2064     {
2065     CASE_FLT_FN (BUILT_IN_POW):
2066       builtin_optab = pow_optab; break;
2067     CASE_FLT_FN (BUILT_IN_ATAN2):
2068       builtin_optab = atan2_optab; break;
2069     CASE_FLT_FN (BUILT_IN_SCALB):
2070       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2071         return 0;
2072       builtin_optab = scalb_optab; break;
2073     CASE_FLT_FN (BUILT_IN_SCALBN):
2074     CASE_FLT_FN (BUILT_IN_SCALBLN):
2075       if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
2076         return 0;
2077     /* Fall through... */
2078     CASE_FLT_FN (BUILT_IN_LDEXP):
2079       builtin_optab = ldexp_optab; break;
2080     CASE_FLT_FN (BUILT_IN_FMOD):
2081       builtin_optab = fmod_optab; break;
2082     CASE_FLT_FN (BUILT_IN_REMAINDER):
2083     CASE_FLT_FN (BUILT_IN_DREM):
2084       builtin_optab = remainder_optab; break;
2085     default:
2086       gcc_unreachable ();
2087     }
2088
2089   /* Make a suitable register to place result in.  */
2090   mode = TYPE_MODE (TREE_TYPE (exp));
2091
2092   /* Before working hard, check whether the instruction is available.  */
2093   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2094     return NULL_RTX;
2095
2096   target = gen_reg_rtx (mode);
2097
2098   if (! flag_errno_math || ! HONOR_NANS (mode))
2099     errno_set = false;
2100
2101   /* Always stabilize the argument list.  */
2102   CALL_EXPR_ARG (exp, 0) = arg0 = builtin_save_expr (arg0);
2103   CALL_EXPR_ARG (exp, 1) = arg1 = builtin_save_expr (arg1);
2104
2105   op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2106   op1 = expand_normal (arg1);
2107
2108   start_sequence ();
2109
2110   /* Compute into TARGET.
2111      Set TARGET to wherever the result comes back.  */
2112   target = expand_binop (mode, builtin_optab, op0, op1,
2113                          target, 0, OPTAB_DIRECT);
2114
2115   /* If we were unable to expand via the builtin, stop the sequence
2116      (without outputting the insns) and call to the library function
2117      with the stabilized argument list.  */
2118   if (target == 0)
2119     {
2120       end_sequence ();
2121       return expand_call (exp, target, target == const0_rtx);
2122     }
2123
2124   if (errno_set)
2125     expand_errno_check (exp, target);
2126
2127   /* Output the entire sequence.  */
2128   insns = get_insns ();
2129   end_sequence ();
2130   emit_insn (insns);
2131
2132   return target;
2133 }
2134
2135 /* Expand a call to the builtin sin and cos math functions.
2136    Return NULL_RTX if a normal call should be emitted rather than expanding the
2137    function in-line.  EXP is the expression that is a call to the builtin
2138    function; if convenient, the result should be placed in TARGET.
2139    SUBTARGET may be used as the target for computing one of EXP's
2140    operands.  */
2141
2142 static rtx
2143 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
2144 {
2145   optab builtin_optab;
2146   rtx op0, insns;
2147   tree fndecl = get_callee_fndecl (exp);
2148   enum machine_mode mode;
2149   tree arg;
2150
2151   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2152     return NULL_RTX;
2153
2154   arg = CALL_EXPR_ARG (exp, 0);
2155
2156   switch (DECL_FUNCTION_CODE (fndecl))
2157     {
2158     CASE_FLT_FN (BUILT_IN_SIN):
2159     CASE_FLT_FN (BUILT_IN_COS):
2160       builtin_optab = sincos_optab; break;
2161     default:
2162       gcc_unreachable ();
2163     }
2164
2165   /* Make a suitable register to place result in.  */
2166   mode = TYPE_MODE (TREE_TYPE (exp));
2167
2168   /* Check if sincos insn is available, otherwise fallback
2169      to sin or cos insn.  */
2170   if (optab_handler (builtin_optab, mode)->insn_code == CODE_FOR_nothing)
2171     switch (DECL_FUNCTION_CODE (fndecl))
2172       {
2173       CASE_FLT_FN (BUILT_IN_SIN):
2174         builtin_optab = sin_optab; break;
2175       CASE_FLT_FN (BUILT_IN_COS):
2176         builtin_optab = cos_optab; break;
2177       default:
2178         gcc_unreachable ();
2179       }
2180
2181   /* Before working hard, check whether the instruction is available.  */
2182   if (optab_handler (builtin_optab, mode)->insn_code != CODE_FOR_nothing)
2183     {
2184       target = gen_reg_rtx (mode);
2185
2186       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2187          need to expand the argument again.  This way, we will not perform
2188          side-effects more the once.  */
2189       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2190
2191       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2192
2193       start_sequence ();
2194
2195       /* Compute into TARGET.
2196          Set TARGET to wherever the result comes back.  */
2197       if (builtin_optab == sincos_optab)
2198         {
2199           int result;
2200
2201           switch (DECL_FUNCTION_CODE (fndecl))
2202             {
2203             CASE_FLT_FN (BUILT_IN_SIN):
2204               result = expand_twoval_unop (builtin_optab, op0, 0, target, 0);
2205               break;
2206             CASE_FLT_FN (BUILT_IN_COS):
2207               result = expand_twoval_unop (builtin_optab, op0, target, 0, 0);
2208               break;
2209             default:
2210               gcc_unreachable ();
2211             }
2212           gcc_assert (result);
2213         }
2214       else
2215         {
2216           target = expand_unop (mode, builtin_optab, op0, target, 0);
2217         }
2218
2219       if (target != 0)
2220         {
2221           /* Output the entire sequence.  */
2222           insns = get_insns ();
2223           end_sequence ();
2224           emit_insn (insns);
2225           return target;
2226         }
2227
2228       /* If we were unable to expand via the builtin, stop the sequence
2229          (without outputting the insns) and call to the library function
2230          with the stabilized argument list.  */
2231       end_sequence ();
2232     }
2233
2234   target = expand_call (exp, target, target == const0_rtx);
2235
2236   return target;
2237 }
2238
2239 /* Given an interclass math builtin decl FNDECL and it's argument ARG
2240    return an RTL instruction code that implements the functionality.
2241    If that isn't possible or available return CODE_FOR_nothing.  */
2242
2243 static enum insn_code
2244 interclass_mathfn_icode (tree arg, tree fndecl)
2245 {
2246   bool errno_set = false;
2247   optab builtin_optab = 0;
2248   enum machine_mode mode;
2249
2250   switch (DECL_FUNCTION_CODE (fndecl))
2251     {
2252     CASE_FLT_FN (BUILT_IN_ILOGB):
2253       errno_set = true; builtin_optab = ilogb_optab; break;
2254     CASE_FLT_FN (BUILT_IN_ISINF):
2255       builtin_optab = isinf_optab; break;
2256     case BUILT_IN_ISNORMAL:
2257     case BUILT_IN_ISFINITE:
2258     CASE_FLT_FN (BUILT_IN_FINITE):
2259     case BUILT_IN_FINITED32:
2260     case BUILT_IN_FINITED64:
2261     case BUILT_IN_FINITED128:
2262     case BUILT_IN_ISINFD32:
2263     case BUILT_IN_ISINFD64:
2264     case BUILT_IN_ISINFD128:
2265       /* These builtins have no optabs (yet).  */
2266       break;
2267     default:
2268       gcc_unreachable ();
2269     }
2270
2271   /* There's no easy way to detect the case we need to set EDOM.  */
2272   if (flag_errno_math && errno_set)
2273     return CODE_FOR_nothing;
2274
2275   /* Optab mode depends on the mode of the input argument.  */
2276   mode = TYPE_MODE (TREE_TYPE (arg));
2277
2278   if (builtin_optab)
2279     return optab_handler (builtin_optab, mode)->insn_code;
2280   return CODE_FOR_nothing;
2281 }
2282
2283 /* Expand a call to one of the builtin math functions that operate on
2284    floating point argument and output an integer result (ilogb, isinf,
2285    isnan, etc).
2286    Return 0 if a normal call should be emitted rather than expanding the
2287    function in-line.  EXP is the expression that is a call to the builtin
2288    function; if convenient, the result should be placed in TARGET.
2289    SUBTARGET may be used as the target for computing one of EXP's operands.  */
2290
2291 static rtx
2292 expand_builtin_interclass_mathfn (tree exp, rtx target, rtx subtarget)
2293 {
2294   enum insn_code icode = CODE_FOR_nothing;
2295   rtx op0;
2296   tree fndecl = get_callee_fndecl (exp);
2297   enum machine_mode mode;
2298   tree arg;
2299
2300   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2301     return NULL_RTX;
2302
2303   arg = CALL_EXPR_ARG (exp, 0);
2304   icode = interclass_mathfn_icode (arg, fndecl);
2305   mode = TYPE_MODE (TREE_TYPE (arg));
2306
2307   if (icode != CODE_FOR_nothing)
2308     {
2309       /* Make a suitable register to place result in.  */
2310       if (!target
2311           || GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
2312          target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
2313
2314       gcc_assert (insn_data[icode].operand[0].predicate
2315                   (target, GET_MODE (target)));
2316
2317       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2318          need to expand the argument again.  This way, we will not perform
2319          side-effects more the once.  */
2320       CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2321
2322       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2323
2324       if (mode != GET_MODE (op0))
2325         op0 = convert_to_mode (mode, op0, 0);
2326
2327       /* Compute into TARGET.
2328          Set TARGET to wherever the result comes back.  */
2329       emit_unop_insn (icode, target, op0, UNKNOWN);
2330       return target;
2331     }
2332
2333   return NULL_RTX;
2334 }
2335
2336 /* Expand a call to the builtin sincos math function.
2337    Return NULL_RTX if a normal call should be emitted rather than expanding the
2338    function in-line.  EXP is the expression that is a call to the builtin
2339    function.  */
2340
2341 static rtx
2342 expand_builtin_sincos (tree exp)
2343 {
2344   rtx op0, op1, op2, target1, target2;
2345   enum machine_mode mode;
2346   tree arg, sinp, cosp;
2347   int result;
2348   location_t loc = EXPR_LOCATION (exp);
2349
2350   if (!validate_arglist (exp, REAL_TYPE,
2351                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2352     return NULL_RTX;
2353
2354   arg = CALL_EXPR_ARG (exp, 0);
2355   sinp = CALL_EXPR_ARG (exp, 1);
2356   cosp = CALL_EXPR_ARG (exp, 2);
2357
2358   /* Make a suitable register to place result in.  */
2359   mode = TYPE_MODE (TREE_TYPE (arg));
2360
2361   /* Check if sincos insn is available, otherwise emit the call.  */
2362   if (optab_handler (sincos_optab, mode)->insn_code == CODE_FOR_nothing)
2363     return NULL_RTX;
2364
2365   target1 = gen_reg_rtx (mode);
2366   target2 = gen_reg_rtx (mode);
2367
2368   op0 = expand_normal (arg);
2369   op1 = expand_normal (build_fold_indirect_ref_loc (loc, sinp));
2370   op2 = expand_normal (build_fold_indirect_ref_loc (loc, cosp));
2371
2372   /* Compute into target1 and target2.
2373      Set TARGET to wherever the result comes back.  */
2374   result = expand_twoval_unop (sincos_optab, op0, target2, target1, 0);
2375   gcc_assert (result);
2376
2377   /* Move target1 and target2 to the memory locations indicated
2378      by op1 and op2.  */
2379   emit_move_insn (op1, target1);
2380   emit_move_insn (op2, target2);
2381
2382   return const0_rtx;
2383 }
2384
2385 /* Expand a call to the internal cexpi builtin to the sincos math function.
2386    EXP is the expression that is a call to the builtin function; if convenient,
2387    the result should be placed in TARGET.  SUBTARGET may be used as the target
2388    for computing one of EXP's operands.  */
2389
2390 static rtx
2391 expand_builtin_cexpi (tree exp, rtx target, rtx subtarget)
2392 {
2393   tree fndecl = get_callee_fndecl (exp);
2394   tree arg, type;
2395   enum machine_mode mode;
2396   rtx op0, op1, op2;
2397   location_t loc = EXPR_LOCATION (exp);
2398
2399   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2400     return NULL_RTX;
2401
2402   arg = CALL_EXPR_ARG (exp, 0);
2403   type = TREE_TYPE (arg);
2404   mode = TYPE_MODE (TREE_TYPE (arg));
2405
2406   /* Try expanding via a sincos optab, fall back to emitting a libcall
2407      to sincos or cexp.  We are sure we have sincos or cexp because cexpi
2408      is only generated from sincos, cexp or if we have either of them.  */
2409   if (optab_handler (sincos_optab, mode)->insn_code != CODE_FOR_nothing)
2410     {
2411       op1 = gen_reg_rtx (mode);
2412       op2 = gen_reg_rtx (mode);
2413
2414       op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
2415
2416       /* Compute into op1 and op2.  */
2417       expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
2418     }
2419   else if (TARGET_HAS_SINCOS)
2420     {
2421       tree call, fn = NULL_TREE;
2422       tree top1, top2;
2423       rtx op1a, op2a;
2424
2425       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2426         fn = built_in_decls[BUILT_IN_SINCOSF];
2427       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2428         fn = built_in_decls[BUILT_IN_SINCOS];
2429       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2430         fn = built_in_decls[BUILT_IN_SINCOSL];
2431       else
2432         gcc_unreachable ();
2433  
2434       op1 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2435       op2 = assign_temp (TREE_TYPE (arg), 0, 1, 1);
2436       op1a = copy_to_mode_reg (Pmode, XEXP (op1, 0));
2437       op2a = copy_to_mode_reg (Pmode, XEXP (op2, 0));
2438       top1 = make_tree (build_pointer_type (TREE_TYPE (arg)), op1a);
2439       top2 = make_tree (build_pointer_type (TREE_TYPE (arg)), op2a);
2440
2441       /* Make sure not to fold the sincos call again.  */
2442       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2443       expand_normal (build_call_nary (TREE_TYPE (TREE_TYPE (fn)),
2444                                       call, 3, arg, top1, top2));
2445     }
2446   else
2447     {
2448       tree call, fn = NULL_TREE, narg;
2449       tree ctype = build_complex_type (type);
2450
2451       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2452         fn = built_in_decls[BUILT_IN_CEXPF];
2453       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2454         fn = built_in_decls[BUILT_IN_CEXP];
2455       else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2456         fn = built_in_decls[BUILT_IN_CEXPL];
2457       else
2458         gcc_unreachable ();
2459
2460       /* If we don't have a decl for cexp create one.  This is the
2461          friendliest fallback if the user calls __builtin_cexpi
2462          without full target C99 function support.  */
2463       if (fn == NULL_TREE)
2464         {
2465           tree fntype;
2466           const char *name = NULL;
2467
2468           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIF)
2469             name = "cexpf";
2470           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPI)
2471             name = "cexp";
2472           else if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CEXPIL)
2473             name = "cexpl";
2474
2475           fntype = build_function_type_list (ctype, ctype, NULL_TREE);
2476           fn = build_fn_decl (name, fntype);
2477         }
2478
2479       narg = fold_build2_loc (loc, COMPLEX_EXPR, ctype,
2480                           build_real (type, dconst0), arg);
2481
2482       /* Make sure not to fold the cexp call again.  */
2483       call = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
2484       return expand_expr (build_call_nary (ctype, call, 1, narg), 
2485                           target, VOIDmode, EXPAND_NORMAL);
2486     }
2487
2488   /* Now build the proper return type.  */
2489   return expand_expr (build2 (COMPLEX_EXPR, build_complex_type (type),
2490                               make_tree (TREE_TYPE (arg), op2),
2491                               make_tree (TREE_TYPE (arg), op1)),
2492                       target, VOIDmode, EXPAND_NORMAL);
2493 }
2494
2495 /* Conveniently construct a function call expression.  FNDECL names the
2496    function to be called, N is the number of arguments, and the "..."
2497    parameters are the argument expressions.  Unlike build_call_exr
2498    this doesn't fold the call, hence it will always return a CALL_EXPR.  */
2499
2500 static tree
2501 build_call_nofold_loc (location_t loc, tree fndecl, int n, ...)
2502 {
2503   va_list ap;
2504   tree fntype = TREE_TYPE (fndecl);
2505   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
2506
2507   va_start (ap, n);
2508   fn = build_call_valist (TREE_TYPE (fntype), fn, n, ap);
2509   va_end (ap);
2510   SET_EXPR_LOCATION (fn, loc);
2511   return fn;
2512 }
2513 #define build_call_nofold(...) \
2514   build_call_nofold_loc (UNKNOWN_LOCATION, __VA_ARGS__)
2515
2516 /* Expand a call to one of the builtin rounding functions gcc defines
2517    as an extension (lfloor and lceil).  As these are gcc extensions we
2518    do not need to worry about setting errno to EDOM.
2519    If expanding via optab fails, lower expression to (int)(floor(x)).
2520    EXP is the expression that is a call to the builtin function;
2521    if convenient, the result should be placed in TARGET.  */
2522
2523 static rtx
2524 expand_builtin_int_roundingfn (tree exp, rtx target)
2525 {
2526   convert_optab builtin_optab;
2527   rtx op0, insns, tmp;
2528   tree fndecl = get_callee_fndecl (exp);
2529   enum built_in_function fallback_fn;
2530   tree fallback_fndecl;
2531   enum machine_mode mode;
2532   tree arg;
2533
2534   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2535     gcc_unreachable ();
2536
2537   arg = CALL_EXPR_ARG (exp, 0);
2538
2539   switch (DECL_FUNCTION_CODE (fndecl))
2540     {
2541     CASE_FLT_FN (BUILT_IN_LCEIL):
2542     CASE_FLT_FN (BUILT_IN_LLCEIL):
2543       builtin_optab = lceil_optab;
2544       fallback_fn = BUILT_IN_CEIL;
2545       break;
2546
2547     CASE_FLT_FN (BUILT_IN_LFLOOR):
2548     CASE_FLT_FN (BUILT_IN_LLFLOOR):
2549       builtin_optab = lfloor_optab;
2550       fallback_fn = BUILT_IN_FLOOR;
2551       break;
2552
2553     default:
2554       gcc_unreachable ();
2555     }
2556
2557   /* Make a suitable register to place result in.  */
2558   mode = TYPE_MODE (TREE_TYPE (exp));
2559
2560   target = gen_reg_rtx (mode);
2561
2562   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2563      need to expand the argument again.  This way, we will not perform
2564      side-effects more the once.  */
2565   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2566
2567   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2568
2569   start_sequence ();
2570
2571   /* Compute into TARGET.  */
2572   if (expand_sfix_optab (target, op0, builtin_optab))
2573     {
2574       /* Output the entire sequence.  */
2575       insns = get_insns ();
2576       end_sequence ();
2577       emit_insn (insns);
2578       return target;
2579     }
2580
2581   /* If we were unable to expand via the builtin, stop the sequence
2582      (without outputting the insns).  */
2583   end_sequence ();
2584
2585   /* Fall back to floating point rounding optab.  */
2586   fallback_fndecl = mathfn_built_in (TREE_TYPE (arg), fallback_fn);
2587
2588   /* For non-C99 targets we may end up without a fallback fndecl here
2589      if the user called __builtin_lfloor directly.  In this case emit
2590      a call to the floor/ceil variants nevertheless.  This should result
2591      in the best user experience for not full C99 targets.  */
2592   if (fallback_fndecl == NULL_TREE)
2593     {
2594       tree fntype;
2595       const char *name = NULL;
2596
2597       switch (DECL_FUNCTION_CODE (fndecl))
2598         {
2599         case BUILT_IN_LCEIL:
2600         case BUILT_IN_LLCEIL:
2601           name = "ceil";
2602           break;
2603         case BUILT_IN_LCEILF:
2604         case BUILT_IN_LLCEILF:
2605           name = "ceilf";
2606           break;
2607         case BUILT_IN_LCEILL:
2608         case BUILT_IN_LLCEILL:
2609           name = "ceill";
2610           break;
2611         case BUILT_IN_LFLOOR:
2612         case BUILT_IN_LLFLOOR:
2613           name = "floor";
2614           break;
2615         case BUILT_IN_LFLOORF:
2616         case BUILT_IN_LLFLOORF:
2617           name = "floorf";
2618           break;
2619         case BUILT_IN_LFLOORL:
2620         case BUILT_IN_LLFLOORL:
2621           name = "floorl";
2622           break;
2623         default:
2624           gcc_unreachable ();
2625         }
2626
2627       fntype = build_function_type_list (TREE_TYPE (arg),
2628                                          TREE_TYPE (arg), NULL_TREE);
2629       fallback_fndecl = build_fn_decl (name, fntype);
2630     }
2631
2632   exp = build_call_nofold (fallback_fndecl, 1, arg);
2633
2634   tmp = expand_normal (exp);
2635
2636   /* Truncate the result of floating point optab to integer
2637      via expand_fix ().  */
2638   target = gen_reg_rtx (mode);
2639   expand_fix (target, tmp, 0);
2640
2641   return target;
2642 }
2643
2644 /* Expand a call to one of the builtin math functions doing integer
2645    conversion (lrint).
2646    Return 0 if a normal call should be emitted rather than expanding the
2647    function in-line.  EXP is the expression that is a call to the builtin
2648    function; if convenient, the result should be placed in TARGET.  */
2649
2650 static rtx
2651 expand_builtin_int_roundingfn_2 (tree exp, rtx target)
2652 {
2653   convert_optab builtin_optab;
2654   rtx op0, insns;
2655   tree fndecl = get_callee_fndecl (exp);
2656   tree arg;
2657   enum machine_mode mode;
2658
2659   /* There's no easy way to detect the case we need to set EDOM.  */
2660   if (flag_errno_math)
2661     return NULL_RTX;
2662
2663   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
2664      gcc_unreachable ();
2665  
2666   arg = CALL_EXPR_ARG (exp, 0);
2667
2668   switch (DECL_FUNCTION_CODE (fndecl))
2669     {
2670     CASE_FLT_FN (BUILT_IN_LRINT):
2671     CASE_FLT_FN (BUILT_IN_LLRINT):
2672       builtin_optab = lrint_optab; break;
2673     CASE_FLT_FN (BUILT_IN_LROUND):
2674     CASE_FLT_FN (BUILT_IN_LLROUND):
2675       builtin_optab = lround_optab; break;
2676     default:
2677       gcc_unreachable ();
2678     }
2679
2680   /* Make a suitable register to place result in.  */
2681   mode = TYPE_MODE (TREE_TYPE (exp));
2682
2683   target = gen_reg_rtx (mode);
2684
2685   /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2686      need to expand the argument again.  This way, we will not perform
2687      side-effects more the once.  */
2688   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
2689
2690   op0 = expand_expr (arg, NULL, VOIDmode, EXPAND_NORMAL);
2691
2692   start_sequence ();
2693
2694   if (expand_sfix_optab (target, op0, builtin_optab))
2695     {
2696       /* Output the entire sequence.  */
2697       insns = get_insns ();
2698       end_sequence ();
2699       emit_insn (insns);
2700       return target;
2701     }
2702
2703   /* If we were unable to expand via the builtin, stop the sequence
2704      (without outputting the insns) and call to the library function
2705      with the stabilized argument list.  */
2706   end_sequence ();
2707
2708   target = expand_call (exp, target, target == const0_rtx);
2709
2710   return target;
2711 }
2712
2713 /* To evaluate powi(x,n), the floating point value x raised to the
2714    constant integer exponent n, we use a hybrid algorithm that
2715    combines the "window method" with look-up tables.  For an
2716    introduction to exponentiation algorithms and "addition chains",
2717    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2718    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2719    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2720    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2721
2722 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2723    multiplications to inline before calling the system library's pow
2724    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2725    so this default never requires calling pow, powf or powl.  */
2726
2727 #ifndef POWI_MAX_MULTS
2728 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2729 #endif
2730
2731 /* The size of the "optimal power tree" lookup table.  All
2732    exponents less than this value are simply looked up in the
2733    powi_table below.  This threshold is also used to size the
2734    cache of pseudo registers that hold intermediate results.  */
2735 #define POWI_TABLE_SIZE 256
2736
2737 /* The size, in bits of the window, used in the "window method"
2738    exponentiation algorithm.  This is equivalent to a radix of
2739    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2740 #define POWI_WINDOW_SIZE 3
2741
2742 /* The following table is an efficient representation of an
2743    "optimal power tree".  For each value, i, the corresponding
2744    value, j, in the table states than an optimal evaluation
2745    sequence for calculating pow(x,i) can be found by evaluating
2746    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2747    100 integers is given in Knuth's "Seminumerical algorithms".  */
2748
2749 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2750   {
2751       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2752       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2753       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2754      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2755      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2756      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2757      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2758      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2759      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2760      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2761      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2762      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2763      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2764      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2765      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2766      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2767      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2768      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2769      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2770      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2771      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2772      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2773      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2774      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2775      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2776     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2777     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2778     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2779     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2780     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2781     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2782     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2783   };
2784
2785
2786 /* Return the number of multiplications required to calculate
2787    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2788    subroutine of powi_cost.  CACHE is an array indicating
2789    which exponents have already been calculated.  */
2790
2791 static int
2792 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2793 {
2794   /* If we've already calculated this exponent, then this evaluation
2795      doesn't require any additional multiplications.  */
2796   if (cache[n])
2797     return 0;
2798
2799   cache[n] = true;
2800   return powi_lookup_cost (n - powi_table[n], cache)
2801          + powi_lookup_cost (powi_table[n], cache) + 1;
2802 }
2803
2804 /* Return the number of multiplications required to calculate
2805    powi(x,n) for an arbitrary x, given the exponent N.  This
2806    function needs to be kept in sync with expand_powi below.  */
2807
2808 static int
2809 powi_cost (HOST_WIDE_INT n)
2810 {
2811   bool cache[POWI_TABLE_SIZE];
2812   unsigned HOST_WIDE_INT digit;
2813   unsigned HOST_WIDE_INT val;
2814   int result;
2815
2816   if (n == 0)
2817     return 0;
2818
2819   /* Ignore the reciprocal when calculating the cost.  */
2820   val = (n < 0) ? -n : n;
2821
2822   /* Initialize the exponent cache.  */
2823   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2824   cache[1] = true;
2825
2826   result = 0;
2827
2828   while (val >= POWI_TABLE_SIZE)
2829     {
2830       if (val & 1)
2831         {
2832           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2833           result += powi_lookup_cost (digit, cache)
2834                     + POWI_WINDOW_SIZE + 1;
2835           val >>= POWI_WINDOW_SIZE;
2836         }
2837       else
2838         {
2839           val >>= 1;
2840           result++;
2841         }
2842     }
2843
2844   return result + powi_lookup_cost (val, cache);
2845 }
2846
2847 /* Recursive subroutine of expand_powi.  This function takes the array,
2848    CACHE, of already calculated exponents and an exponent N and returns
2849    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2850
2851 static rtx
2852 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2853 {
2854   unsigned HOST_WIDE_INT digit;
2855   rtx target, result;
2856   rtx op0, op1;
2857
2858   if (n < POWI_TABLE_SIZE)
2859     {
2860       if (cache[n])
2861         return cache[n];
2862
2863       target = gen_reg_rtx (mode);
2864       cache[n] = target;
2865
2866       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2867       op1 = expand_powi_1 (mode, powi_table[n], cache);
2868     }
2869   else if (n & 1)
2870     {
2871       target = gen_reg_rtx (mode);
2872       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2873       op0 = expand_powi_1 (mode, n - digit, cache);
2874       op1 = expand_powi_1 (mode, digit, cache);
2875     }
2876   else
2877     {
2878       target = gen_reg_rtx (mode);
2879       op0 = expand_powi_1 (mode, n >> 1, cache);
2880       op1 = op0;
2881     }
2882
2883   result = expand_mult (mode, op0, op1, target, 0);
2884   if (result != target)
2885     emit_move_insn (target, result);
2886   return target;
2887 }
2888
2889 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2890    floating point operand in mode MODE, and N is the exponent.  This
2891    function needs to be kept in sync with powi_cost above.  */
2892
2893 static rtx
2894 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2895 {
2896   rtx cache[POWI_TABLE_SIZE];
2897   rtx result;
2898
2899   if (n == 0)
2900     return CONST1_RTX (mode);
2901
2902   memset (cache, 0, sizeof (cache));
2903   cache[1] = x;
2904
2905   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2906
2907   /* If the original exponent was negative, reciprocate the result.  */
2908   if (n < 0)
2909     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2910                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2911
2912   return result;
2913 }
2914
2915 /* Expand a call to the pow built-in mathematical function.  Return NULL_RTX if
2916    a normal call should be emitted rather than expanding the function
2917    in-line.  EXP is the expression that is a call to the builtin
2918    function; if convenient, the result should be placed in TARGET.  */
2919
2920 static rtx
2921 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2922 {
2923   tree arg0, arg1;
2924   tree fn, narg0;
2925   tree type = TREE_TYPE (exp);
2926   REAL_VALUE_TYPE cint, c, c2;
2927   HOST_WIDE_INT n;
2928   rtx op, op2;
2929   enum machine_mode mode = TYPE_MODE (type);
2930
2931   if (! validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2932     return NULL_RTX;
2933
2934   arg0 = CALL_EXPR_ARG (exp, 0);
2935   arg1 = CALL_EXPR_ARG (exp, 1);
2936
2937   if (TREE_CODE (arg1) != REAL_CST
2938       || TREE_OVERFLOW (arg1))
2939     return expand_builtin_mathfn_2 (exp, target, subtarget);
2940
2941   /* Handle constant exponents.  */
2942
2943   /* For integer valued exponents we can expand to an optimal multiplication
2944      sequence using expand_powi.  */
2945   c = TREE_REAL_CST (arg1);
2946   n = real_to_integer (&c);
2947   real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2948   if (real_identical (&c, &cint)
2949       && ((n >= -1 && n <= 2)
2950           || (flag_unsafe_math_optimizations
2951               && optimize_insn_for_speed_p ()
2952               && powi_cost (n) <= POWI_MAX_MULTS)))
2953     {
2954       op = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
2955       if (n != 1)
2956         {
2957           op = force_reg (mode, op);
2958           op = expand_powi (op, mode, n);
2959         }
2960       return op;
2961     }
2962
2963   narg0 = builtin_save_expr (arg0);
2964
2965   /* If the exponent is not integer valued, check if it is half of an integer.
2966      In this case we can expand to sqrt (x) * x**(n/2).  */
2967   fn = mathfn_built_in (type, BUILT_IN_SQRT);
2968   if (fn != NULL_TREE)
2969     {
2970       real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2971       n = real_to_integer (&c2);
2972       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2973       if (real_identical (&c2, &cint)
2974           && ((flag_unsafe_math_optimizations
2975                && optimize_insn_for_speed_p ()
2976                && powi_cost (n/2) <= POWI_MAX_MULTS)
2977               || n == 1))
2978         {
2979           tree call_expr = build_call_nofold (fn, 1, narg0);
2980           /* Use expand_expr in case the newly built call expression
2981              was folded to a non-call.  */
2982           op = expand_expr (call_expr, subtarget, mode, EXPAND_NORMAL);
2983           if (n != 1)
2984             {
2985               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
2986               op2 = force_reg (mode, op2);
2987               op2 = expand_powi (op2, mode, abs (n / 2));
2988               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
2989                                         0, OPTAB_LIB_WIDEN);
2990               /* If the original exponent was negative, reciprocate the
2991                  result.  */
2992               if (n < 0)
2993                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2994                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2995             }
2996           return op;
2997         }
2998     }
2999
3000   /* Try if the exponent is a third of an integer.  In this case
3001      we can expand to x**(n/3) * cbrt(x)**(n%3).  As cbrt (x) is
3002      different from pow (x, 1./3.) due to rounding and behavior
3003      with negative x we need to constrain this transformation to
3004      unsafe math and positive x or finite math.  */
3005   fn = mathfn_built_in (type, BUILT_IN_CBRT);
3006   if (fn != NULL_TREE
3007       && flag_unsafe_math_optimizations
3008       && (tree_expr_nonnegative_p (arg0)
3009           || !HONOR_NANS (mode)))
3010     {
3011       REAL_VALUE_TYPE dconst3;
3012       real_from_integer (&dconst3, VOIDmode, 3, 0, 0);
3013       real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
3014       real_round (&c2, mode, &c2);
3015       n = real_to_integer (&c2);
3016       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
3017       real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
3018       real_convert (&c2, mode, &c2);
3019       if (real_identical (&c2, &c)
3020           && ((optimize_insn_for_speed_p ()
3021                && powi_cost (n/3) <= POWI_MAX_MULTS)
3022               || n == 1))
3023         {
3024           tree call_expr = build_call_nofold (fn, 1,narg0);
3025           op = expand_builtin (call_expr, NULL_RTX, subtarget, mode, 0);
3026           if (abs (n) % 3 == 2)
3027             op = expand_simple_binop (mode, MULT, op, op, op,
3028                                       0, OPTAB_LIB_WIDEN);
3029           if (n != 1)
3030             {
3031               op2 = expand_expr (narg0, subtarget, VOIDmode, EXPAND_NORMAL);
3032               op2 = force_reg (mode, op2);
3033               op2 = expand_powi (op2, mode, abs (n / 3));
3034               op = expand_simple_binop (mode, MULT, op, op2, NULL_RTX,
3035                                         0, OPTAB_LIB_WIDEN);
3036               /* If the original exponent was negative, reciprocate the
3037                  result.  */
3038               if (n < 0)
3039                 op = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
3040                                    op, NULL_RTX, 0, OPTAB_LIB_WIDEN);
3041             }
3042           return op;
3043         }
3044     }
3045
3046   /* Fall back to optab expansion.  */
3047   return expand_builtin_mathfn_2 (exp, target, subtarget);
3048 }
3049
3050 /* Expand a call to the powi built-in mathematical function.  Return NULL_RTX if
3051    a normal call should be emitted rather than expanding the function
3052    in-line.  EXP is the expression that is a call to the builtin
3053    function; if convenient, the result should be placed in TARGET.  */
3054
3055 static rtx
3056 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
3057 {
3058   tree arg0, arg1;
3059   rtx op0, op1;
3060   enum machine_mode mode;
3061   enum machine_mode mode2;
3062
3063   if (! validate_arglist (exp, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
3064     return NULL_RTX;
3065
3066   arg0 = CALL_EXPR_ARG (exp, 0);
3067   arg1 = CALL_EXPR_ARG (exp, 1);
3068   mode = TYPE_MODE (TREE_TYPE (exp));
3069
3070   /* Handle constant power.  */
3071
3072   if (TREE_CODE (arg1) == INTEGER_CST
3073       && !TREE_OVERFLOW (arg1))
3074     {
3075       HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
3076
3077       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
3078          Otherwise, check the number of multiplications required.  */
3079       if ((TREE_INT_CST_HIGH (arg1) == 0
3080            || TREE_INT_CST_HIGH (arg1) == -1)
3081           && ((n >= -1 && n <= 2)
3082               || (optimize_insn_for_speed_p ()
3083                   && powi_cost (n) <= POWI_MAX_MULTS)))
3084         {
3085           op0 = expand_expr (arg0, subtarget, VOIDmode, EXPAND_NORMAL);
3086           op0 = force_reg (mode, op0);
3087           return expand_powi (op0, mode, n);
3088         }
3089     }
3090
3091   /* Emit a libcall to libgcc.  */
3092
3093   /* Mode of the 2nd argument must match that of an int.  */
3094   mode2 = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
3095
3096   if (target == NULL_RTX)
3097     target = gen_reg_rtx (mode);
3098
3099   op0 = expand_expr (arg0, subtarget, mode, EXPAND_NORMAL);
3100   if (GET_MODE (op0) != mode)
3101     op0 = convert_to_mode (mode, op0, 0);
3102   op1 = expand_expr (arg1, NULL_RTX, mode2, EXPAND_NORMAL);
3103   if (GET_MODE (op1) != mode2)
3104     op1 = convert_to_mode (mode2, op1, 0);
3105
3106   target = emit_library_call_value (optab_libfunc (powi_optab, mode),
3107                                     target, LCT_CONST, mode, 2,
3108                                     op0, mode, op1, mode2);
3109
3110   return target;
3111 }
3112
3113 /* Expand expression EXP which is a call to the strlen builtin.  Return 
3114    NULL_RTX if we failed the caller should emit a normal call, otherwise
3115    try to get the result in TARGET, if convenient.  */
3116
3117 static rtx
3118 expand_builtin_strlen (tree exp, rtx target,
3119                        enum machine_mode target_mode)
3120 {
3121   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
3122     return NULL_RTX;
3123   else
3124     {
3125       rtx pat;
3126       tree len;
3127       tree src = CALL_EXPR_ARG (exp, 0);
3128       rtx result, src_reg, char_rtx, before_strlen;
3129       enum machine_mode insn_mode = target_mode, char_mode;
3130       enum insn_code icode = CODE_FOR_nothing;
3131       int align;
3132
3133       /* If the length can be computed at compile-time, return it.  */
3134       len = c_strlen (src, 0);
3135       if (len)
3136         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3137
3138       /* If the length can be computed at compile-time and is constant
3139          integer, but there are side-effects in src, evaluate
3140          src for side-effects, then return len.
3141          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
3142          can be optimized into: i++; x = 3;  */
3143       len = c_strlen (src, 1);
3144       if (len && TREE_CODE (len) == INTEGER_CST)
3145         {
3146           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3147           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
3148         }
3149
3150       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3151
3152       /* If SRC is not a pointer type, don't do this operation inline.  */
3153       if (align == 0)
3154         return NULL_RTX;
3155
3156       /* Bail out if we can't compute strlen in the right mode.  */
3157       while (insn_mode != VOIDmode)
3158         {
3159           icode = optab_handler (strlen_optab, insn_mode)->insn_code;
3160           if (icode != CODE_FOR_nothing)
3161             break;
3162
3163           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
3164         }
3165       if (insn_mode == VOIDmode)
3166         return NULL_RTX;
3167
3168       /* Make a place to write the result of the instruction.  */
3169       result = target;
3170       if (! (result != 0
3171              && REG_P (result)
3172              && GET_MODE (result) == insn_mode
3173              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3174         result = gen_reg_rtx (insn_mode);
3175
3176       /* Make a place to hold the source address.  We will not expand
3177          the actual source until we are sure that the expansion will
3178          not fail -- there are trees that cannot be expanded twice.  */
3179       src_reg = gen_reg_rtx (Pmode);
3180
3181       /* Mark the beginning of the strlen sequence so we can emit the
3182          source operand later.  */
3183       before_strlen = get_last_insn ();
3184
3185       char_rtx = const0_rtx;
3186       char_mode = insn_data[(int) icode].operand[2].mode;
3187       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
3188                                                             char_mode))
3189         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
3190
3191       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
3192                              char_rtx, GEN_INT (align));
3193       if (! pat)
3194         return NULL_RTX;
3195       emit_insn (pat);
3196
3197       /* Now that we are assured of success, expand the source.  */
3198       start_sequence ();
3199       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
3200       if (pat != src_reg)
3201         emit_move_insn (src_reg, pat);
3202       pat = get_insns ();
3203       end_sequence ();
3204
3205       if (before_strlen)
3206         emit_insn_after (pat, before_strlen);
3207       else
3208         emit_insn_before (pat, get_insns ());
3209
3210       /* Return the value in the proper mode for this function.  */
3211       if (GET_MODE (result) == target_mode)
3212         target = result;
3213       else if (target != 0)
3214         convert_move (target, result, 0);
3215       else
3216         target = convert_to_mode (target_mode, result, 0);
3217
3218       return target;
3219     }
3220 }
3221
3222 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3223    bytes from constant string DATA + OFFSET and return it as target
3224    constant.  */
3225
3226 static rtx
3227 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
3228                          enum machine_mode mode)
3229 {
3230   const char *str = (const char *) data;
3231
3232   gcc_assert (offset >= 0
3233               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
3234                   <= strlen (str) + 1));
3235
3236   return c_readstr (str + offset, mode);
3237 }
3238
3239 /* Expand a call EXP to the memcpy builtin.
3240    Return NULL_RTX if we failed, the caller should emit a normal call,
3241    otherwise try to get the result in TARGET, if convenient (and in
3242    mode MODE if that's convenient).  */
3243
3244 static rtx
3245 expand_builtin_memcpy (tree exp, rtx target)
3246 {
3247   if (!validate_arglist (exp,
3248                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3249     return NULL_RTX;
3250   else
3251     {
3252       tree dest = CALL_EXPR_ARG (exp, 0);
3253       tree src = CALL_EXPR_ARG (exp, 1);
3254       tree len = CALL_EXPR_ARG (exp, 2);
3255       const char *src_str;
3256       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3257       unsigned int dest_align
3258         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3259       rtx dest_mem, src_mem, dest_addr, len_rtx;
3260       HOST_WIDE_INT expected_size = -1;
3261       unsigned int expected_align = 0;
3262       tree_ann_common_t ann;
3263
3264       /* If DEST is not a pointer type, call the normal function.  */
3265       if (dest_align == 0)
3266         return NULL_RTX;
3267
3268       /* If either SRC is not a pointer type, don't do this
3269          operation in-line.  */
3270       if (src_align == 0)
3271         return NULL_RTX;
3272  
3273       ann = tree_common_ann (exp);
3274       if (ann)
3275         stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3276
3277       if (expected_align < dest_align)
3278         expected_align = dest_align;
3279       dest_mem = get_memory_rtx (dest, len);
3280       set_mem_align (dest_mem, dest_align);
3281       len_rtx = expand_normal (len);
3282       src_str = c_getstr (src);
3283
3284       /* If SRC is a string constant and block move would be done
3285          by pieces, we can avoid loading the string from memory
3286          and only stored the computed constants.  */
3287       if (src_str
3288           && CONST_INT_P (len_rtx)
3289           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3290           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3291                                   CONST_CAST (char *, src_str),
3292                                   dest_align, false))
3293         {
3294           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3295                                       builtin_memcpy_read_str,
3296                                       CONST_CAST (char *, src_str),
3297                                       dest_align, false, 0);
3298           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3299           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3300           return dest_mem;
3301         }
3302
3303       src_mem = get_memory_rtx (src, len);
3304       set_mem_align (src_mem, src_align);
3305
3306       /* Copy word part most expediently.  */
3307       dest_addr = emit_block_move_hints (dest_mem, src_mem, len_rtx,
3308                                          CALL_EXPR_TAILCALL (exp)
3309                                          ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3310                                          expected_align, expected_size);
3311
3312       if (dest_addr == 0)
3313         {
3314           dest_addr = force_operand (XEXP (dest_mem, 0), target);
3315           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3316         }
3317       return dest_addr;
3318     }
3319 }
3320
3321 /* Expand a call EXP to the mempcpy builtin.
3322    Return NULL_RTX if we failed; the caller should emit a normal call,
3323    otherwise try to get the result in TARGET, if convenient (and in
3324    mode MODE if that's convenient).  If ENDP is 0 return the
3325    destination pointer, if ENDP is 1 return the end pointer ala
3326    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3327    stpcpy.  */
3328
3329 static rtx
3330 expand_builtin_mempcpy (tree exp, rtx target, enum machine_mode mode)
3331 {
3332   if (!validate_arglist (exp,
3333                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3334     return NULL_RTX;
3335   else
3336     {
3337       tree dest = CALL_EXPR_ARG (exp, 0);
3338       tree src = CALL_EXPR_ARG (exp, 1);
3339       tree len = CALL_EXPR_ARG (exp, 2);
3340       return expand_builtin_mempcpy_args (dest, src, len,
3341                                           target, mode, /*endp=*/ 1);
3342     }
3343 }
3344
3345 /* Helper function to do the actual work for expand_builtin_mempcpy.  The
3346    arguments to the builtin_mempcpy call DEST, SRC, and LEN are broken out
3347    so that this can also be called without constructing an actual CALL_EXPR.
3348    The other arguments and return value are the same as for
3349    expand_builtin_mempcpy.  */
3350
3351 static rtx
3352 expand_builtin_mempcpy_args (tree dest, tree src, tree len,
3353                              rtx target, enum machine_mode mode, int endp)
3354 {
3355     /* If return value is ignored, transform mempcpy into memcpy.  */
3356   if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_MEMCPY])
3357     {
3358       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3359       tree result = build_call_nofold (fn, 3, dest, src, len);
3360       return expand_expr (result, target, mode, EXPAND_NORMAL);
3361     }
3362   else
3363     {
3364       const char *src_str;
3365       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
3366       unsigned int dest_align
3367         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3368       rtx dest_mem, src_mem, len_rtx;
3369
3370       /* If either SRC or DEST is not a pointer type, don't do this
3371          operation in-line.  */
3372       if (dest_align == 0 || src_align == 0)
3373         return NULL_RTX;
3374
3375       /* If LEN is not constant, call the normal function.  */
3376       if (! host_integerp (len, 1))
3377         return NULL_RTX;
3378
3379       len_rtx = expand_normal (len);
3380       src_str = c_getstr (src);
3381
3382       /* If SRC is a string constant and block move would be done
3383          by pieces, we can avoid loading the string from memory
3384          and only stored the computed constants.  */
3385       if (src_str
3386           && CONST_INT_P (len_rtx)
3387           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
3388           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
3389                                   CONST_CAST (char *, src_str),
3390                                   dest_align, false))
3391         {
3392           dest_mem = get_memory_rtx (dest, len);
3393           set_mem_align (dest_mem, dest_align);
3394           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
3395                                       builtin_memcpy_read_str,
3396                                       CONST_CAST (char *, src_str),
3397                                       dest_align, false, endp);
3398           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3399           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3400           return dest_mem;
3401         }
3402
3403       if (CONST_INT_P (len_rtx)
3404           && can_move_by_pieces (INTVAL (len_rtx),
3405                                  MIN (dest_align, src_align)))
3406         {
3407           dest_mem = get_memory_rtx (dest, len);
3408           set_mem_align (dest_mem, dest_align);
3409           src_mem = get_memory_rtx (src, len);
3410           set_mem_align (src_mem, src_align);
3411           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
3412                                      MIN (dest_align, src_align), endp);
3413           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3414           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3415           return dest_mem;
3416         }
3417
3418       return NULL_RTX;
3419     }
3420 }
3421
3422 #ifndef HAVE_movstr
3423 # define HAVE_movstr 0
3424 # define CODE_FOR_movstr CODE_FOR_nothing
3425 #endif
3426
3427 /* Expand into a movstr instruction, if one is available.  Return NULL_RTX if
3428    we failed, the caller should emit a normal call, otherwise try to
3429    get the result in TARGET, if convenient.  If ENDP is 0 return the
3430    destination pointer, if ENDP is 1 return the end pointer ala
3431    mempcpy, and if ENDP is 2 return the end pointer minus one ala
3432    stpcpy.  */
3433
3434 static rtx
3435 expand_movstr (tree dest, tree src, rtx target, int endp)
3436 {
3437   rtx end;
3438   rtx dest_mem;
3439   rtx src_mem;
3440   rtx insn;
3441   const struct insn_data * data;
3442
3443   if (!HAVE_movstr)
3444     return NULL_RTX;
3445
3446   dest_mem = get_memory_rtx (dest, NULL);
3447   src_mem = get_memory_rtx (src, NULL);
3448   if (!endp)
3449     {
3450       target = force_reg (Pmode, XEXP (dest_mem, 0));
3451       dest_mem = replace_equiv_address (dest_mem, target);
3452       end = gen_reg_rtx (Pmode);
3453     }
3454   else
3455     {
3456       if (target == 0 || target == const0_rtx)
3457         {
3458           end = gen_reg_rtx (Pmode);
3459           if (target == 0)
3460             target = end;
3461         }
3462       else
3463         end = target;
3464     }
3465
3466   data = insn_data + CODE_FOR_movstr;
3467
3468   if (data->operand[0].mode != VOIDmode)
3469     end = gen_lowpart (data->operand[0].mode, end);
3470
3471   insn = data->genfun (end, dest_mem, src_mem);
3472
3473   gcc_assert (insn);
3474
3475   emit_insn (insn);
3476
3477   /* movstr is supposed to set end to the address of the NUL
3478      terminator.  If the caller requested a mempcpy-like return value,
3479      adjust it.  */
3480   if (endp == 1 && target != const0_rtx)
3481     {
3482       rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
3483       emit_move_insn (target, force_operand (tem, NULL_RTX));
3484     }
3485
3486   return target;
3487 }
3488
3489 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 
3490    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3491    try to get the result in TARGET, if convenient (and in mode MODE if that's
3492    convenient).  */
3493
3494 static rtx
3495 expand_builtin_strcpy (tree exp, rtx target)
3496 {
3497   if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3498    {
3499      tree dest = CALL_EXPR_ARG (exp, 0);
3500      tree src = CALL_EXPR_ARG (exp, 1);
3501      return expand_builtin_strcpy_args (dest, src, target);
3502    }
3503    return NULL_RTX;
3504 }
3505
3506 /* Helper function to do the actual work for expand_builtin_strcpy.  The
3507    arguments to the builtin_strcpy call DEST and SRC are broken out
3508    so that this can also be called without constructing an actual CALL_EXPR.
3509    The other arguments and return value are the same as for
3510    expand_builtin_strcpy.  */
3511
3512 static rtx
3513 expand_builtin_strcpy_args (tree dest, tree src, rtx target)
3514 {
3515   return expand_movstr (dest, src, target, /*endp=*/0);
3516 }
3517
3518 /* Expand a call EXP to the stpcpy builtin.
3519    Return NULL_RTX if we failed the caller should emit a normal call,
3520    otherwise try to get the result in TARGET, if convenient (and in
3521    mode MODE if that's convenient).  */
3522
3523 static rtx
3524 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
3525 {
3526   tree dst, src;
3527   location_t loc = EXPR_LOCATION (exp);
3528
3529   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3530     return NULL_RTX;
3531
3532   dst = CALL_EXPR_ARG (exp, 0);
3533   src = CALL_EXPR_ARG (exp, 1);
3534
3535   /* If return value is ignored, transform stpcpy into strcpy.  */
3536   if (target == const0_rtx && implicit_built_in_decls[BUILT_IN_STRCPY])
3537     {
3538       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3539       tree result = build_call_nofold (fn, 2, dst, src);
3540       return expand_expr (result, target, mode, EXPAND_NORMAL);
3541     }
3542   else
3543     {
3544       tree len, lenp1;
3545       rtx ret;
3546
3547       /* Ensure we get an actual string whose length can be evaluated at
3548          compile-time, not an expression containing a string.  This is
3549          because the latter will potentially produce pessimized code
3550          when used to produce the return value.  */
3551       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3552         return expand_movstr (dst, src, target, /*endp=*/2);
3553
3554       lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
3555       ret = expand_builtin_mempcpy_args (dst, src, lenp1,
3556                                          target, mode, /*endp=*/2);
3557
3558       if (ret)
3559         return ret;
3560
3561       if (TREE_CODE (len) == INTEGER_CST)
3562         {
3563           rtx len_rtx = expand_normal (len);
3564
3565           if (CONST_INT_P (len_rtx))
3566             {
3567               ret = expand_builtin_strcpy_args (dst, src, target);
3568
3569               if (ret)
3570                 {
3571                   if (! target)
3572                     {
3573                       if (mode != VOIDmode)
3574                         target = gen_reg_rtx (mode);
3575                       else
3576                         target = gen_reg_rtx (GET_MODE (ret));
3577                     }
3578                   if (GET_MODE (target) != GET_MODE (ret))
3579                     ret = gen_lowpart (GET_MODE (target), ret);
3580
3581                   ret = plus_constant (ret, INTVAL (len_rtx));
3582                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3583                   gcc_assert (ret);
3584
3585                   return target;
3586                 }
3587             }
3588         }
3589
3590       return expand_movstr (dst, src, target, /*endp=*/2);
3591     }
3592 }
3593
3594 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3595    bytes from constant string DATA + OFFSET and return it as target
3596    constant.  */
3597
3598 rtx
3599 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3600                           enum machine_mode mode)
3601 {
3602   const char *str = (const char *) data;
3603
3604   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3605     return const0_rtx;
3606
3607   return c_readstr (str + offset, mode);
3608 }
3609
3610 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 
3611    NULL_RTX if we failed the caller should emit a normal call.  */
3612
3613 static rtx
3614 expand_builtin_strncpy (tree exp, rtx target)
3615 {
3616   location_t loc = EXPR_LOCATION (exp);
3617
3618   if (validate_arglist (exp,
3619                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3620     {
3621       tree dest = CALL_EXPR_ARG (exp, 0);
3622       tree src = CALL_EXPR_ARG (exp, 1);
3623       tree len = CALL_EXPR_ARG (exp, 2);
3624       tree slen = c_strlen (src, 1);
3625
3626       /* We must be passed a constant len and src parameter.  */
3627       if (!host_integerp (len, 1) || !slen || !host_integerp (slen, 1))
3628         return NULL_RTX;
3629
3630       slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
3631
3632       /* We're required to pad with trailing zeros if the requested
3633          len is greater than strlen(s2)+1.  In that case try to
3634          use store_by_pieces, if it fails, punt.  */
3635       if (tree_int_cst_lt (slen, len))
3636         {
3637           unsigned int dest_align
3638             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3639           const char *p = c_getstr (src);
3640           rtx dest_mem;
3641
3642           if (!p || dest_align == 0 || !host_integerp (len, 1)
3643               || !can_store_by_pieces (tree_low_cst (len, 1),
3644                                        builtin_strncpy_read_str,
3645                                        CONST_CAST (char *, p),
3646                                        dest_align, false))
3647             return NULL_RTX;
3648
3649           dest_mem = get_memory_rtx (dest, len);
3650           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3651                            builtin_strncpy_read_str,
3652                            CONST_CAST (char *, p), dest_align, false, 0);
3653           dest_mem = force_operand (XEXP (dest_mem, 0), target);
3654           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3655           return dest_mem;
3656         }
3657     }
3658   return NULL_RTX;
3659 }
3660
3661 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3662    bytes from constant string DATA + OFFSET and return it as target
3663    constant.  */
3664
3665 rtx
3666 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3667                          enum machine_mode mode)
3668 {
3669   const char *c = (const char *) data;
3670   char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
3671
3672   memset (p, *c, GET_MODE_SIZE (mode));
3673
3674   return c_readstr (p, mode);
3675 }
3676
3677 /* Callback routine for store_by_pieces.  Return the RTL of a register
3678    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3679    char value given in the RTL register data.  For example, if mode is
3680    4 bytes wide, return the RTL for 0x01010101*data.  */
3681
3682 static rtx
3683 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3684                         enum machine_mode mode)
3685 {
3686   rtx target, coeff;
3687   size_t size;
3688   char *p;
3689
3690   size = GET_MODE_SIZE (mode);
3691   if (size == 1)
3692     return (rtx) data;
3693
3694   p = XALLOCAVEC (char, size);
3695   memset (p, 1, size);
3696   coeff = c_readstr (p, mode);
3697
3698   target = convert_to_mode (mode, (rtx) data, 1);
3699   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3700   return force_reg (mode, target);
3701 }
3702
3703 /* Expand expression EXP, which is a call to the memset builtin.  Return 
3704    NULL_RTX if we failed the caller should emit a normal call, otherwise 
3705    try to get the result in TARGET, if convenient (and in mode MODE if that's
3706    convenient).  */
3707
3708 static rtx
3709 expand_builtin_memset (tree exp, rtx target, enum machine_mode mode)
3710 {
3711   if (!validate_arglist (exp,
3712                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3713     return NULL_RTX;
3714   else
3715     {
3716       tree dest = CALL_EXPR_ARG (exp, 0);
3717       tree val = CALL_EXPR_ARG (exp, 1);
3718       tree len = CALL_EXPR_ARG (exp, 2);
3719       return expand_builtin_memset_args (dest, val, len, target, mode, exp);
3720     }
3721 }
3722
3723 /* Helper function to do the actual work for expand_builtin_memset.  The
3724    arguments to the builtin_memset call DEST, VAL, and LEN are broken out
3725    so that this can also be called without constructing an actual CALL_EXPR.
3726    The other arguments and return value are the same as for
3727    expand_builtin_memset.  */
3728
3729 static rtx
3730 expand_builtin_memset_args (tree dest, tree val, tree len,
3731                             rtx target, enum machine_mode mode, tree orig_exp)
3732 {
3733   tree fndecl, fn;
3734   enum built_in_function fcode;
3735   char c;
3736   unsigned int dest_align;
3737   rtx dest_mem, dest_addr, len_rtx;
3738   HOST_WIDE_INT expected_size = -1;
3739   unsigned int expected_align = 0;
3740   tree_ann_common_t ann;
3741
3742   dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3743
3744   /* If DEST is not a pointer type, don't do this operation in-line.  */
3745   if (dest_align == 0)
3746     return NULL_RTX;
3747
3748   ann = tree_common_ann (orig_exp);
3749   if (ann)
3750     stringop_block_profile (ann->stmt, &expected_align, &expected_size);
3751
3752   if (expected_align < dest_align)
3753     expected_align = dest_align;
3754
3755   /* If the LEN parameter is zero, return DEST.  */
3756   if (integer_zerop (len))
3757     {
3758       /* Evaluate and ignore VAL in case it has side-effects.  */
3759       expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3760       return expand_expr (dest, target, mode, EXPAND_NORMAL);
3761     }
3762
3763   /* Stabilize the arguments in case we fail.  */
3764   dest = builtin_save_expr (dest);
3765   val = builtin_save_expr (val);
3766   len = builtin_save_expr (len);
3767
3768   len_rtx = expand_normal (len);
3769   dest_mem = get_memory_rtx (dest, len);
3770
3771   if (TREE_CODE (val) != INTEGER_CST)
3772     {
3773       rtx val_rtx;
3774
3775       val_rtx = expand_normal (val);
3776       val_rtx = convert_to_mode (TYPE_MODE (unsigned_char_type_node),
3777                                  val_rtx, 0);
3778
3779       /* Assume that we can memset by pieces if we can store
3780        * the coefficients by pieces (in the required modes).
3781        * We can't pass builtin_memset_gen_str as that emits RTL.  */
3782       c = 1;
3783       if (host_integerp (len, 1)
3784           && can_store_by_pieces (tree_low_cst (len, 1),
3785                                   builtin_memset_read_str, &c, dest_align,
3786                                   true))
3787         {
3788           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3789                                val_rtx);
3790           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3791                            builtin_memset_gen_str, val_rtx, dest_align,
3792                            true, 0);
3793         }
3794       else if (!set_storage_via_setmem (dest_mem, len_rtx, val_rtx,
3795                                         dest_align, expected_align,
3796                                         expected_size))
3797         goto do_libcall;
3798       
3799       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3800       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3801       return dest_mem;
3802     }
3803
3804   if (target_char_cast (val, &c))
3805     goto do_libcall;
3806
3807   if (c)
3808     {
3809       if (host_integerp (len, 1)
3810           && can_store_by_pieces (tree_low_cst (len, 1),
3811                                   builtin_memset_read_str, &c, dest_align,
3812                                   true))
3813         store_by_pieces (dest_mem, tree_low_cst (len, 1),
3814                          builtin_memset_read_str, &c, dest_align, true, 0);
3815       else if (!set_storage_via_setmem (dest_mem, len_rtx, GEN_INT (c),
3816                                         dest_align, expected_align,
3817                                         expected_size))
3818         goto do_libcall;
3819       
3820       dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3821       dest_mem = convert_memory_address (ptr_mode, dest_mem);
3822       return dest_mem;
3823     }
3824
3825   set_mem_align (dest_mem, dest_align);
3826   dest_addr = clear_storage_hints (dest_mem, len_rtx,
3827                                    CALL_EXPR_TAILCALL (orig_exp)
3828                                    ? BLOCK_OP_TAILCALL : BLOCK_OP_NORMAL,
3829                                    expected_align, expected_size);
3830
3831   if (dest_addr == 0)
3832     {
3833       dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3834       dest_addr = convert_memory_address (ptr_mode, dest_addr);
3835     }
3836
3837   return dest_addr;
3838
3839  do_libcall:
3840   fndecl = get_callee_fndecl (orig_exp);
3841   fcode = DECL_FUNCTION_CODE (fndecl);
3842   if (fcode == BUILT_IN_MEMSET)
3843     fn = build_call_nofold (fndecl, 3, dest, val, len);
3844   else if (fcode == BUILT_IN_BZERO)
3845     fn = build_call_nofold (fndecl, 2, dest, len);
3846   else
3847     gcc_unreachable ();
3848   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
3849   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (orig_exp);
3850   return expand_call (fn, target, target == const0_rtx);
3851 }
3852
3853 /* Expand expression EXP, which is a call to the bzero builtin.  Return 
3854    NULL_RTX if we failed the caller should emit a normal call.  */
3855
3856 static rtx
3857 expand_builtin_bzero (tree exp)
3858 {
3859   tree dest, size;
3860   location_t loc = EXPR_LOCATION (exp);
3861
3862   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3863     return NULL_RTX;
3864
3865   dest = CALL_EXPR_ARG (exp, 0);
3866   size = CALL_EXPR_ARG (exp, 1);
3867
3868   /* New argument list transforming bzero(ptr x, int y) to
3869      memset(ptr x, int 0, size_t y).   This is done this way
3870      so that if it isn't expanded inline, we fallback to
3871      calling bzero instead of memset.  */
3872
3873   return expand_builtin_memset_args (dest, integer_zero_node,
3874                                      fold_convert_loc (loc, sizetype, size),
3875                                      const0_rtx, VOIDmode, exp);
3876 }
3877
3878 /* Expand expression EXP, which is a call to the memcmp built-in function.
3879    Return NULL_RTX if we failed and the
3880    caller should emit a normal call, otherwise try to get the result in
3881    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3882
3883 static rtx
3884 expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
3885                        ATTRIBUTE_UNUSED enum machine_mode mode)
3886 {
3887   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
3888
3889   if (!validate_arglist (exp,
3890                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3891     return NULL_RTX;
3892
3893 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrnsi
3894   {
3895     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3896     rtx result;
3897     rtx insn;
3898     tree arg1 = CALL_EXPR_ARG (exp, 0);
3899     tree arg2 = CALL_EXPR_ARG (exp, 1);
3900     tree len = CALL_EXPR_ARG (exp, 2);
3901
3902     int arg1_align
3903       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3904     int arg2_align
3905       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3906     enum machine_mode insn_mode;
3907
3908 #ifdef HAVE_cmpmemsi
3909     if (HAVE_cmpmemsi)
3910       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3911     else
3912 #endif
3913 #ifdef HAVE_cmpstrnsi
3914     if (HAVE_cmpstrnsi)
3915       insn_mode = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
3916     else
3917 #endif
3918       return NULL_RTX;
3919
3920     /* If we don't have POINTER_TYPE, call the function.  */
3921     if (arg1_align == 0 || arg2_align == 0)
3922       return NULL_RTX;
3923
3924     /* Make a place to write the result of the instruction.  */
3925     result = target;
3926     if (! (result != 0
3927            && REG_P (result) && GET_MODE (result) == insn_mode
3928            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3929       result = gen_reg_rtx (insn_mode);
3930
3931     arg1_rtx = get_memory_rtx (arg1, len);
3932     arg2_rtx = get_memory_rtx (arg2, len);
3933     arg3_rtx = expand_normal (fold_convert_loc (loc, sizetype, len));
3934
3935     /* Set MEM_SIZE as appropriate.  */
3936     if (CONST_INT_P (arg3_rtx))
3937       {
3938         set_mem_size (arg1_rtx, arg3_rtx);
3939         set_mem_size (arg2_rtx, arg3_rtx);
3940       }
3941
3942 #ifdef HAVE_cmpmemsi
3943     if (HAVE_cmpmemsi)
3944       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3945                            GEN_INT (MIN (arg1_align, arg2_align)));
3946     else
3947 #endif
3948 #ifdef HAVE_cmpstrnsi
3949     if (HAVE_cmpstrnsi)
3950       insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3951                             GEN_INT (MIN (arg1_align, arg2_align)));
3952     else
3953 #endif
3954       gcc_unreachable ();
3955
3956     if (insn)
3957       emit_insn (insn);
3958     else
3959       emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
3960                                TYPE_MODE (integer_type_node), 3,
3961                                XEXP (arg1_rtx, 0), Pmode,
3962                                XEXP (arg2_rtx, 0), Pmode,
3963                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3964                                                 TYPE_UNSIGNED (sizetype)),
3965                                TYPE_MODE (sizetype));
3966
3967     /* Return the value in the proper mode for this function.  */
3968     mode = TYPE_MODE (TREE_TYPE (exp));
3969     if (GET_MODE (result) == mode)
3970       return result;
3971     else if (target != 0)
3972       {
3973         convert_move (target, result, 0);
3974         return target;
3975       }
3976     else
3977       return convert_to_mode (mode, result, 0);
3978   }
3979 #endif
3980
3981   return NULL_RTX;
3982 }
3983
3984 /* Expand expression EXP, which is a call to the strcmp builtin.  Return NULL_RTX
3985    if we failed the caller should emit a normal call, otherwise try to get
3986    the result in TARGET, if convenient.  */
3987
3988 static rtx
3989 expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
3990 {
3991   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3992     return NULL_RTX;
3993
3994 #if defined HAVE_cmpstrsi || defined HAVE_cmpstrnsi
3995   if (cmpstr_optab[SImode] != CODE_FOR_nothing
3996       || cmpstrn_optab[SImode] != CODE_FOR_nothing)
3997     {
3998       rtx arg1_rtx, arg2_rtx;
3999       rtx result, insn = NULL_RTX;
4000       tree fndecl, fn;
4001       tree arg1 = CALL_EXPR_ARG (exp, 0);
4002       tree arg2 = CALL_EXPR_ARG (exp, 1);
4003
4004       int arg1_align
4005         = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4006       int arg2_align
4007         = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4008
4009       /* If we don't have POINTER_TYPE, call the function.  */
4010       if (arg1_align == 0 || arg2_align == 0)
4011         return NULL_RTX;
4012
4013       /* Stabilize the arguments in case gen_cmpstr(n)si fail.  */
4014       arg1 = builtin_save_expr (arg1);
4015       arg2 = builtin_save_expr (arg2);
4016
4017       arg1_rtx = get_memory_rtx (arg1, NULL);
4018       arg2_rtx = get_memory_rtx (arg2, NULL);
4019
4020 #ifdef HAVE_cmpstrsi
4021       /* Try to call cmpstrsi.  */
4022       if (HAVE_cmpstrsi)
4023         {
4024           enum machine_mode insn_mode
4025             = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
4026
4027           /* Make a place to write the result of the instruction.  */
4028           result = target;
4029           if (! (result != 0
4030                  && REG_P (result) && GET_MODE (result) == insn_mode
4031                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4032             result = gen_reg_rtx (insn_mode);
4033
4034           insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx,
4035                                GEN_INT (MIN (arg1_align, arg2_align)));
4036         }
4037 #endif
4038 #ifdef HAVE_cmpstrnsi
4039       /* Try to determine at least one length and call cmpstrnsi.  */
4040       if (!insn && HAVE_cmpstrnsi)
4041         {
4042           tree len;
4043           rtx arg3_rtx;
4044
4045           enum machine_mode insn_mode
4046             = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4047           tree len1 = c_strlen (arg1, 1);
4048           tree len2 = c_strlen (arg2, 1);
4049
4050           if (len1)
4051             len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
4052           if (len2)
4053             len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
4054
4055           /* If we don't have a constant length for the first, use the length
4056              of the second, if we know it.  We don't require a constant for
4057              this case; some cost analysis could be done if both are available
4058              but neither is constant.  For now, assume they're equally cheap,
4059              unless one has side effects.  If both strings have constant lengths,
4060              use the smaller.  */
4061
4062           if (!len1)
4063             len = len2;
4064           else if (!len2)
4065             len = len1;
4066           else if (TREE_SIDE_EFFECTS (len1))
4067             len = len2;
4068           else if (TREE_SIDE_EFFECTS (len2))
4069             len = len1;
4070           else if (TREE_CODE (len1) != INTEGER_CST)
4071             len = len2;
4072           else if (TREE_CODE (len2) != INTEGER_CST)
4073             len = len1;
4074           else if (tree_int_cst_lt (len1, len2))
4075             len = len1;
4076           else
4077             len = len2;
4078
4079           /* If both arguments have side effects, we cannot optimize.  */
4080           if (!len || TREE_SIDE_EFFECTS (len))
4081             goto do_libcall;
4082
4083           arg3_rtx = expand_normal (len);
4084
4085           /* Make a place to write the result of the instruction.  */
4086           result = target;
4087           if (! (result != 0
4088                  && REG_P (result) && GET_MODE (result) == insn_mode
4089                  && REGNO (result) >= FIRST_PSEUDO_REGISTER))
4090             result = gen_reg_rtx (insn_mode);
4091
4092           insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4093                                 GEN_INT (MIN (arg1_align, arg2_align)));
4094         }
4095 #endif
4096
4097       if (insn)
4098         {
4099           enum machine_mode mode;
4100           emit_insn (insn);
4101
4102           /* Return the value in the proper mode for this function.  */
4103           mode = TYPE_MODE (TREE_TYPE (exp));
4104           if (GET_MODE (result) == mode)
4105             return result;
4106           if (target == 0)
4107             return convert_to_mode (mode, result, 0);
4108           convert_move (target, result, 0);
4109           return target;
4110         }
4111
4112       /* Expand the library call ourselves using a stabilized argument
4113          list to avoid re-evaluating the function's arguments twice.  */
4114 #ifdef HAVE_cmpstrnsi
4115     do_libcall:
4116 #endif
4117       fndecl = get_callee_fndecl (exp);
4118       fn = build_call_nofold (fndecl, 2, arg1, arg2);
4119       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4120       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4121       return expand_call (fn, target, target == const0_rtx);
4122     }
4123 #endif
4124   return NULL_RTX;
4125 }
4126
4127 /* Expand expression EXP, which is a call to the strncmp builtin. Return 
4128    NULL_RTX if we failed the caller should emit a normal call, otherwise try to get
4129    the result in TARGET, if convenient.  */
4130
4131 static rtx
4132 expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
4133                         ATTRIBUTE_UNUSED enum machine_mode mode)
4134 {
4135   location_t loc ATTRIBUTE_UNUSED = EXPR_LOCATION (exp);
4136
4137   if (!validate_arglist (exp,
4138                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
4139     return NULL_RTX;
4140
4141   /* If c_strlen can determine an expression for one of the string
4142      lengths, and it doesn't have side effects, then emit cmpstrnsi
4143      using length MIN(strlen(string)+1, arg3).  */
4144 #ifdef HAVE_cmpstrnsi
4145   if (HAVE_cmpstrnsi)
4146   {
4147     tree len, len1, len2;
4148     rtx arg1_rtx, arg2_rtx, arg3_rtx;
4149     rtx result, insn;
4150     tree fndecl, fn;
4151     tree arg1 = CALL_EXPR_ARG (exp, 0);
4152     tree arg2 = CALL_EXPR_ARG (exp, 1);
4153     tree arg3 = CALL_EXPR_ARG (exp, 2);
4154
4155     int arg1_align
4156       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4157     int arg2_align
4158       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
4159     enum machine_mode insn_mode
4160       = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
4161
4162     len1 = c_strlen (arg1, 1);
4163     len2 = c_strlen (arg2, 1);
4164
4165     if (len1)
4166       len1 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len1);
4167     if (len2)
4168       len2 = size_binop_loc (loc, PLUS_EXPR, ssize_int (1), len2);
4169
4170     /* If we don't have a constant length for the first, use the length
4171        of the second, if we know it.  We don't require a constant for
4172        this case; some cost analysis could be done if both are available
4173        but neither is constant.  For now, assume they're equally cheap,
4174        unless one has side effects.  If both strings have constant lengths,
4175        use the smaller.  */
4176
4177     if (!len1)
4178       len = len2;
4179     else if (!len2)
4180       len = len1;
4181     else if (TREE_SIDE_EFFECTS (len1))
4182       len = len2;
4183     else if (TREE_SIDE_EFFECTS (len2))
4184       len = len1;
4185     else if (TREE_CODE (len1) != INTEGER_CST)
4186       len = len2;
4187     else if (TREE_CODE (len2) != INTEGER_CST)
4188       len = len1;
4189     else if (tree_int_cst_lt (len1, len2))
4190       len = len1;
4191     else
4192       len = len2;
4193
4194     /* If both arguments have side effects, we cannot optimize.  */
4195     if (!len || TREE_SIDE_EFFECTS (len))
4196       return NULL_RTX;
4197
4198     /* The actual new length parameter is MIN(len,arg3).  */
4199     len = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (len), len,
4200                        fold_convert_loc (loc, TREE_TYPE (len), arg3));
4201
4202     /* If we don't have POINTER_TYPE, call the function.  */
4203     if (arg1_align == 0 || arg2_align == 0)
4204       return NULL_RTX;
4205
4206     /* 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     /* Stabilize the arguments in case gen_cmpstrnsi fails.  */
4214     arg1 = builtin_save_expr (arg1);
4215     arg2 = builtin_save_expr (arg2);
4216     len = builtin_save_expr (len);
4217
4218     arg1_rtx = get_memory_rtx (arg1, len);
4219     arg2_rtx = get_memory_rtx (arg2, len);
4220     arg3_rtx = expand_normal (len);
4221     insn = gen_cmpstrnsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
4222                           GEN_INT (MIN (arg1_align, arg2_align)));
4223     if (insn)
4224       {
4225         emit_insn (insn);
4226
4227         /* Return the value in the proper mode for this function.  */
4228         mode = TYPE_MODE (TREE_TYPE (exp));
4229         if (GET_MODE (result) == mode)
4230           return result;
4231         if (target == 0)
4232           return convert_to_mode (mode, result, 0);
4233         convert_move (target, result, 0);
4234         return target;
4235       }
4236
4237     /* Expand the library call ourselves using a stabilized argument
4238        list to avoid re-evaluating the function's arguments twice.  */
4239     fndecl = get_callee_fndecl (exp);
4240     fn = build_call_nofold (fndecl, 3, arg1, arg2, len);
4241     gcc_assert (TREE_CODE (fn) == CALL_EXPR);
4242     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4243     return expand_call (fn, target, target == const0_rtx);
4244   }
4245 #endif
4246   return NULL_RTX;
4247 }
4248
4249 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4250    if that's convenient.  */
4251
4252 rtx
4253 expand_builtin_saveregs (void)
4254 {
4255   rtx val, seq;
4256
4257   /* Don't do __builtin_saveregs more than once in a function.
4258      Save the result of the first call and reuse it.  */
4259   if (saveregs_value != 0)
4260     return saveregs_value;
4261
4262   /* When this function is called, it means that registers must be
4263      saved on entry to this function.  So we migrate the call to the
4264      first insn of this function.  */
4265
4266   start_sequence ();
4267
4268   /* Do whatever the machine needs done in this case.  */
4269   val = targetm.calls.expand_builtin_saveregs ();
4270
4271   seq = get_insns ();
4272   end_sequence ();
4273
4274   saveregs_value = val;
4275
4276   /* Put the insns after the NOTE that starts the function.  If this
4277      is inside a start_sequence, make the outer-level insn chain current, so
4278      the code is placed at the start of the function.  */
4279   push_topmost_sequence ();
4280   emit_insn_after (seq, entry_of_function ());
4281   pop_topmost_sequence ();
4282
4283   return val;
4284 }
4285
4286 /* __builtin_args_info (N) returns word N of the arg space info
4287    for the current function.  The number and meanings of words
4288    is controlled by the definition of CUMULATIVE_ARGS.  */
4289
4290 static rtx
4291 expand_builtin_args_info (tree exp)
4292 {
4293   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4294   int *word_ptr = (int *) &crtl->args.info;
4295
4296   gcc_assert (sizeof (CUMULATIVE_ARGS) % sizeof (int) == 0);
4297
4298   if (call_expr_nargs (exp) != 0)
4299     {
4300       if (!host_integerp (CALL_EXPR_ARG (exp, 0), 0))
4301         error ("argument of %<__builtin_args_info%> must be constant");
4302       else
4303         {
4304           HOST_WIDE_INT wordnum = tree_low_cst (CALL_EXPR_ARG (exp, 0), 0);
4305
4306           if (wordnum < 0 || wordnum >= nwords)
4307             error ("argument of %<__builtin_args_info%> out of range");
4308           else
4309             return GEN_INT (word_ptr[wordnum]);
4310         }
4311     }
4312   else
4313     error ("missing argument in %<__builtin_args_info%>");
4314
4315   return const0_rtx;
4316 }
4317
4318 /* Expand a call to __builtin_next_arg.  */
4319
4320 static rtx
4321 expand_builtin_next_arg (void)
4322 {
4323   /* Checking arguments is already done in fold_builtin_next_arg
4324      that must be called before this function.  */
4325   return expand_binop (ptr_mode, add_optab,
4326                        crtl->args.internal_arg_pointer,
4327                        crtl->args.arg_offset_rtx,
4328                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4329 }
4330
4331 /* Make it easier for the backends by protecting the valist argument
4332    from multiple evaluations.  */
4333
4334 static tree
4335 stabilize_va_list_loc (location_t loc, tree valist, int needs_lvalue)
4336 {
4337   tree vatype = targetm.canonical_va_list_type (TREE_TYPE (valist));
4338
4339   gcc_assert (vatype != NULL_TREE);
4340
4341   if (TREE_CODE (vatype) == ARRAY_TYPE)
4342     {
4343       if (TREE_SIDE_EFFECTS (valist))
4344         valist = save_expr (valist);
4345
4346       /* For this case, the backends will be expecting a pointer to
4347          vatype, but it's possible we've actually been given an array
4348          (an actual TARGET_CANONICAL_VA_LIST_TYPE (valist)).
4349          So fix it.  */
4350       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4351         {
4352           tree p1 = build_pointer_type (TREE_TYPE (vatype));
4353           valist = build_fold_addr_expr_with_type_loc (loc, valist, p1);
4354         }
4355     }
4356   else
4357     {
4358       tree pt;
4359
4360       if (! needs_lvalue)
4361         {
4362           if (! TREE_SIDE_EFFECTS (valist))
4363             return valist;
4364
4365           pt = build_pointer_type (vatype);
4366           valist = fold_build1_loc (loc, ADDR_EXPR, pt, valist);
4367           TREE_SIDE_EFFECTS (valist) = 1;
4368         }
4369
4370       if (TREE_SIDE_EFFECTS (valist))
4371         valist = save_expr (valist);
4372       valist = build_fold_indirect_ref_loc (loc, valist);
4373     }
4374
4375   return valist;
4376 }
4377
4378 /* The "standard" definition of va_list is void*.  */
4379
4380 tree
4381 std_build_builtin_va_list (void)
4382 {
4383   return ptr_type_node;
4384 }
4385
4386 /* The "standard" abi va_list is va_list_type_node.  */
4387
4388 tree
4389 std_fn_abi_va_list (tree fndecl ATTRIBUTE_UNUSED)
4390 {
4391   return va_list_type_node;
4392 }
4393
4394 /* The "standard" type of va_list is va_list_type_node.  */
4395
4396 tree
4397 std_canonical_va_list_type (tree type)
4398 {
4399   tree wtype, htype;
4400
4401   if (INDIRECT_REF_P (type))
4402     type = TREE_TYPE (type);
4403   else if (POINTER_TYPE_P (type) && POINTER_TYPE_P (TREE_TYPE(type)))
4404     type = TREE_TYPE (type);
4405   wtype = va_list_type_node;
4406   htype = type;
4407   /* Treat structure va_list types.  */
4408   if (TREE_CODE (wtype) == RECORD_TYPE && POINTER_TYPE_P (htype))
4409     htype = TREE_TYPE (htype);
4410   else if (TREE_CODE (wtype) == ARRAY_TYPE)
4411     {
4412       /* If va_list is an array type, the argument may have decayed
4413          to a pointer type, e.g. by being passed to another function.
4414          In that case, unwrap both types so that we can compare the
4415          underlying records.  */
4416       if (TREE_CODE (htype) == ARRAY_TYPE
4417           || POINTER_TYPE_P (htype))
4418         {
4419           wtype = TREE_TYPE (wtype);
4420           htype = TREE_TYPE (htype);
4421         }
4422     }
4423   if (TYPE_MAIN_VARIANT (wtype) == TYPE_MAIN_VARIANT (htype))
4424     return va_list_type_node;
4425
4426   return NULL_TREE;
4427 }
4428
4429 /* The "standard" implementation of va_start: just assign `nextarg' to
4430    the variable.  */
4431
4432 void
4433 std_expand_builtin_va_start (tree valist, rtx nextarg)
4434 {
4435   rtx va_r = expand_expr (valist, NULL_RTX, VOIDmode, EXPAND_WRITE);
4436   convert_move (va_r, nextarg, 0);
4437 }
4438
4439 /* Expand EXP, a call to __builtin_va_start.  */
4440
4441 static rtx
4442 expand_builtin_va_start (tree exp)
4443 {
4444   rtx nextarg;
4445   tree valist;
4446   location_t loc = EXPR_LOCATION (exp);
4447
4448   if (call_expr_nargs (exp) < 2)
4449     {
4450       error_at (loc, "too few arguments to function %<va_start%>");
4451       return const0_rtx;
4452     }
4453
4454   if (fold_builtin_next_arg (exp, true))
4455     return const0_rtx;
4456
4457   nextarg = expand_builtin_next_arg ();
4458   valist = stabilize_va_list_loc (loc, CALL_EXPR_ARG (exp, 0), 1);
4459
4460   if (targetm.expand_builtin_va_start)
4461     targetm.expand_builtin_va_start (valist, nextarg);
4462   else
4463     std_expand_builtin_va_start (valist, nextarg);
4464
4465   return const0_rtx;
4466 }
4467
4468 /* The "standard" implementation of va_arg: read the value from the
4469    current (padded) address and increment by the (padded) size.  */
4470
4471 tree
4472 std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
4473                           gimple_seq *post_p)
4474 {
4475   tree addr, t, type_size, rounded_size, valist_tmp;
4476   unsigned HOST_WIDE_INT align, boundary;
4477   bool indirect;
4478
4479 #ifdef ARGS_GROW_DOWNWARD
4480   /* All of the alignment and movement below is for args-grow-up machines.
4481      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4482      implement their own specialized gimplify_va_arg_expr routines.  */
4483   gcc_unreachable ();
4484 #endif
4485
4486   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4487   if (indirect)
4488     type = build_pointer_type (type);
4489
4490   align = PARM_BOUNDARY / BITS_PER_UNIT;
4491   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
4492
4493   /* When we align parameter on stack for caller, if the parameter
4494      alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be
4495      aligned at MAX_SUPPORTED_STACK_ALIGNMENT.  We will match callee
4496      here with caller.  */
4497   if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
4498     boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
4499
4500   boundary /= BITS_PER_UNIT;
4501
4502   /* Hoist the valist value into a temporary for the moment.  */
4503   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4504
4505   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4506      requires greater alignment, we must perform dynamic alignment.  */
4507   if (boundary > align
4508       && !integer_zerop (TYPE_SIZE (type)))
4509     {
4510       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4511                   fold_build2 (POINTER_PLUS_EXPR,
4512                                TREE_TYPE (valist),
4513                                valist_tmp, size_int (boundary - 1)));
4514       gimplify_and_add (t, pre_p);
4515
4516       t = fold_convert (sizetype, valist_tmp);
4517       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4518                   fold_convert (TREE_TYPE (valist),
4519                                 fold_build2 (BIT_AND_EXPR, sizetype, t,
4520                                              size_int (-boundary))));
4521       gimplify_and_add (t, pre_p);
4522     }
4523   else
4524     boundary = align;
4525
4526   /* If the actual alignment is less than the alignment of the type,
4527      adjust the type accordingly so that we don't assume strict alignment
4528      when dereferencing the pointer.  */
4529   boundary *= BITS_PER_UNIT;
4530   if (boundary < TYPE_ALIGN (type))
4531     {
4532       type = build_variant_type_copy (type);
4533       TYPE_ALIGN (type) = boundary;
4534     }
4535
4536   /* Compute the rounded size of the type.  */
4537   type_size = size_in_bytes (type);
4538   rounded_size = round_up (type_size, align);
4539
4540   /* Reduce rounded_size so it's sharable with the postqueue.  */
4541   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4542
4543   /* Get AP.  */
4544   addr = valist_tmp;
4545   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4546     {
4547       /* Small args are padded downward.  */
4548       t = fold_build2_loc (input_location, GT_EXPR, sizetype,
4549                        rounded_size, size_int (align));
4550       t = fold_build3 (COND_EXPR, sizetype, t, size_zero_node,
4551                        size_binop (MINUS_EXPR, rounded_size, type_size));
4552       addr = fold_build2 (POINTER_PLUS_EXPR,
4553                           TREE_TYPE (addr), addr, t);
4554     }
4555
4556   /* Compute new value for AP.  */
4557   t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (valist), valist_tmp, rounded_size);
4558   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4559   gimplify_and_add (t, pre_p);
4560
4561   addr = fold_convert (build_pointer_type (type), addr);
4562
4563   if (indirect)
4564     addr = build_va_arg_indirect_ref (addr);
4565
4566   return build_va_arg_indirect_ref (addr);
4567 }
4568
4569 /* Build an indirect-ref expression over the given TREE, which represents a
4570    piece of a va_arg() expansion.  */
4571 tree
4572 build_va_arg_indirect_ref (tree addr)
4573 {
4574   addr = build_fold_indirect_ref_loc (EXPR_LOCATION (addr), addr);
4575
4576   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
4577     mf_mark (addr);
4578
4579   return addr;
4580 }
4581
4582 /* Return a dummy expression of type TYPE in order to keep going after an
4583    error.  */
4584
4585 static tree
4586 dummy_object (tree type)
4587 {
4588   tree t = build_int_cst (build_pointer_type (type), 0);
4589   return build1 (INDIRECT_REF, type, t);
4590 }
4591
4592 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4593    builtin function, but a very special sort of operator.  */
4594
4595 enum gimplify_status
4596 gimplify_va_arg_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
4597 {
4598   tree promoted_type, have_va_type;
4599   tree valist = TREE_OPERAND (*expr_p, 0);
4600   tree type = TREE_TYPE (*expr_p);
4601   tree t;
4602   location_t loc = EXPR_LOCATION (*expr_p);
4603
4604   /* Verify that valist is of the proper type.  */
4605   have_va_type = TREE_TYPE (valist);
4606   if (have_va_type == error_mark_node)
4607     return GS_ERROR;
4608   have_va_type = targetm.canonical_va_list_type (have_va_type);
4609
4610   if (have_va_type == NULL_TREE)
4611     {
4612       error_at (loc, "first argument to %<va_arg%> not of type %<va_list%>");
4613       return GS_ERROR;
4614     }
4615
4616   /* Generate a diagnostic for requesting data of a type that cannot
4617      be passed through `...' due to type promotion at the call site.  */
4618   if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4619            != type)
4620     {
4621       static bool gave_help;
4622       bool warned;
4623
4624       /* Unfortunately, this is merely undefined, rather than a constraint
4625          violation, so we cannot make this an error.  If this call is never
4626          executed, the program is still strictly conforming.  */
4627       warned = warning_at (loc, 0,
4628                            "%qT is promoted to %qT when passed through %<...%>",
4629                            type, promoted_type);
4630       if (!gave_help && warned)
4631         {
4632           gave_help = true;
4633           inform (loc, "(so you should pass %qT not %qT to %<va_arg%>)",
4634                   promoted_type, type);
4635         }
4636
4637       /* We can, however, treat "undefined" any way we please.
4638          Call abort to encourage the user to fix the program.  */
4639       if (warned)
4640         inform (loc, "if this code is reached, the program will abort");
4641       /* Before the abort, allow the evaluation of the va_list
4642          expression to exit or longjmp.  */
4643       gimplify_and_add (valist, pre_p);
4644       t = build_call_expr_loc (loc,
4645                                implicit_built_in_decls[BUILT_IN_TRAP], 0);
4646       gimplify_and_add (t, pre_p);
4647
4648       /* This is dead code, but go ahead and finish so that the
4649          mode of the result comes out right.  */
4650       *expr_p = dummy_object (type);
4651       return GS_ALL_DONE;
4652     }
4653   else
4654     {
4655       /* Make it easier for the backends by protecting the valist argument
4656          from multiple evaluations.  */
4657       if (TREE_CODE (have_va_type) == ARRAY_TYPE)
4658         {
4659           /* For this case, the backends will be expecting a pointer to
4660              TREE_TYPE (abi), but it's possible we've
4661              actually been given an array (an actual TARGET_FN_ABI_VA_LIST).
4662              So fix it.  */
4663           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4664             {
4665               tree p1 = build_pointer_type (TREE_TYPE (have_va_type));
4666               valist = fold_convert_loc (loc, p1,
4667                                          build_fold_addr_expr_loc (loc, valist));
4668             }
4669
4670           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4671         }
4672       else
4673         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4674
4675       if (!targetm.gimplify_va_arg_expr)
4676         /* FIXME: Once most targets are converted we should merely
4677            assert this is non-null.  */
4678         return GS_ALL_DONE;
4679
4680       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4681       return GS_OK;
4682     }
4683 }
4684
4685 /* Expand EXP, a call to __builtin_va_end.  */
4686
4687 static rtx
4688 expand_builtin_va_end (tree exp)
4689 {
4690   tree valist = CALL_EXPR_ARG (exp, 0);
4691
4692   /* Evaluate for side effects, if needed.  I hate macros that don't
4693      do that.  */
4694   if (TREE_SIDE_EFFECTS (valist))
4695     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4696
4697   return const0_rtx;
4698 }
4699
4700 /* Expand EXP, a call to __builtin_va_copy.  We do this as a
4701    builtin rather than just as an assignment in stdarg.h because of the
4702    nastiness of array-type va_list types.  */
4703
4704 static rtx
4705 expand_builtin_va_copy (tree exp)
4706 {
4707   tree dst, src, t;
4708   location_t loc = EXPR_LOCATION (exp);
4709
4710   dst = CALL_EXPR_ARG (exp, 0);
4711   src = CALL_EXPR_ARG (exp, 1);
4712
4713   dst = stabilize_va_list_loc (loc, dst, 1);
4714   src = stabilize_va_list_loc (loc, src, 0);
4715
4716   gcc_assert (cfun != NULL && cfun->decl != NULL_TREE);
4717
4718   if (TREE_CODE (targetm.fn_abi_va_list (cfun->decl)) != ARRAY_TYPE)
4719     {
4720       t = build2 (MODIFY_EXPR, targetm.fn_abi_va_list (cfun->decl), dst, src);
4721       TREE_SIDE_EFFECTS (t) = 1;
4722       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4723     }
4724   else
4725     {
4726       rtx dstb, srcb, size;
4727
4728       /* Evaluate to pointers.  */
4729       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4730       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4731       size = expand_expr (TYPE_SIZE_UNIT (targetm.fn_abi_va_list (cfun->decl)),
4732                   NULL_RTX, VOIDmode, EXPAND_NORMAL);
4733
4734       dstb = convert_memory_address (Pmode, dstb);
4735       srcb = convert_memory_address (Pmode, srcb);
4736
4737       /* "Dereference" to BLKmode memories.  */
4738       dstb = gen_rtx_MEM (BLKmode, dstb);
4739       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4740       set_mem_align (dstb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4741       srcb = gen_rtx_MEM (BLKmode, srcb);
4742       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4743       set_mem_align (srcb, TYPE_ALIGN (targetm.fn_abi_va_list (cfun->decl)));
4744
4745       /* Copy.  */
4746       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4747     }
4748
4749   return const0_rtx;
4750 }
4751
4752 /* Expand a call to one of the builtin functions __builtin_frame_address or
4753    __builtin_return_address.  */
4754
4755 static rtx
4756 expand_builtin_frame_address (tree fndecl, tree exp)
4757 {
4758   /* The argument must be a nonnegative integer constant.
4759      It counts the number of frames to scan up the stack.
4760      The value is the return address saved in that frame.  */
4761   if (call_expr_nargs (exp) == 0)
4762     /* Warning about missing arg was already issued.  */
4763     return const0_rtx;
4764   else if (! host_integerp (CALL_EXPR_ARG (exp, 0), 1))
4765     {
4766       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4767         error ("invalid argument to %<__builtin_frame_address%>");
4768       else
4769         error ("invalid argument to %<__builtin_return_address%>");
4770       return const0_rtx;
4771     }
4772   else
4773     {
4774       rtx tem
4775         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4776                                       tree_low_cst (CALL_EXPR_ARG (exp, 0), 1));
4777
4778       /* Some ports cannot access arbitrary stack frames.  */
4779       if (tem == NULL)
4780         {
4781           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4782             warning (0, "unsupported argument to %<__builtin_frame_address%>");
4783           else
4784             warning (0, "unsupported argument to %<__builtin_return_address%>");
4785           return const0_rtx;
4786         }
4787
4788       /* For __builtin_frame_address, return what we've got.  */
4789       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4790         return tem;
4791
4792       if (!REG_P (tem)
4793           && ! CONSTANT_P (tem))
4794         tem = copy_to_mode_reg (Pmode, tem);
4795       return tem;
4796     }
4797 }
4798
4799 /* Expand EXP, a call to the alloca builtin.  Return NULL_RTX if
4800    we failed and the caller should emit a normal call, otherwise try to get
4801    the result in TARGET, if convenient.  */
4802
4803 static rtx
4804 expand_builtin_alloca (tree exp, rtx target)
4805 {
4806   rtx op0;
4807   rtx result;
4808
4809   /* Emit normal call if marked not-inlineable.  */
4810   if (CALL_CANNOT_INLINE_P (exp)) 
4811     return NULL_RTX;
4812
4813   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4814     return NULL_RTX;
4815
4816   /* Compute the argument.  */
4817   op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
4818
4819   /* Allocate the desired space.  */
4820   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4821   result = convert_memory_address (ptr_mode, result);
4822
4823   return result;
4824 }
4825
4826 /* Expand a call to a bswap builtin with argument ARG0.  MODE
4827    is the mode to expand with.  */
4828
4829 static rtx
4830 expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
4831 {
4832   enum machine_mode mode;
4833   tree arg;
4834   rtx op0;
4835
4836   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4837     return NULL_RTX;
4838
4839   arg = CALL_EXPR_ARG (exp, 0);
4840   mode = TYPE_MODE (TREE_TYPE (arg));
4841   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4842
4843   target = expand_unop (mode, bswap_optab, op0, target, 1);
4844
4845   gcc_assert (target);
4846
4847   return convert_to_mode (mode, target, 0);
4848 }
4849
4850 /* Expand a call to a unary builtin in EXP.
4851    Return NULL_RTX if a normal call should be emitted rather than expanding the
4852    function in-line.  If convenient, the result should be placed in TARGET.
4853    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4854
4855 static rtx
4856 expand_builtin_unop (enum machine_mode target_mode, tree exp, rtx target,
4857                      rtx subtarget, optab op_optab)
4858 {
4859   rtx op0;
4860
4861   if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE))
4862     return NULL_RTX;
4863
4864   /* Compute the argument.  */
4865   op0 = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
4866                      VOIDmode, EXPAND_NORMAL);
4867   /* Compute op, into TARGET if possible.
4868      Set TARGET to wherever the result comes back.  */
4869   target = expand_unop (TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 0))),
4870                         op_optab, op0, target, 1);
4871   gcc_assert (target);
4872
4873   return convert_to_mode (target_mode, target, 0);
4874 }
4875
4876 /* Expand a call to __builtin_expect.  We just return our argument 
4877    as the builtin_expect semantic should've been already executed by
4878    tree branch prediction pass. */
4879
4880 static rtx
4881 expand_builtin_expect (tree exp, rtx target)
4882 {
4883   tree arg;
4884
4885   if (call_expr_nargs (exp) < 2)
4886     return const0_rtx;
4887   arg = CALL_EXPR_ARG (exp, 0);
4888
4889   target = expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4890   /* When guessing was done, the hints should be already stripped away.  */
4891   gcc_assert (!flag_guess_branch_prob
4892               || optimize == 0 || errorcount || sorrycount);
4893   return target;
4894 }
4895
4896 void
4897 expand_builtin_trap (void)
4898 {
4899 #ifdef HAVE_trap
4900   if (HAVE_trap)
4901     emit_insn (gen_trap ());
4902   else
4903 #endif
4904     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4905   emit_barrier ();
4906 }
4907
4908 /* Expand a call to __builtin_unreachable.  We do nothing except emit
4909    a barrier saying that control flow will not pass here.
4910
4911    It is the responsibility of the program being compiled to ensure
4912    that control flow does never reach __builtin_unreachable.  */
4913 static void
4914 expand_builtin_unreachable (void)
4915 {
4916   emit_barrier ();
4917 }
4918
4919 /* Expand EXP, a call to fabs, fabsf or fabsl.
4920    Return NULL_RTX if a normal call should be emitted rather than expanding
4921    the function inline.  If convenient, the result should be placed
4922    in TARGET.  SUBTARGET may be used as the target for computing
4923    the operand.  */
4924
4925 static rtx
4926 expand_builtin_fabs (tree exp, rtx target, rtx subtarget)
4927 {
4928   enum machine_mode mode;
4929   tree arg;
4930   rtx op0;
4931
4932   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
4933     return NULL_RTX;
4934
4935   arg = CALL_EXPR_ARG (exp, 0);
4936   CALL_EXPR_ARG (exp, 0) = arg = builtin_save_expr (arg);
4937   mode = TYPE_MODE (TREE_TYPE (arg));
4938   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4939   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4940 }
4941
4942 /* Expand EXP, a call to copysign, copysignf, or copysignl.
4943    Return NULL is a normal call should be emitted rather than expanding the
4944    function inline.  If convenient, the result should be placed in TARGET.
4945    SUBTARGET may be used as the target for computing the operand.  */
4946
4947 static rtx
4948 expand_builtin_copysign (tree exp, rtx target, rtx subtarget)
4949 {
4950   rtx op0, op1;
4951   tree arg;
4952
4953   if (!validate_arglist (exp, REAL_TYPE, REAL_TYPE, VOID_TYPE))
4954     return NULL_RTX;
4955
4956   arg = CALL_EXPR_ARG (exp, 0);
4957   op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
4958
4959   arg = CALL_EXPR_ARG (exp, 1);
4960   op1 = expand_normal (arg);
4961
4962   return expand_copysign (op0, op1, target);
4963 }
4964
4965 /* Create a new constant string literal and return a char* pointer to it.
4966    The STRING_CST value is the LEN characters at STR.  */
4967 tree
4968 build_string_literal (int len, const char *str)
4969 {
4970   tree t, elem, index, type;
4971
4972   t = build_string (len, str);
4973   elem = build_type_variant (char_type_node, 1, 0);
4974   index = build_index_type (size_int (len - 1));
4975   type = build_array_type (elem, index);
4976   TREE_TYPE (t) = type;
4977   TREE_CONSTANT (t) = 1;
4978   TREE_READONLY (t) = 1;
4979   TREE_STATIC (t) = 1;
4980
4981   type = build_pointer_type (elem);
4982   t = build1 (ADDR_EXPR, type,
4983               build4 (ARRAY_REF, elem,
4984                       t, integer_zero_node, NULL_TREE, NULL_TREE));
4985   return t;
4986 }
4987
4988 /* Expand EXP, a call to printf or printf_unlocked.
4989    Return NULL_RTX if a normal call should be emitted rather than transforming
4990    the function inline.  If convenient, the result should be placed in
4991    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4992    call.  */
4993 static rtx
4994 expand_builtin_printf (tree exp, rtx target, enum machine_mode mode,
4995                        bool unlocked)
4996 {
4997   /* If we're using an unlocked function, assume the other unlocked
4998      functions exist explicitly.  */
4999   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
5000     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
5001   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
5002     : implicit_built_in_decls[BUILT_IN_PUTS];
5003   const char *fmt_str;
5004   tree fn = 0;
5005   tree fmt, arg;
5006   int nargs = call_expr_nargs (exp);
5007
5008   /* If the return value is used, don't do the transformation.  */
5009   if (target != const0_rtx)
5010     return NULL_RTX;
5011
5012   /* Verify the required arguments in the original call.  */
5013   if (nargs == 0)
5014     return NULL_RTX;
5015   fmt = CALL_EXPR_ARG (exp, 0);
5016   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5017     return NULL_RTX;
5018
5019   /* Check whether the format is a literal string constant.  */
5020   fmt_str = c_getstr (fmt);
5021   if (fmt_str == NULL)
5022     return NULL_RTX;
5023
5024   if (!init_target_chars ())
5025     return NULL_RTX;
5026
5027   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
5028   if (strcmp (fmt_str, target_percent_s_newline) == 0)
5029     {
5030       if ((nargs != 2)
5031           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 1))))
5032         return NULL_RTX;
5033       if (fn_puts)
5034         fn = build_call_nofold (fn_puts, 1, CALL_EXPR_ARG (exp, 1));
5035     }
5036   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
5037   else if (strcmp (fmt_str, target_percent_c) == 0)
5038     {
5039       if ((nargs != 2)
5040           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1))) != INTEGER_TYPE)
5041         return NULL_RTX;
5042       if (fn_putchar)
5043         fn = build_call_nofold (fn_putchar, 1, CALL_EXPR_ARG (exp, 1));
5044     }
5045   else
5046     {
5047       /* We can't handle anything else with % args or %% ... yet.  */
5048       if (strchr (fmt_str, target_percent))
5049         return NULL_RTX;
5050
5051       if (nargs > 1)
5052         return NULL_RTX;
5053
5054       /* If the format specifier was "", printf does nothing.  */
5055       if (fmt_str[0] == '\0')
5056         return const0_rtx;
5057       /* If the format specifier has length of 1, call putchar.  */
5058       if (fmt_str[1] == '\0')
5059         {
5060           /* Given printf("c"), (where c is any one character,)
5061              convert "c"[0] to an int and pass that to the replacement
5062              function.  */
5063           arg = build_int_cst (NULL_TREE, fmt_str[0]);
5064           if (fn_putchar)
5065             fn = build_call_nofold (fn_putchar, 1, arg);
5066         }
5067       else
5068         {
5069           /* If the format specifier was "string\n", call puts("string").  */
5070           size_t len = strlen (fmt_str);
5071           if ((unsigned char)fmt_str[len - 1] == target_newline)
5072             {
5073               /* Create a NUL-terminated string that's one char shorter
5074                  than the original, stripping off the trailing '\n'.  */
5075               char *newstr = XALLOCAVEC (char, len);
5076               memcpy (newstr, fmt_str, len - 1);
5077               newstr[len - 1] = 0;
5078               arg = build_string_literal (len, newstr);
5079               if (fn_puts)
5080                 fn = build_call_nofold (fn_puts, 1, arg);
5081             }
5082           else
5083             /* We'd like to arrange to call fputs(string,stdout) here,
5084                but we need stdout and don't have a way to get it yet.  */
5085             return NULL_RTX;
5086         }
5087     }
5088
5089   if (!fn)
5090     return NULL_RTX;
5091   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5092   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5093   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5094 }
5095
5096 /* Expand EXP, a call to fprintf or fprintf_unlocked.
5097    Return NULL_RTX if a normal call should be emitted rather than transforming
5098    the function inline.  If convenient, the result should be placed in
5099    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5100    call.  */
5101 static rtx
5102 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
5103                         bool unlocked)
5104 {
5105   /* If we're using an unlocked function, assume the other unlocked
5106      functions exist explicitly.  */
5107   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5108     : implicit_built_in_decls[BUILT_IN_FPUTC];
5109   tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5110     : implicit_built_in_decls[BUILT_IN_FPUTS];
5111   const char *fmt_str;
5112   tree fn = 0;
5113   tree fmt, fp, arg;
5114   int nargs = call_expr_nargs (exp);
5115
5116   /* If the return value is used, don't do the transformation.  */
5117   if (target != const0_rtx)
5118     return NULL_RTX;
5119
5120   /* Verify the required arguments in the original call.  */
5121   if (nargs < 2)
5122     return NULL_RTX;
5123   fp = CALL_EXPR_ARG (exp, 0);
5124   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
5125     return NULL_RTX;
5126   fmt = CALL_EXPR_ARG (exp, 1);
5127   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5128     return NULL_RTX;
5129
5130   /* Check whether the format is a literal string constant.  */
5131   fmt_str = c_getstr (fmt);
5132   if (fmt_str == NULL)
5133     return NULL_RTX;
5134
5135   if (!init_target_chars ())
5136     return NULL_RTX;
5137
5138   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5139   if (strcmp (fmt_str, target_percent_s) == 0)
5140     {
5141       if ((nargs != 3)
5142           || ! POINTER_TYPE_P (TREE_TYPE (CALL_EXPR_ARG (exp, 2))))
5143         return NULL_RTX;
5144       arg = CALL_EXPR_ARG (exp, 2);
5145       if (fn_fputs)
5146         fn = build_call_nofold (fn_fputs, 2, arg, fp);
5147     }
5148   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5149   else if (strcmp (fmt_str, target_percent_c) == 0)
5150     {
5151       if ((nargs != 3)
5152           || TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2))) != INTEGER_TYPE)
5153         return NULL_RTX;
5154       arg = CALL_EXPR_ARG (exp, 2);
5155       if (fn_fputc)
5156         fn = build_call_nofold (fn_fputc, 2, arg, fp);
5157     }
5158   else
5159     {
5160       /* We can't handle anything else with % args or %% ... yet.  */
5161       if (strchr (fmt_str, target_percent))
5162         return NULL_RTX;
5163
5164       if (nargs > 2)
5165         return NULL_RTX;
5166
5167       /* If the format specifier was "", fprintf does nothing.  */
5168       if (fmt_str[0] == '\0')
5169         {
5170           /* Evaluate and ignore FILE* argument for side-effects.  */
5171           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5172           return const0_rtx;
5173         }
5174
5175       /* When "string" doesn't contain %, replace all cases of
5176          fprintf(stream,string) with fputs(string,stream).  The fputs
5177          builtin will take care of special cases like length == 1.  */
5178       if (fn_fputs)
5179         fn = build_call_nofold (fn_fputs, 2, fmt, fp);
5180     }
5181
5182   if (!fn)
5183     return NULL_RTX;
5184   gcc_assert (TREE_CODE (fn) == CALL_EXPR);
5185   CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5186   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5187 }
5188
5189 /* Expand a call EXP to sprintf.  Return NULL_RTX if
5190    a normal call should be emitted rather than expanding the function
5191    inline.  If convenient, the result should be placed in TARGET with
5192    mode MODE.  */
5193
5194 static rtx
5195 expand_builtin_sprintf (tree exp, rtx target, enum machine_mode mode)
5196 {
5197   tree dest, fmt;
5198   const char *fmt_str;
5199   int nargs = call_expr_nargs (exp);
5200
5201   /* Verify the required arguments in the original call.  */
5202   if (nargs < 2)
5203     return NULL_RTX;
5204   dest = CALL_EXPR_ARG (exp, 0);
5205   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5206     return NULL_RTX;
5207   fmt = CALL_EXPR_ARG (exp, 0);
5208   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5209     return NULL_RTX;
5210
5211   /* Check whether the format is a literal string constant.  */
5212   fmt_str = c_getstr (fmt);
5213   if (fmt_str == NULL)
5214     return NULL_RTX;
5215
5216   if (!init_target_chars ())
5217     return NULL_RTX;
5218
5219   /* If the format doesn't contain % args or %%, use strcpy.  */
5220   if (strchr (fmt_str, target_percent) == 0)
5221     {
5222       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5223       tree exp;
5224
5225       if ((nargs > 2) || ! fn)
5226         return NULL_RTX;
5227       expand_expr (build_call_nofold (fn, 2, dest, fmt),
5228                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5229       if (target == const0_rtx)
5230         return const0_rtx;
5231       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5232       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5233     }
5234   /* If the format is "%s", use strcpy if the result isn't used.  */
5235   else if (strcmp (fmt_str, target_percent_s) == 0)
5236     {
5237       tree fn, arg, len;
5238       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5239
5240       if (! fn)
5241         return NULL_RTX;
5242       if (nargs != 3)
5243         return NULL_RTX;
5244       arg = CALL_EXPR_ARG (exp, 2);
5245       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5246         return NULL_RTX;
5247
5248       if (target != const0_rtx)
5249         {
5250           len = c_strlen (arg, 1);
5251           if (! len || TREE_CODE (len) != INTEGER_CST)
5252             return NULL_RTX;
5253         }
5254       else
5255         len = NULL_TREE;
5256
5257       expand_expr (build_call_nofold (fn, 2, dest, arg),
5258                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5259
5260       if (target == const0_rtx)
5261         return const0_rtx;
5262       return expand_expr (len, target, mode, EXPAND_NORMAL);
5263     }
5264
5265   return NULL_RTX;
5266 }
5267
5268 /* Expand a call to either the entry or exit function profiler.  */
5269
5270 static rtx
5271 expand_builtin_profile_func (bool exitp)
5272 {
5273   rtx this_rtx, which;
5274
5275   this_rtx = DECL_RTL (current_function_decl);
5276   gcc_assert (MEM_P (this_rtx));
5277   this_rtx = XEXP (this_rtx, 0);
5278
5279   if (exitp)
5280     which = profile_function_exit_libfunc;
5281   else
5282     which = profile_function_entry_libfunc;
5283
5284   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this_rtx, Pmode,
5285                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5286                                                  0),
5287                      Pmode);
5288
5289   return const0_rtx;
5290 }
5291
5292 /* Expand a call to __builtin___clear_cache.  */
5293
5294 static rtx
5295 expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED)
5296 {
5297 #ifndef HAVE_clear_cache
5298 #ifdef CLEAR_INSN_CACHE
5299   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5300      does something.  Just do the default expansion to a call to
5301      __clear_cache().  */
5302   return NULL_RTX;
5303 #else
5304   /* There is no "clear_cache" insn, and __clear_cache() in libgcc
5305      does nothing.  There is no need to call it.  Do nothing.  */
5306   return const0_rtx;
5307 #endif /* CLEAR_INSN_CACHE */
5308 #else
5309   /* We have a "clear_cache" insn, and it will handle everything.  */
5310   tree begin, end;
5311   rtx begin_rtx, end_rtx;
5312   enum insn_code icode;
5313
5314   /* We must not expand to a library call.  If we did, any
5315      fallback library function in libgcc that might contain a call to
5316      __builtin___clear_cache() would recurse infinitely.  */
5317   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
5318     {
5319       error ("both arguments to %<__builtin___clear_cache%> must be pointers");
5320       return const0_rtx;
5321     }
5322
5323   if (HAVE_clear_cache)
5324     {
5325       icode = CODE_FOR_clear_cache;
5326
5327       begin = CALL_EXPR_ARG (exp, 0);
5328       begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL);
5329       begin_rtx = convert_memory_address (Pmode, begin_rtx);
5330       if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode))
5331         begin_rtx = copy_to_mode_reg (Pmode, begin_rtx);
5332
5333       end = CALL_EXPR_ARG (exp, 1);
5334       end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL);
5335       end_rtx = convert_memory_address (Pmode, end_rtx);
5336       if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode))
5337         end_rtx = copy_to_mode_reg (Pmode, end_rtx);
5338
5339       emit_insn (gen_clear_cache (begin_rtx, end_rtx));
5340     }
5341   return const0_rtx;
5342 #endif /* HAVE_clear_cache */
5343 }
5344
5345 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5346
5347 static rtx
5348 round_trampoline_addr (rtx tramp)
5349 {
5350   rtx temp, addend, mask;
5351
5352   /* If we don't need too much alignment, we'll have been guaranteed
5353      proper alignment by get_trampoline_type.  */
5354   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5355     return tramp;
5356
5357   /* Round address up to desired boundary.  */
5358   temp = gen_reg_rtx (Pmode);
5359   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5360   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5361
5362   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5363                                temp, 0, OPTAB_LIB_WIDEN);
5364   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5365                                temp, 0, OPTAB_LIB_WIDEN);
5366
5367   return tramp;
5368 }
5369
5370 static rtx
5371 expand_builtin_init_trampoline (tree exp)
5372 {
5373   tree t_tramp, t_func, t_chain;
5374   rtx m_tramp, r_tramp, r_chain, tmp;
5375
5376   if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE,
5377                          POINTER_TYPE, VOID_TYPE))
5378     return NULL_RTX;
5379
5380   t_tramp = CALL_EXPR_ARG (exp, 0);
5381   t_func = CALL_EXPR_ARG (exp, 1);
5382   t_chain = CALL_EXPR_ARG (exp, 2);
5383
5384   r_tramp = expand_normal (t_tramp);
5385   m_tramp = gen_rtx_MEM (BLKmode, r_tramp);
5386   MEM_NOTRAP_P (m_tramp) = 1;
5387
5388   /* The TRAMP argument should be the address of a field within the
5389      local function's FRAME decl.  Let's see if we can fill in the
5390      to fill in the MEM_ATTRs for this memory.  */
5391   if (TREE_CODE (t_tramp) == ADDR_EXPR)
5392     set_mem_attributes_minus_bitpos (m_tramp, TREE_OPERAND (t_tramp, 0),
5393                                      true, 0);
5394
5395   tmp = round_trampoline_addr (r_tramp);
5396   if (tmp != r_tramp)
5397     {
5398       m_tramp = change_address (m_tramp, BLKmode, tmp);
5399       set_mem_align (m_tramp, TRAMPOLINE_ALIGNMENT);
5400       set_mem_size (m_tramp, GEN_INT (TRAMPOLINE_SIZE));
5401     }
5402
5403   /* The FUNC argument should be the address of the nested function.
5404      Extract the actual function decl to pass to the hook.  */
5405   gcc_assert (TREE_CODE (t_func) == ADDR_EXPR);
5406   t_func = TREE_OPERAND (t_func, 0);
5407   gcc_assert (TREE_CODE (t_func) == FUNCTION_DECL);
5408
5409   r_chain = expand_normal (t_chain);
5410
5411   /* Generate insns to initialize the trampoline.  */
5412   targetm.calls.trampoline_init (m_tramp, t_func, r_chain);
5413
5414   trampolines_created = 1;
5415   return const0_rtx;
5416 }
5417
5418 static rtx
5419 expand_builtin_adjust_trampoline (tree exp)
5420 {
5421   rtx tramp;
5422
5423   if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
5424     return NULL_RTX;
5425
5426   tramp = expand_normal (CALL_EXPR_ARG (exp, 0));
5427   tramp = round_trampoline_addr (tramp);
5428   if (targetm.calls.trampoline_adjust_address)
5429     tramp = targetm.calls.trampoline_adjust_address (tramp);
5430
5431   return tramp;
5432 }
5433
5434 /* Expand the call EXP to the built-in signbit, signbitf or signbitl
5435    function.  The function first checks whether the back end provides
5436    an insn to implement signbit for the respective mode.  If not, it
5437    checks whether the floating point format of the value is such that
5438    the sign bit can be extracted.  If that is not the case, the
5439    function returns NULL_RTX to indicate that a normal call should be
5440    emitted rather than expanding the function in-line.  EXP is the
5441    expression that is a call to the builtin function; if convenient,
5442    the result should be placed in TARGET.  */
5443 static rtx
5444 expand_builtin_signbit (tree exp, rtx target)
5445 {
5446   const struct real_format *fmt;
5447   enum machine_mode fmode, imode, rmode;
5448   HOST_WIDE_INT hi, lo;
5449   tree arg;
5450   int word, bitpos;
5451   enum insn_code icode;
5452   rtx temp;
5453   location_t loc = EXPR_LOCATION (exp);
5454
5455   if (!validate_arglist (exp, REAL_TYPE, VOID_TYPE))
5456     return NULL_RTX;
5457
5458   arg = CALL_EXPR_ARG (exp, 0);
5459   fmode = TYPE_MODE (TREE_TYPE (arg));
5460   rmode = TYPE_MODE (TREE_TYPE (exp));
5461   fmt = REAL_MODE_FORMAT (fmode);
5462
5463   arg = builtin_save_expr (arg);
5464
5465   /* Expand the argument yielding a RTX expression. */
5466   temp = expand_normal (arg);
5467
5468   /* Check if the back end provides an insn that handles signbit for the
5469      argument's mode. */
5470   icode = signbit_optab->handlers [(int) fmode].insn_code;
5471   if (icode != CODE_FOR_nothing)
5472     {
5473       target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
5474       emit_unop_insn (icode, target, temp, UNKNOWN);
5475       return target;
5476     }
5477
5478   /* For floating point formats without a sign bit, implement signbit
5479      as "ARG < 0.0".  */
5480   bitpos = fmt->signbit_ro;
5481   if (bitpos < 0)
5482   {
5483     /* But we can't do this if the format supports signed zero.  */
5484     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5485       return NULL_RTX;
5486
5487     arg = fold_build2_loc (loc, LT_EXPR, TREE_TYPE (exp), arg,
5488                        build_real (TREE_TYPE (arg), dconst0));
5489     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5490   }
5491
5492   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5493     {
5494       imode = int_mode_for_mode (fmode);
5495       if (imode == BLKmode)
5496         return NULL_RTX;
5497       temp = gen_lowpart (imode, temp);
5498     }
5499   else
5500     {
5501       imode = word_mode;
5502       /* Handle targets with different FP word orders.  */
5503       if (FLOAT_WORDS_BIG_ENDIAN)
5504         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5505       else
5506         word = bitpos / BITS_PER_WORD;
5507       temp = operand_subword_force (temp, word, fmode);
5508       bitpos = bitpos % BITS_PER_WORD;
5509     }
5510
5511   /* Force the intermediate word_mode (or narrower) result into a
5512      register.  This avoids attempting to create paradoxical SUBREGs
5513      of floating point modes below.  */
5514   temp = force_reg (imode, temp);
5515
5516   /* If the bitpos is within the "result mode" lowpart, the operation
5517      can be implement with a single bitwise AND.  Otherwise, we need
5518      a right shift and an AND.  */
5519
5520   if (bitpos < GET_MODE_BITSIZE (rmode))
5521     {
5522       if (bitpos < HOST_BITS_PER_WIDE_INT)
5523         {
5524           hi = 0;
5525           lo = (HOST_WIDE_INT) 1 << bitpos;
5526         }
5527       else
5528         {
5529           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5530           lo = 0;
5531         }
5532
5533       if (GET_MODE_SIZE (imode) > GET_MODE_SIZE (rmode))
5534         temp = gen_lowpart (rmode, temp);
5535       temp = expand_binop (rmode, and_optab, temp,
5536                            immed_double_const (lo, hi, rmode),
5537                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5538     }
5539   else
5540     {
5541       /* Perform a logical right shift to place the signbit in the least
5542          significant bit, then truncate the result to the desired mode
5543          and mask just this bit.  */
5544       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5545                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5546       temp = gen_lowpart (rmode, temp);
5547       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5548                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5549     }
5550
5551   return temp;
5552 }
5553
5554 /* Expand fork or exec calls.  TARGET is the desired target of the
5555    call.  EXP is the call. FN is the
5556    identificator of the actual function.  IGNORE is nonzero if the
5557    value is to be ignored.  */
5558
5559 static rtx
5560 expand_builtin_fork_or_exec (tree fn, tree exp, rtx target, int ignore)
5561 {
5562   tree id, decl;
5563   tree call;
5564
5565   /* If we are not profiling, just call the function.  */
5566   if (!profile_arc_flag)
5567     return NULL_RTX;
5568
5569   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5570      compiler, so the code does not diverge, and the wrapper may run the
5571      code necessary for keeping the profiling sane.  */
5572
5573   switch (DECL_FUNCTION_CODE (fn))
5574     {
5575     case BUILT_IN_FORK:
5576       id = get_identifier ("__gcov_fork");
5577       break;
5578
5579     case BUILT_IN_EXECL:
5580       id = get_identifier ("__gcov_execl");
5581       break;
5582
5583     case BUILT_IN_EXECV:
5584       id = get_identifier ("__gcov_execv");
5585       break;
5586
5587     case BUILT_IN_EXECLP:
5588       id = get_identifier ("__gcov_execlp");
5589       break;
5590
5591     case BUILT_IN_EXECLE:
5592       id = get_identifier ("__gcov_execle");
5593       break;
5594
5595     case BUILT_IN_EXECVP:
5596       id = get_identifier ("__gcov_execvp");
5597       break;
5598
5599     case BUILT_IN_EXECVE:
5600       id = get_identifier ("__gcov_execve");
5601       break;
5602
5603     default:
5604       gcc_unreachable ();
5605     }
5606
5607   decl = build_decl (DECL_SOURCE_LOCATION (fn),
5608                      FUNCTION_DECL, id, TREE_TYPE (fn));
5609   DECL_EXTERNAL (decl) = 1;
5610   TREE_PUBLIC (decl) = 1;
5611   DECL_ARTIFICIAL (decl) = 1;
5612   TREE_NOTHROW (decl) = 1;
5613   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
5614   DECL_VISIBILITY_SPECIFIED (decl) = 1;
5615   call = rewrite_call_expr (EXPR_LOCATION (exp), exp, 0, decl, 0);
5616   return expand_call (call, target, ignore);
5617  }
5618   
5619
5620 \f
5621 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5622    the pointer in these functions is void*, the tree optimizers may remove
5623    casts.  The mode computed in expand_builtin isn't reliable either, due
5624    to __sync_bool_compare_and_swap.
5625
5626    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5627    group of builtins.  This gives us log2 of the mode size.  */
5628
5629 static inline enum machine_mode
5630 get_builtin_sync_mode (int fcode_diff)
5631 {
5632   /* The size is not negotiable, so ask not to get BLKmode in return
5633      if the target indicates that a smaller size would be better.  */
5634   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5635 }
5636
5637 /* Expand the memory expression LOC and return the appropriate memory operand
5638    for the builtin_sync operations.  */
5639
5640 static rtx
5641 get_builtin_sync_mem (tree loc, enum machine_mode mode)
5642 {
5643   rtx addr, mem;
5644
5645   addr = expand_expr (loc, NULL_RTX, ptr_mode, EXPAND_SUM);
5646   addr = convert_memory_address (Pmode, addr);
5647
5648   /* Note that we explicitly do not want any alias information for this
5649      memory, so that we kill all other live memories.  Otherwise we don't
5650      satisfy the full barrier semantics of the intrinsic.  */
5651   mem = validize_mem (gen_rtx_MEM (mode, addr));
5652
5653   set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
5654   set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
5655   MEM_VOLATILE_P (mem) = 1;
5656
5657   return mem;
5658 }
5659
5660 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5661    EXP is the CALL_EXPR.  CODE is the rtx code
5662    that corresponds to the arithmetic or logical operation from the name;
5663    an exception here is that NOT actually means NAND.  TARGET is an optional
5664    place for us to store the results; AFTER is true if this is the
5665    fetch_and_xxx form.  IGNORE is true if we don't actually care about
5666    the result of the operation at all.  */
5667
5668 static rtx
5669 expand_builtin_sync_operation (enum machine_mode mode, tree exp,
5670                                enum rtx_code code, bool after,
5671                                rtx target, bool ignore)
5672 {
5673   rtx val, mem;
5674   enum machine_mode old_mode;
5675   location_t loc = EXPR_LOCATION (exp);
5676
5677   if (code == NOT && warn_sync_nand)
5678     {
5679       tree fndecl = get_callee_fndecl (exp);
5680       enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5681
5682       static bool warned_f_a_n, warned_n_a_f;
5683
5684       switch (fcode)
5685         {
5686         case BUILT_IN_FETCH_AND_NAND_1:
5687         case BUILT_IN_FETCH_AND_NAND_2:
5688         case BUILT_IN_FETCH_AND_NAND_4:
5689         case BUILT_IN_FETCH_AND_NAND_8:
5690         case BUILT_IN_FETCH_AND_NAND_16:
5691
5692           if (warned_f_a_n)
5693             break;
5694
5695           fndecl = implicit_built_in_decls[BUILT_IN_FETCH_AND_NAND_N];
5696           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5697           warned_f_a_n = true;
5698           break;
5699
5700         case BUILT_IN_NAND_AND_FETCH_1:
5701         case BUILT_IN_NAND_AND_FETCH_2:
5702         case BUILT_IN_NAND_AND_FETCH_4:
5703         case BUILT_IN_NAND_AND_FETCH_8:
5704         case BUILT_IN_NAND_AND_FETCH_16:
5705
5706           if (warned_n_a_f)
5707             break;
5708
5709           fndecl = implicit_built_in_decls[BUILT_IN_NAND_AND_FETCH_N];
5710           inform (loc, "%qD changed semantics in GCC 4.4", fndecl);
5711           warned_n_a_f = true;
5712           break;
5713
5714         default:
5715           gcc_unreachable ();
5716         }
5717     }
5718
5719   /* Expand the operands.  */
5720   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5721
5722   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5723   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5724      of CONST_INTs, where we know the old_mode only from the call argument.  */
5725   old_mode = GET_MODE (val);
5726   if (old_mode == VOIDmode)
5727     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5728   val = convert_modes (mode, old_mode, val, 1);
5729
5730   if (ignore)
5731     return expand_sync_operation (mem, val, code);
5732   else
5733     return expand_sync_fetch_operation (mem, val, code, after, target);
5734 }
5735
5736 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5737    intrinsics. EXP is the CALL_EXPR.  IS_BOOL is
5738    true if this is the boolean form.  TARGET is a place for us to store the
5739    results; this is NOT optional if IS_BOOL is true.  */
5740
5741 static rtx
5742 expand_builtin_compare_and_swap (enum machine_mode mode, tree exp,
5743                                  bool is_bool, rtx target)
5744 {
5745   rtx old_val, new_val, mem;
5746   enum machine_mode old_mode;
5747
5748   /* Expand the operands.  */
5749   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5750
5751
5752   old_val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX,
5753                          mode, EXPAND_NORMAL);
5754   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5755      of CONST_INTs, where we know the old_mode only from the call argument.  */
5756   old_mode = GET_MODE (old_val);
5757   if (old_mode == VOIDmode)
5758     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5759   old_val = convert_modes (mode, old_mode, old_val, 1);
5760
5761   new_val = expand_expr (CALL_EXPR_ARG (exp, 2), NULL_RTX,
5762                          mode, EXPAND_NORMAL);
5763   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5764      of CONST_INTs, where we know the old_mode only from the call argument.  */
5765   old_mode = GET_MODE (new_val);
5766   if (old_mode == VOIDmode)
5767     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 2)));
5768   new_val = convert_modes (mode, old_mode, new_val, 1);
5769
5770   if (is_bool)
5771     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5772   else
5773     return expand_val_compare_and_swap (mem, old_val, new_val, target);
5774 }
5775
5776 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5777    general form is actually an atomic exchange, and some targets only
5778    support a reduced form with the second argument being a constant 1.
5779    EXP is the CALL_EXPR; TARGET is an optional place for us to store 
5780    the results.  */
5781
5782 static rtx
5783 expand_builtin_lock_test_and_set (enum machine_mode mode, tree exp,
5784                                   rtx target)
5785 {
5786   rtx val, mem;
5787   enum machine_mode old_mode;
5788
5789   /* Expand the operands.  */
5790   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5791   val = expand_expr (CALL_EXPR_ARG (exp, 1), NULL_RTX, mode, EXPAND_NORMAL);
5792   /* If VAL is promoted to a wider mode, convert it back to MODE.  Take care
5793      of CONST_INTs, where we know the old_mode only from the call argument.  */
5794   old_mode = GET_MODE (val);
5795   if (old_mode == VOIDmode)
5796     old_mode = TYPE_MODE (TREE_TYPE (CALL_EXPR_ARG (exp, 1)));
5797   val = convert_modes (mode, old_mode, val, 1);
5798
5799   return expand_sync_lock_test_and_set (mem, val, target);
5800 }
5801
5802 /* Expand the __sync_synchronize intrinsic.  */
5803
5804 static void
5805 expand_builtin_synchronize (void)
5806 {
5807   gimple x;
5808   VEC (tree, gc) *v_clobbers;
5809
5810 #ifdef HAVE_memory_barrier
5811   if (HAVE_memory_barrier)
5812     {
5813       emit_insn (gen_memory_barrier ());
5814       return;
5815     }
5816 #endif
5817
5818   if (synchronize_libfunc != NULL_RTX)
5819     {
5820       emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5821       return;
5822     }
5823
5824   /* If no explicit memory barrier instruction is available, create an
5825      empty asm stmt with a memory clobber.  */
5826   v_clobbers = VEC_alloc (tree, gc, 1);
5827   VEC_quick_push (tree, v_clobbers,
5828                   tree_cons (NULL, build_string (6, "memory"), NULL));
5829   x = gimple_build_asm_vec ("", NULL, NULL, v_clobbers, NULL);
5830   gimple_asm_set_volatile (x, true);
5831   expand_asm_stmt (x);
5832 }
5833
5834 /* Expand the __sync_lock_release intrinsic.  EXP is the CALL_EXPR.  */
5835
5836 static void
5837 expand_builtin_lock_release (enum machine_mode mode, tree exp)
5838 {
5839   enum insn_code icode;
5840   rtx mem, insn;
5841   rtx val = const0_rtx;
5842
5843   /* Expand the operands.  */
5844   mem = get_builtin_sync_mem (CALL_EXPR_ARG (exp, 0), mode);
5845
5846   /* If there is an explicit operation in the md file, use it.  */
5847   icode = sync_lock_release[mode];
5848   if (icode != CODE_FOR_nothing)
5849     {
5850       if (!insn_data[icode].operand[1].predicate (val, mode))
5851         val = force_reg (mode, val);
5852
5853       insn = GEN_FCN (icode) (mem, val);
5854       if (insn)
5855         {
5856           emit_insn (insn);
5857           return;
5858         }
5859     }
5860
5861   /* Otherwise we can implement this operation by emitting a barrier
5862      followed by a store of zero.  */
5863   expand_builtin_synchronize ();
5864   emit_move_insn (mem, val);
5865 }
5866 \f
5867 /* Expand an expression EXP that calls a built-in function,
5868    with result going to TARGET if that's convenient
5869    (and in mode MODE if that's convenient).
5870    SUBTARGET may be used as the target for computing one of EXP's operands.
5871    IGNORE is nonzero if the value is to be ignored.  */
5872
5873 rtx
5874 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5875                 int ignore)
5876 {
5877   tree fndecl = get_callee_fndecl (exp);
5878   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5879   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5880
5881   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5882     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5883
5884   /* When not optimizing, generate calls to library functions for a certain
5885      set of builtins.  */
5886   if (!optimize
5887       && !called_as_built_in (fndecl)
5888       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5889       && fcode != BUILT_IN_ALLOCA
5890       && fcode != BUILT_IN_FREE)
5891     return expand_call (exp, target, ignore);
5892
5893   /* The built-in function expanders test for target == const0_rtx
5894      to determine whether the function's result will be ignored.  */
5895   if (ignore)
5896     target = const0_rtx;
5897
5898   /* If the result of a pure or const built-in function is ignored, and
5899      none of its arguments are volatile, we can avoid expanding the
5900      built-in call and just evaluate the arguments for side-effects.  */
5901   if (target == const0_rtx
5902       && (DECL_PURE_P (fndecl) || TREE_READONLY (fndecl)))
5903     {
5904       bool volatilep = false;
5905       tree arg;
5906       call_expr_arg_iterator iter;
5907
5908       FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5909         if (TREE_THIS_VOLATILE (arg))
5910           {
5911             volatilep = true;
5912             break;
5913           }
5914
5915       if (! volatilep)
5916         {
5917           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
5918             expand_expr (arg, const0_rtx, VOIDmode, EXPAND_NORMAL);
5919           return const0_rtx;
5920         }
5921     }
5922
5923   switch (fcode)
5924     {
5925     CASE_FLT_FN (BUILT_IN_FABS):
5926       target = expand_builtin_fabs (exp, target, subtarget);
5927       if (target)
5928         return target;
5929       break;
5930
5931     CASE_FLT_FN (BUILT_IN_COPYSIGN):
5932       target = expand_builtin_copysign (exp, target, subtarget);
5933       if (target)
5934         return target;
5935       break;
5936
5937       /* Just do a normal library call if we were unable to fold
5938          the values.  */
5939     CASE_FLT_FN (BUILT_IN_CABS):
5940       break;
5941
5942     CASE_FLT_FN (BUILT_IN_EXP):
5943     CASE_FLT_FN (BUILT_IN_EXP10):
5944     CASE_FLT_FN (BUILT_IN_POW10):
5945     CASE_FLT_FN (BUILT_IN_EXP2):
5946     CASE_FLT_FN (BUILT_IN_EXPM1):
5947     CASE_FLT_FN (BUILT_IN_LOGB):
5948     CASE_FLT_FN (BUILT_IN_LOG):
5949     CASE_FLT_FN (BUILT_IN_LOG10):
5950     CASE_FLT_FN (BUILT_IN_LOG2):
5951     CASE_FLT_FN (BUILT_IN_LOG1P):
5952     CASE_FLT_FN (BUILT_IN_TAN):
5953     CASE_FLT_FN (BUILT_IN_ASIN):
5954     CASE_FLT_FN (BUILT_IN_ACOS):
5955     CASE_FLT_FN (BUILT_IN_ATAN):
5956     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
5957       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5958          because of possible accuracy problems.  */
5959       if (! flag_unsafe_math_optimizations)
5960         break;
5961     CASE_FLT_FN (BUILT_IN_SQRT):
5962     CASE_FLT_FN (BUILT_IN_FLOOR):
5963     CASE_FLT_FN (BUILT_IN_CEIL):
5964     CASE_FLT_FN (BUILT_IN_TRUNC):
5965     CASE_FLT_FN (BUILT_IN_ROUND):
5966     CASE_FLT_FN (BUILT_IN_NEARBYINT):
5967     CASE_FLT_FN (BUILT_IN_RINT):
5968       target = expand_builtin_mathfn (exp, target, subtarget);
5969       if (target)
5970         return target;
5971       break;
5972
5973     CASE_FLT_FN (BUILT_IN_ILOGB):
5974       if (! flag_unsafe_math_optimizations)
5975         break;
5976     CASE_FLT_FN (BUILT_IN_ISINF):
5977     CASE_FLT_FN (BUILT_IN_FINITE):
5978     case BUILT_IN_ISFINITE:
5979     case BUILT_IN_ISNORMAL:
5980       target = expand_builtin_interclass_mathfn (exp, target, subtarget);
5981       if (target)
5982         return target;
5983       break;
5984
5985     CASE_FLT_FN (BUILT_IN_LCEIL):
5986     CASE_FLT_FN (BUILT_IN_LLCEIL):
5987     CASE_FLT_FN (BUILT_IN_LFLOOR):
5988     CASE_FLT_FN (BUILT_IN_LLFLOOR):
5989       target = expand_builtin_int_roundingfn (exp, target);
5990       if (target)
5991         return target;
5992       break;
5993
5994     CASE_FLT_FN (BUILT_IN_LRINT):
5995     CASE_FLT_FN (BUILT_IN_LLRINT):
5996     CASE_FLT_FN (BUILT_IN_LROUND):
5997     CASE_FLT_FN (BUILT_IN_LLROUND):
5998       target = expand_builtin_int_roundingfn_2 (exp, target);
5999       if (target)
6000         return target;
6001       break;
6002
6003     CASE_FLT_FN (BUILT_IN_POW):
6004       target = expand_builtin_pow (exp, target, subtarget);
6005       if (target)
6006         return target;
6007       break;
6008
6009     CASE_FLT_FN (BUILT_IN_POWI):
6010       target = expand_builtin_powi (exp, target, subtarget);
6011       if (target)
6012         return target;
6013       break;
6014
6015     CASE_FLT_FN (BUILT_IN_ATAN2):
6016     CASE_FLT_FN (BUILT_IN_LDEXP):
6017     CASE_FLT_FN (BUILT_IN_SCALB):
6018     CASE_FLT_FN (BUILT_IN_SCALBN):
6019     CASE_FLT_FN (BUILT_IN_SCALBLN):
6020       if (! flag_unsafe_math_optimizations)
6021         break;
6022
6023     CASE_FLT_FN (BUILT_IN_FMOD):
6024     CASE_FLT_FN (BUILT_IN_REMAINDER):
6025     CASE_FLT_FN (BUILT_IN_DREM):
6026       target = expand_builtin_mathfn_2 (exp, target, subtarget);
6027       if (target)
6028         return target;
6029       break;
6030
6031     CASE_FLT_FN (BUILT_IN_CEXPI):
6032       target = expand_builtin_cexpi (exp, target, subtarget);
6033       gcc_assert (target);
6034       return target;
6035
6036     CASE_FLT_FN (BUILT_IN_SIN):
6037     CASE_FLT_FN (BUILT_IN_COS):
6038       if (! flag_unsafe_math_optimizations)
6039         break;
6040       target = expand_builtin_mathfn_3 (exp, target, subtarget);
6041       if (target)
6042         return target;
6043       break;
6044
6045     CASE_FLT_FN (BUILT_IN_SINCOS):
6046       if (! flag_unsafe_math_optimizations)
6047         break;
6048       target = expand_builtin_sincos (exp);
6049       if (target)
6050         return target;
6051       break;
6052
6053     case BUILT_IN_APPLY_ARGS:
6054       return expand_builtin_apply_args ();
6055
6056       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
6057          FUNCTION with a copy of the parameters described by
6058          ARGUMENTS, and ARGSIZE.  It returns a block of memory
6059          allocated on the stack into which is stored all the registers
6060          that might possibly be used for returning the result of a
6061          function.  ARGUMENTS is the value returned by
6062          __builtin_apply_args.  ARGSIZE is the number of bytes of
6063          arguments that must be copied.  ??? How should this value be
6064          computed?  We'll also need a safe worst case value for varargs
6065          functions.  */
6066     case BUILT_IN_APPLY:
6067       if (!validate_arglist (exp, POINTER_TYPE,
6068                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
6069           && !validate_arglist (exp, REFERENCE_TYPE,
6070                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6071         return const0_rtx;
6072       else
6073         {
6074           rtx ops[3];
6075
6076           ops[0] = expand_normal (CALL_EXPR_ARG (exp, 0));
6077           ops[1] = expand_normal (CALL_EXPR_ARG (exp, 1));
6078           ops[2] = expand_normal (CALL_EXPR_ARG (exp, 2));
6079
6080           return expand_builtin_apply (ops[0], ops[1], ops[2]);
6081         }
6082
6083       /* __builtin_return (RESULT) causes the function to return the
6084          value described by RESULT.  RESULT is address of the block of
6085          memory returned by __builtin_apply.  */
6086     case BUILT_IN_RETURN:
6087       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6088         expand_builtin_return (expand_normal (CALL_EXPR_ARG (exp, 0)));
6089       return const0_rtx;
6090
6091     case BUILT_IN_SAVEREGS:
6092       return expand_builtin_saveregs ();
6093
6094     case BUILT_IN_ARGS_INFO:
6095       return expand_builtin_args_info (exp);
6096
6097     case BUILT_IN_VA_ARG_PACK:
6098       /* All valid uses of __builtin_va_arg_pack () are removed during
6099          inlining.  */
6100       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
6101       return const0_rtx;
6102
6103     case BUILT_IN_VA_ARG_PACK_LEN:
6104       /* All valid uses of __builtin_va_arg_pack_len () are removed during
6105          inlining.  */
6106       error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
6107       return const0_rtx;
6108
6109       /* Return the address of the first anonymous stack arg.  */
6110     case BUILT_IN_NEXT_ARG:
6111       if (fold_builtin_next_arg (exp, false))
6112         return const0_rtx;
6113       return expand_builtin_next_arg ();
6114
6115     case BUILT_IN_CLEAR_CACHE:
6116       target = expand_builtin___clear_cache (exp);
6117       if (target)
6118         return target;
6119       break;
6120
6121     case BUILT_IN_CLASSIFY_TYPE:
6122       return expand_builtin_classify_type (exp);
6123
6124     case BUILT_IN_CONSTANT_P:
6125       return const0_rtx;
6126
6127     case BUILT_IN_FRAME_ADDRESS:
6128     case BUILT_IN_RETURN_ADDRESS:
6129       return expand_builtin_frame_address (fndecl, exp);
6130
6131     /* Returns the address of the area where the structure is returned.
6132        0 otherwise.  */
6133     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
6134       if (call_expr_nargs (exp) != 0
6135           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
6136           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
6137         return const0_rtx;
6138       else
6139         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
6140
6141     case BUILT_IN_ALLOCA:
6142       target = expand_builtin_alloca (exp, target);
6143       if (target)
6144         return target;
6145       break;
6146
6147     case BUILT_IN_STACK_SAVE:
6148       return expand_stack_save ();
6149
6150     case BUILT_IN_STACK_RESTORE:
6151       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
6152       return const0_rtx;
6153
6154     case BUILT_IN_BSWAP32:
6155     case BUILT_IN_BSWAP64:
6156       target = expand_builtin_bswap (exp, target, subtarget);
6157
6158       if (target)
6159         return target;
6160       break;
6161
6162     CASE_INT_FN (BUILT_IN_FFS):
6163     case BUILT_IN_FFSIMAX:
6164       target = expand_builtin_unop (target_mode, exp, target,
6165                                     subtarget, ffs_optab);
6166       if (target)
6167         return target;
6168       break;
6169
6170     CASE_INT_FN (BUILT_IN_CLZ):
6171     case BUILT_IN_CLZIMAX:
6172       target = expand_builtin_unop (target_mode, exp, target,
6173                                     subtarget, clz_optab);
6174       if (target)
6175         return target;
6176       break;
6177
6178     CASE_INT_FN (BUILT_IN_CTZ):
6179     case BUILT_IN_CTZIMAX:
6180       target = expand_builtin_unop (target_mode, exp, target,
6181                                     subtarget, ctz_optab);
6182       if (target)
6183         return target;
6184       break;
6185
6186     CASE_INT_FN (BUILT_IN_POPCOUNT):
6187     case BUILT_IN_POPCOUNTIMAX:
6188       target = expand_builtin_unop (target_mode, exp, target,
6189                                     subtarget, popcount_optab);
6190       if (target)
6191         return target;
6192       break;
6193
6194     CASE_INT_FN (BUILT_IN_PARITY):
6195     case BUILT_IN_PARITYIMAX:
6196       target = expand_builtin_unop (target_mode, exp, target,
6197                                     subtarget, parity_optab);
6198       if (target)
6199         return target;
6200       break;
6201
6202     case BUILT_IN_STRLEN:
6203       target = expand_builtin_strlen (exp, target, target_mode);
6204       if (target)
6205         return target;
6206       break;
6207
6208     case BUILT_IN_STRCPY:
6209       target = expand_builtin_strcpy (exp, target);
6210       if (target)
6211         return target;
6212       break;
6213
6214     case BUILT_IN_STRNCPY:
6215       target = expand_builtin_strncpy (exp, target);
6216       if (target)
6217         return target;
6218       break;
6219
6220     case BUILT_IN_STPCPY:
6221       target = expand_builtin_stpcpy (exp, target, mode);
6222       if (target)
6223         return target;
6224       break;
6225
6226     case BUILT_IN_MEMCPY:
6227       target = expand_builtin_memcpy (exp, target);
6228       if (target)
6229         return target;
6230       break;
6231
6232     case BUILT_IN_MEMPCPY:
6233       target = expand_builtin_mempcpy (exp, target, mode);
6234       if (target)
6235         return target;
6236       break;
6237
6238     case BUILT_IN_MEMSET:
6239       target = expand_builtin_memset (exp, target, mode);
6240       if (target)
6241         return target;
6242       break;
6243
6244     case BUILT_IN_BZERO:
6245       target = expand_builtin_bzero (exp);
6246       if (target)
6247         return target;
6248       break;
6249
6250     case BUILT_IN_STRCMP:
6251       target = expand_builtin_strcmp (exp, target);
6252       if (target)
6253         return target;
6254       break;
6255
6256     case BUILT_IN_STRNCMP:
6257       target = expand_builtin_strncmp (exp, target, mode);
6258       if (target)
6259         return target;
6260       break;
6261
6262     case BUILT_IN_BCMP:
6263     case BUILT_IN_MEMCMP:
6264       target = expand_builtin_memcmp (exp, target, mode);
6265       if (target)
6266         return target;
6267       break;
6268
6269     case BUILT_IN_SETJMP:
6270       /* This should have been lowered to the builtins below.  */
6271       gcc_unreachable ();
6272
6273     case BUILT_IN_SETJMP_SETUP:
6274       /* __builtin_setjmp_setup is passed a pointer to an array of five words
6275           and the receiver label.  */
6276       if (validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6277         {
6278           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6279                                       VOIDmode, EXPAND_NORMAL);
6280           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 1), 0);
6281           rtx label_r = label_rtx (label);
6282
6283           /* This is copied from the handling of non-local gotos.  */
6284           expand_builtin_setjmp_setup (buf_addr, label_r);
6285           nonlocal_goto_handler_labels
6286             = gen_rtx_EXPR_LIST (VOIDmode, label_r,
6287                                  nonlocal_goto_handler_labels);
6288           /* ??? Do not let expand_label treat us as such since we would
6289              not want to be both on the list of non-local labels and on
6290              the list of forced labels.  */
6291           FORCED_LABEL (label) = 0;
6292           return const0_rtx;
6293         }
6294       break;
6295
6296     case BUILT_IN_SETJMP_DISPATCHER:
6297        /* __builtin_setjmp_dispatcher is passed the dispatcher label.  */
6298       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6299         {
6300           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6301           rtx label_r = label_rtx (label);
6302
6303           /* Remove the dispatcher label from the list of non-local labels
6304              since the receiver labels have been added to it above.  */
6305           remove_node_from_expr_list (label_r, &nonlocal_goto_handler_labels);
6306           return const0_rtx;
6307         }
6308       break;
6309
6310     case BUILT_IN_SETJMP_RECEIVER:
6311        /* __builtin_setjmp_receiver is passed the receiver label.  */
6312       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6313         {
6314           tree label = TREE_OPERAND (CALL_EXPR_ARG (exp, 0), 0);
6315           rtx label_r = label_rtx (label);
6316
6317           expand_builtin_setjmp_receiver (label_r);
6318           return const0_rtx;
6319         }
6320       break;
6321
6322       /* __builtin_longjmp is passed a pointer to an array of five words.
6323          It's similar to the C library longjmp function but works with
6324          __builtin_setjmp above.  */
6325     case BUILT_IN_LONGJMP:
6326       if (validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6327         {
6328           rtx buf_addr = expand_expr (CALL_EXPR_ARG (exp, 0), subtarget,
6329                                       VOIDmode, EXPAND_NORMAL);
6330           rtx value = expand_normal (CALL_EXPR_ARG (exp, 1));
6331
6332           if (value != const1_rtx)
6333             {
6334               error ("%<__builtin_longjmp%> second argument must be 1");
6335               return const0_rtx;
6336             }
6337
6338           expand_builtin_longjmp (buf_addr, value);
6339           return const0_rtx;
6340         }
6341       break;
6342
6343     case BUILT_IN_NONLOCAL_GOTO:
6344       target = expand_builtin_nonlocal_goto (exp);
6345       if (target)
6346         return target;
6347       break;
6348
6349       /* This updates the setjmp buffer that is its argument with the value
6350          of the current stack pointer.  */
6351     case BUILT_IN_UPDATE_SETJMP_BUF:
6352       if (validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
6353         {
6354           rtx buf_addr
6355             = expand_normal (CALL_EXPR_ARG (exp, 0));
6356
6357           expand_builtin_update_setjmp_buf (buf_addr);
6358           return const0_rtx;
6359         }
6360       break;
6361
6362     case BUILT_IN_TRAP:
6363       expand_builtin_trap ();
6364       return const0_rtx;
6365
6366     case BUILT_IN_UNREACHABLE:
6367       expand_builtin_unreachable ();
6368       return const0_rtx;
6369
6370     case BUILT_IN_PRINTF:
6371       target = expand_builtin_printf (exp, target, mode, false);
6372       if (target)
6373         return target;
6374       break;
6375
6376     case BUILT_IN_PRINTF_UNLOCKED:
6377       target = expand_builtin_printf (exp, target, mode, true);
6378       if (target)
6379         return target;
6380       break;
6381
6382     case BUILT_IN_FPRINTF:
6383       target = expand_builtin_fprintf (exp, target, mode, false);
6384       if (target)
6385         return target;
6386       break;
6387
6388     case BUILT_IN_FPRINTF_UNLOCKED:
6389       target = expand_builtin_fprintf (exp, target, mode, true);
6390       if (target)
6391         return target;
6392       break;
6393
6394     case BUILT_IN_SPRINTF:
6395       target = expand_builtin_sprintf (exp, target, mode);
6396       if (target)
6397         return target;
6398       break;
6399
6400     CASE_FLT_FN (BUILT_IN_SIGNBIT):
6401     case BUILT_IN_SIGNBITD32:
6402     case BUILT_IN_SIGNBITD64:
6403     case BUILT_IN_SIGNBITD128:
6404       target = expand_builtin_signbit (exp, target);
6405       if (target)
6406         return target;
6407       break;
6408
6409       /* Various hooks for the DWARF 2 __throw routine.  */
6410     case BUILT_IN_UNWIND_INIT:
6411       expand_builtin_unwind_init ();
6412       return const0_rtx;
6413     case BUILT_IN_DWARF_CFA:
6414       return virtual_cfa_rtx;
6415 #ifdef DWARF2_UNWIND_INFO
6416     case BUILT_IN_DWARF_SP_COLUMN:
6417       return expand_builtin_dwarf_sp_column ();
6418     case BUILT_IN_INIT_DWARF_REG_SIZES:
6419       expand_builtin_init_dwarf_reg_sizes (CALL_EXPR_ARG (exp, 0));
6420       return const0_rtx;
6421 #endif
6422     case BUILT_IN_FROB_RETURN_ADDR:
6423       return expand_builtin_frob_return_addr (CALL_EXPR_ARG (exp, 0));
6424     case BUILT_IN_EXTRACT_RETURN_ADDR:
6425       return expand_builtin_extract_return_addr (CALL_EXPR_ARG (exp, 0));
6426     case BUILT_IN_EH_RETURN:
6427       expand_builtin_eh_return (CALL_EXPR_ARG (exp, 0),
6428                                 CALL_EXPR_ARG (exp, 1));
6429       return const0_rtx;
6430 #ifdef EH_RETURN_DATA_REGNO
6431     case BUILT_IN_EH_RETURN_DATA_REGNO:
6432       return expand_builtin_eh_return_data_regno (exp);
6433 #endif
6434     case BUILT_IN_EXTEND_POINTER:
6435       return expand_builtin_extend_pointer (CALL_EXPR_ARG (exp, 0));
6436     case BUILT_IN_EH_POINTER:
6437       return expand_builtin_eh_pointer (exp);
6438     case BUILT_IN_EH_FILTER:
6439       return expand_builtin_eh_filter (exp);
6440     case BUILT_IN_EH_COPY_VALUES:
6441       return expand_builtin_eh_copy_values (exp);
6442
6443     case BUILT_IN_VA_START:
6444       return expand_builtin_va_start (exp);
6445     case BUILT_IN_VA_END:
6446       return expand_builtin_va_end (exp);
6447     case BUILT_IN_VA_COPY:
6448       return expand_builtin_va_copy (exp);
6449     case BUILT_IN_EXPECT:
6450       return expand_builtin_expect (exp, target);
6451     case BUILT_IN_PREFETCH:
6452       expand_builtin_prefetch (exp);
6453       return const0_rtx;
6454
6455     case BUILT_IN_PROFILE_FUNC_ENTER:
6456       return expand_builtin_profile_func (false);
6457     case BUILT_IN_PROFILE_FUNC_EXIT:
6458       return expand_builtin_profile_func (true);
6459
6460     case BUILT_IN_INIT_TRAMPOLINE:
6461       return expand_builtin_init_trampoline (exp);
6462     case BUILT_IN_ADJUST_TRAMPOLINE:
6463       return expand_builtin_adjust_trampoline (exp);
6464
6465     case BUILT_IN_FORK:
6466     case BUILT_IN_EXECL:
6467     case BUILT_IN_EXECV:
6468     case BUILT_IN_EXECLP:
6469     case BUILT_IN_EXECLE:
6470     case BUILT_IN_EXECVP:
6471     case BUILT_IN_EXECVE:
6472       target = expand_builtin_fork_or_exec (fndecl, exp, target, ignore);
6473       if (target)
6474         return target;
6475       break;
6476
6477     case BUILT_IN_FETCH_AND_ADD_1:
6478     case BUILT_IN_FETCH_AND_ADD_2:
6479     case BUILT_IN_FETCH_AND_ADD_4:
6480     case BUILT_IN_FETCH_AND_ADD_8:
6481     case BUILT_IN_FETCH_AND_ADD_16:
6482       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6483       target = expand_builtin_sync_operation (mode, exp, PLUS,
6484                                               false, target, ignore);
6485       if (target)
6486         return target;
6487       break;
6488
6489     case BUILT_IN_FETCH_AND_SUB_1:
6490     case BUILT_IN_FETCH_AND_SUB_2:
6491     case BUILT_IN_FETCH_AND_SUB_4:
6492     case BUILT_IN_FETCH_AND_SUB_8:
6493     case BUILT_IN_FETCH_AND_SUB_16:
6494       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6495       target = expand_builtin_sync_operation (mode, exp, MINUS,
6496                                               false, target, ignore);
6497       if (target)
6498         return target;
6499       break;
6500
6501     case BUILT_IN_FETCH_AND_OR_1:
6502     case BUILT_IN_FETCH_AND_OR_2:
6503     case BUILT_IN_FETCH_AND_OR_4:
6504     case BUILT_IN_FETCH_AND_OR_8:
6505     case BUILT_IN_FETCH_AND_OR_16:
6506       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6507       target = expand_builtin_sync_operation (mode, exp, IOR,
6508                                               false, target, ignore);
6509       if (target)
6510         return target;
6511       break;
6512
6513     case BUILT_IN_FETCH_AND_AND_1:
6514     case BUILT_IN_FETCH_AND_AND_2:
6515     case BUILT_IN_FETCH_AND_AND_4:
6516     case BUILT_IN_FETCH_AND_AND_8:
6517     case BUILT_IN_FETCH_AND_AND_16:
6518       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6519       target = expand_builtin_sync_operation (mode, exp, AND,
6520                                               false, target, ignore);
6521       if (target)
6522         return target;
6523       break;
6524
6525     case BUILT_IN_FETCH_AND_XOR_1:
6526     case BUILT_IN_FETCH_AND_XOR_2:
6527     case BUILT_IN_FETCH_AND_XOR_4:
6528     case BUILT_IN_FETCH_AND_XOR_8:
6529     case BUILT_IN_FETCH_AND_XOR_16:
6530       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6531       target = expand_builtin_sync_operation (mode, exp, XOR,
6532                                               false, target, ignore);
6533       if (target)
6534         return target;
6535       break;
6536
6537     case BUILT_IN_FETCH_AND_NAND_1:
6538     case BUILT_IN_FETCH_AND_NAND_2:
6539     case BUILT_IN_FETCH_AND_NAND_4:
6540     case BUILT_IN_FETCH_AND_NAND_8:
6541     case BUILT_IN_FETCH_AND_NAND_16:
6542       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6543       target = expand_builtin_sync_operation (mode, exp, NOT,
6544                                               false, target, ignore);
6545       if (target)
6546         return target;
6547       break;
6548
6549     case BUILT_IN_ADD_AND_FETCH_1:
6550     case BUILT_IN_ADD_AND_FETCH_2:
6551     case BUILT_IN_ADD_AND_FETCH_4:
6552     case BUILT_IN_ADD_AND_FETCH_8:
6553     case BUILT_IN_ADD_AND_FETCH_16:
6554       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6555       target = expand_builtin_sync_operation (mode, exp, PLUS,
6556                                               true, target, ignore);
6557       if (target)
6558         return target;
6559       break;
6560
6561     case BUILT_IN_SUB_AND_FETCH_1:
6562     case BUILT_IN_SUB_AND_FETCH_2:
6563     case BUILT_IN_SUB_AND_FETCH_4:
6564     case BUILT_IN_SUB_AND_FETCH_8:
6565     case BUILT_IN_SUB_AND_FETCH_16:
6566       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6567       target = expand_builtin_sync_operation (mode, exp, MINUS,
6568                                               true, target, ignore);
6569       if (target)
6570         return target;
6571       break;
6572
6573     case BUILT_IN_OR_AND_FETCH_1:
6574     case BUILT_IN_OR_AND_FETCH_2:
6575     case BUILT_IN_OR_AND_FETCH_4:
6576     case BUILT_IN_OR_AND_FETCH_8:
6577     case BUILT_IN_OR_AND_FETCH_16:
6578       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6579       target = expand_builtin_sync_operation (mode, exp, IOR,
6580                                               true, target, ignore);
6581       if (target)
6582         return target;
6583       break;
6584
6585     case BUILT_IN_AND_AND_FETCH_1:
6586     case BUILT_IN_AND_AND_FETCH_2:
6587     case BUILT_IN_AND_AND_FETCH_4:
6588     case BUILT_IN_AND_AND_FETCH_8:
6589     case BUILT_IN_AND_AND_FETCH_16:
6590       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6591       target = expand_builtin_sync_operation (mode, exp, AND,
6592                                               true, target, ignore);
6593       if (target)
6594         return target;
6595       break;
6596
6597     case BUILT_IN_XOR_AND_FETCH_1:
6598     case BUILT_IN_XOR_AND_FETCH_2:
6599     case BUILT_IN_XOR_AND_FETCH_4:
6600     case BUILT_IN_XOR_AND_FETCH_8:
6601     case BUILT_IN_XOR_AND_FETCH_16:
6602       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6603       target = expand_builtin_sync_operation (mode, exp, XOR,
6604                                               true, target, ignore);
6605       if (target)
6606         return target;
6607       break;
6608
6609     case BUILT_IN_NAND_AND_FETCH_1:
6610     case BUILT_IN_NAND_AND_FETCH_2:
6611     case BUILT_IN_NAND_AND_FETCH_4:
6612     case BUILT_IN_NAND_AND_FETCH_8:
6613     case BUILT_IN_NAND_AND_FETCH_16:
6614       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6615       target = expand_builtin_sync_operation (mode, exp, NOT,
6616                                               true, target, ignore);
6617       if (target)
6618         return target;
6619       break;
6620
6621     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6622     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6623     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6624     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6625     case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
6626       if (mode == VOIDmode)
6627         mode = TYPE_MODE (boolean_type_node);
6628       if (!target || !register_operand (target, mode))
6629         target = gen_reg_rtx (mode);
6630
6631       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6632       target = expand_builtin_compare_and_swap (mode, exp, true, target);
6633       if (target)
6634         return target;
6635       break;
6636
6637     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6638     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6639     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6640     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6641     case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
6642       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6643       target = expand_builtin_compare_and_swap (mode, exp, false, target);
6644       if (target)
6645         return target;
6646       break;
6647
6648     case BUILT_IN_LOCK_TEST_AND_SET_1:
6649     case BUILT_IN_LOCK_TEST_AND_SET_2:
6650     case BUILT_IN_LOCK_TEST_AND_SET_4:
6651     case BUILT_IN_LOCK_TEST_AND_SET_8:
6652     case BUILT_IN_LOCK_TEST_AND_SET_16:
6653       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6654       target = expand_builtin_lock_test_and_set (mode, exp, target);
6655       if (target)
6656         return target;
6657       break;
6658
6659     case BUILT_IN_LOCK_RELEASE_1:
6660     case BUILT_IN_LOCK_RELEASE_2:
6661     case BUILT_IN_LOCK_RELEASE_4:
6662     case BUILT_IN_LOCK_RELEASE_8:
6663     case BUILT_IN_LOCK_RELEASE_16:
6664       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6665       expand_builtin_lock_release (mode, exp);
6666       return const0_rtx;
6667
6668     case BUILT_IN_SYNCHRONIZE:
6669       expand_builtin_synchronize ();
6670       return const0_rtx;
6671
6672     case BUILT_IN_OBJECT_SIZE:
6673       return expand_builtin_object_size (exp);
6674
6675     case BUILT_IN_MEMCPY_CHK:
6676     case BUILT_IN_MEMPCPY_CHK:
6677     case BUILT_IN_MEMMOVE_CHK:
6678     case BUILT_IN_MEMSET_CHK:
6679       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6680       if (target)
6681         return target;
6682       break;
6683
6684     case BUILT_IN_STRCPY_CHK:
6685     case BUILT_IN_STPCPY_CHK:
6686     case BUILT_IN_STRNCPY_CHK:
6687     case BUILT_IN_STRCAT_CHK:
6688     case BUILT_IN_STRNCAT_CHK:
6689     case BUILT_IN_SNPRINTF_CHK:
6690     case BUILT_IN_VSNPRINTF_CHK:
6691       maybe_emit_chk_warning (exp, fcode);
6692       break;
6693
6694     case BUILT_IN_SPRINTF_CHK:
6695     case BUILT_IN_VSPRINTF_CHK:
6696       maybe_emit_sprintf_chk_warning (exp, fcode);
6697       break;
6698
6699     case BUILT_IN_FREE:
6700       maybe_emit_free_warning (exp);
6701       break;
6702
6703     default:    /* just do library call, if unknown builtin */
6704       break;
6705     }
6706
6707   /* The switch statement above can drop through to cause the function
6708      to be called normally.  */
6709   return expand_call (exp, target, ignore);
6710 }
6711
6712 /* Determine whether a tree node represents a call to a built-in
6713    function.  If the tree T is a call to a built-in function with
6714    the right number of arguments of the appropriate types, return
6715    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6716    Otherwise the return value is END_BUILTINS.  */
6717
6718 enum built_in_function
6719 builtin_mathfn_code (const_tree t)
6720 {
6721   const_tree fndecl, arg, parmlist;
6722   const_tree argtype, parmtype;
6723   const_call_expr_arg_iterator iter;
6724
6725   if (TREE_CODE (t) != CALL_EXPR
6726       || TREE_CODE (CALL_EXPR_FN (t)) != ADDR_EXPR)
6727     return END_BUILTINS;
6728
6729   fndecl = get_callee_fndecl (t);
6730   if (fndecl == NULL_TREE
6731       || TREE_CODE (fndecl) != FUNCTION_DECL
6732       || ! DECL_BUILT_IN (fndecl)
6733       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6734     return END_BUILTINS;
6735
6736   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6737   init_const_call_expr_arg_iterator (t, &iter);
6738   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6739     {
6740       /* If a function doesn't take a variable number of arguments,
6741          the last element in the list will have type `void'.  */
6742       parmtype = TREE_VALUE (parmlist);
6743       if (VOID_TYPE_P (parmtype))
6744         {
6745           if (more_const_call_expr_args_p (&iter))
6746             return END_BUILTINS;
6747           return DECL_FUNCTION_CODE (fndecl);
6748         }
6749
6750       if (! more_const_call_expr_args_p (&iter))
6751         return END_BUILTINS;
6752       
6753       arg = next_const_call_expr_arg (&iter);
6754       argtype = TREE_TYPE (arg);
6755
6756       if (SCALAR_FLOAT_TYPE_P (parmtype))
6757         {
6758           if (! SCALAR_FLOAT_TYPE_P (argtype))
6759             return END_BUILTINS;
6760         }
6761       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6762         {
6763           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6764             return END_BUILTINS;
6765         }
6766       else if (POINTER_TYPE_P (parmtype))
6767         {
6768           if (! POINTER_TYPE_P (argtype))
6769             return END_BUILTINS;
6770         }
6771       else if (INTEGRAL_TYPE_P (parmtype))
6772         {
6773           if (! INTEGRAL_TYPE_P (argtype))
6774             return END_BUILTINS;
6775         }
6776       else
6777         return END_BUILTINS;
6778     }
6779
6780   /* Variable-length argument list.  */
6781   return DECL_FUNCTION_CODE (fndecl);
6782 }
6783
6784 /* Fold a call to __builtin_constant_p, if we know its argument ARG will
6785    evaluate to a constant.  */
6786
6787 static tree
6788 fold_builtin_constant_p (tree arg)
6789 {
6790   /* We return 1 for a numeric type that's known to be a constant
6791      value at compile-time or for an aggregate type that's a
6792      literal constant.  */
6793   STRIP_NOPS (arg);
6794
6795   /* If we know this is a constant, emit the constant of one.  */
6796   if (CONSTANT_CLASS_P (arg)
6797       || (TREE_CODE (arg) == CONSTRUCTOR
6798           && TREE_CONSTANT (arg)))
6799     return integer_one_node;
6800   if (TREE_CODE (arg) == ADDR_EXPR)
6801     {
6802        tree op = TREE_OPERAND (arg, 0);
6803        if (TREE_CODE (op) == STRING_CST
6804            || (TREE_CODE (op) == ARRAY_REF
6805                && integer_zerop (TREE_OPERAND (op, 1))
6806                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6807          return integer_one_node;
6808     }
6809
6810   /* If this expression has side effects, show we don't know it to be a
6811      constant.  Likewise if it's a pointer or aggregate type since in
6812      those case we only want literals, since those are only optimized
6813      when generating RTL, not later.
6814      And finally, if we are compiling an initializer, not code, we
6815      need to return a definite result now; there's not going to be any
6816      more optimization done.  */
6817   if (TREE_SIDE_EFFECTS (arg)
6818       || AGGREGATE_TYPE_P (TREE_TYPE (arg))
6819       || POINTER_TYPE_P (TREE_TYPE (arg))
6820       || cfun == 0
6821       || folding_initializer)
6822     return integer_zero_node;
6823
6824   return NULL_TREE;
6825 }
6826
6827 /* Create builtin_expect with PRED and EXPECTED as its arguments and
6828    return it as a truthvalue.  */
6829
6830 static tree
6831 build_builtin_expect_predicate (location_t loc, tree pred, tree expected)
6832 {
6833   tree fn, arg_types, pred_type, expected_type, call_expr, ret_type;
6834
6835   fn = built_in_decls[BUILT_IN_EXPECT];
6836   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
6837   ret_type = TREE_TYPE (TREE_TYPE (fn));
6838   pred_type = TREE_VALUE (arg_types);
6839   expected_type = TREE_VALUE (TREE_CHAIN (arg_types));
6840
6841   pred = fold_convert_loc (loc, pred_type, pred);
6842   expected = fold_convert_loc (loc, expected_type, expected);
6843   call_expr = build_call_expr_loc (loc, fn, 2, pred, expected);
6844
6845   return build2 (NE_EXPR, TREE_TYPE (pred), call_expr,
6846                  build_int_cst (ret_type, 0));
6847 }
6848
6849 /* Fold a call to builtin_expect with arguments ARG0 and ARG1.  Return
6850    NULL_TREE if no simplification is possible.  */
6851
6852 static tree
6853 fold_builtin_expect (location_t loc, tree arg0, tree arg1)
6854 {
6855   tree inner, fndecl;
6856   enum tree_code code;
6857
6858   /* If this is a builtin_expect within a builtin_expect keep the
6859      inner one.  See through a comparison against a constant.  It
6860      might have been added to create a thruthvalue.  */
6861   inner = arg0;
6862   if (COMPARISON_CLASS_P (inner)
6863       && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST)
6864     inner = TREE_OPERAND (inner, 0);
6865
6866   if (TREE_CODE (inner) == CALL_EXPR
6867       && (fndecl = get_callee_fndecl (inner))
6868       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
6869       && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT)
6870     return arg0;
6871
6872   /* Distribute the expected value over short-circuiting operators.
6873      See through the cast from truthvalue_type_node to long.  */
6874   inner = arg0;
6875   while (TREE_CODE (inner) == NOP_EXPR
6876          && INTEGRAL_TYPE_P (TREE_TYPE (inner))
6877          && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (inner, 0))))
6878     inner = TREE_OPERAND (inner, 0);
6879
6880   code = TREE_CODE (inner);
6881   if (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
6882     {
6883       tree op0 = TREE_OPERAND (inner, 0);
6884       tree op1 = TREE_OPERAND (inner, 1);
6885
6886       op0 = build_builtin_expect_predicate (loc, op0, arg1);
6887       op1 = build_builtin_expect_predicate (loc, op1, arg1);
6888       inner = build2 (code, TREE_TYPE (inner), op0, op1);
6889
6890       return fold_convert_loc (loc, TREE_TYPE (arg0), inner);
6891     }
6892
6893   /* If the argument isn't invariant then there's nothing else we can do.  */
6894   if (!TREE_CONSTANT (arg0))
6895     return NULL_TREE;
6896
6897   /* If we expect that a comparison against the argument will fold to
6898      a constant return the constant.  In practice, this means a true
6899      constant or the address of a non-weak symbol.  */
6900   inner = arg0;
6901   STRIP_NOPS (inner);
6902   if (TREE_CODE (inner) == ADDR_EXPR)
6903     {
6904       do
6905         {
6906           inner = TREE_OPERAND (inner, 0);
6907         }
6908       while (TREE_CODE (inner) == COMPONENT_REF
6909              || TREE_CODE (inner) == ARRAY_REF);
6910       if ((TREE_CODE (inner) == VAR_DECL
6911            || TREE_CODE (inner) == FUNCTION_DECL)
6912           && DECL_WEAK (inner))
6913         return NULL_TREE;
6914     }
6915
6916   /* Otherwise, ARG0 already has the proper type for the return value.  */
6917   return arg0;
6918 }
6919
6920 /* Fold a call to __builtin_classify_type with argument ARG.  */
6921
6922 static tree
6923 fold_builtin_classify_type (tree arg)
6924 {
6925   if (arg == 0)
6926     return build_int_cst (NULL_TREE, no_type_class);
6927
6928   return build_int_cst (NULL_TREE, type_to_class (TREE_TYPE (arg)));
6929 }
6930
6931 /* Fold a call to __builtin_strlen with argument ARG.  */
6932
6933 static tree
6934 fold_builtin_strlen (location_t loc, tree arg)
6935 {
6936   if (!validate_arg (arg, POINTER_TYPE))
6937     return NULL_TREE;
6938   else
6939     {
6940       tree len = c_strlen (arg, 0);
6941
6942       if (len)
6943         {
6944           /* Convert from the internal "sizetype" type to "size_t".  */
6945           if (size_type_node)
6946             len = fold_convert_loc (loc, size_type_node, len);
6947           return len;
6948         }
6949
6950       return NULL_TREE;
6951     }
6952 }
6953
6954 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6955
6956 static tree
6957 fold_builtin_inf (location_t loc, tree type, int warn)
6958 {
6959   REAL_VALUE_TYPE real;
6960
6961   /* __builtin_inff is intended to be usable to define INFINITY on all
6962      targets.  If an infinity is not available, INFINITY expands "to a
6963      positive constant of type float that overflows at translation
6964      time", footnote "In this case, using INFINITY will violate the
6965      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6966      Thus we pedwarn to ensure this constraint violation is
6967      diagnosed.  */
6968   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6969     pedwarn (loc, 0, "target format does not support infinity");
6970
6971   real_inf (&real);
6972   return build_real (type, real);
6973 }
6974
6975 /* Fold a call to __builtin_nan or __builtin_nans with argument ARG.  */
6976
6977 static tree
6978 fold_builtin_nan (tree arg, tree type, int quiet)
6979 {
6980   REAL_VALUE_TYPE real;
6981   const char *str;
6982
6983   if (!validate_arg (arg, POINTER_TYPE))
6984     return NULL_TREE;
6985   str = c_getstr (arg);
6986   if (!str)
6987     return NULL_TREE;
6988
6989   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6990     return NULL_TREE;
6991
6992   return build_real (type, real);
6993 }
6994
6995 /* Return true if the floating point expression T has an integer value.
6996    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6997
6998 static bool
6999 integer_valued_real_p (tree t)
7000 {
7001   switch (TREE_CODE (t))
7002     {
7003     case FLOAT_EXPR:
7004       return true;
7005
7006     case ABS_EXPR:
7007     case SAVE_EXPR:
7008       return integer_valued_real_p (TREE_OPERAND (t, 0));
7009
7010     case COMPOUND_EXPR:
7011     case MODIFY_EXPR:
7012     case BIND_EXPR:
7013       return integer_valued_real_p (TREE_OPERAND (t, 1));
7014
7015     case PLUS_EXPR:
7016     case MINUS_EXPR:
7017     case MULT_EXPR:
7018     case MIN_EXPR:
7019     case MAX_EXPR:
7020       return integer_valued_real_p (TREE_OPERAND (t, 0))
7021              && integer_valued_real_p (TREE_OPERAND (t, 1));
7022
7023     case COND_EXPR:
7024       return integer_valued_real_p (TREE_OPERAND (t, 1))
7025              && integer_valued_real_p (TREE_OPERAND (t, 2));
7026
7027     case REAL_CST:
7028       return real_isinteger (TREE_REAL_CST_PTR (t), TYPE_MODE (TREE_TYPE (t)));
7029
7030     case NOP_EXPR:
7031       {
7032         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
7033         if (TREE_CODE (type) == INTEGER_TYPE)
7034           return true;
7035         if (TREE_CODE (type) == REAL_TYPE)
7036           return integer_valued_real_p (TREE_OPERAND (t, 0));
7037         break;
7038       }
7039
7040     case CALL_EXPR:
7041       switch (builtin_mathfn_code (t))
7042         {
7043         CASE_FLT_FN (BUILT_IN_CEIL):
7044         CASE_FLT_FN (BUILT_IN_FLOOR):
7045         CASE_FLT_FN (BUILT_IN_NEARBYINT):
7046         CASE_FLT_FN (BUILT_IN_RINT):
7047         CASE_FLT_FN (BUILT_IN_ROUND):
7048         CASE_FLT_FN (BUILT_IN_TRUNC):
7049           return true;
7050
7051         CASE_FLT_FN (BUILT_IN_FMIN):
7052         CASE_FLT_FN (BUILT_IN_FMAX):
7053           return integer_valued_real_p (CALL_EXPR_ARG (t, 0))
7054             && integer_valued_real_p (CALL_EXPR_ARG (t, 1));
7055
7056         default:
7057           break;
7058         }
7059       break;
7060
7061     default:
7062       break;
7063     }
7064   return false;
7065 }
7066
7067 /* FNDECL is assumed to be a builtin where truncation can be propagated
7068    across (for instance floor((double)f) == (double)floorf (f).
7069    Do the transformation for a call with argument ARG.  */
7070
7071 static tree
7072 fold_trunc_transparent_mathfn (location_t loc, tree fndecl, tree arg)
7073 {
7074   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7075
7076   if (!validate_arg (arg, REAL_TYPE))
7077     return NULL_TREE;
7078
7079   /* Integer rounding functions are idempotent.  */
7080   if (fcode == builtin_mathfn_code (arg))
7081     return arg;
7082
7083   /* If argument is already integer valued, and we don't need to worry
7084      about setting errno, there's no need to perform rounding.  */
7085   if (! flag_errno_math && integer_valued_real_p (arg))
7086     return arg;
7087
7088   if (optimize)
7089     {
7090       tree arg0 = strip_float_extensions (arg);
7091       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
7092       tree newtype = TREE_TYPE (arg0);
7093       tree decl;
7094
7095       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7096           && (decl = mathfn_built_in (newtype, fcode)))
7097         return fold_convert_loc (loc, ftype,
7098                                  build_call_expr_loc (loc, decl, 1,
7099                                                   fold_convert_loc (loc,
7100                                                                     newtype,
7101                                                                     arg0)));
7102     }
7103   return NULL_TREE;
7104 }
7105
7106 /* FNDECL is assumed to be builtin which can narrow the FP type of
7107    the argument, for instance lround((double)f) -> lroundf (f).
7108    Do the transformation for a call with argument ARG.  */
7109
7110 static tree
7111 fold_fixed_mathfn (location_t loc, tree fndecl, tree arg)
7112 {
7113   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
7114
7115   if (!validate_arg (arg, REAL_TYPE))
7116     return NULL_TREE;
7117
7118   /* If argument is already integer valued, and we don't need to worry
7119      about setting errno, there's no need to perform rounding.  */
7120   if (! flag_errno_math && integer_valued_real_p (arg))
7121     return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7122                         TREE_TYPE (TREE_TYPE (fndecl)), arg);
7123
7124   if (optimize)
7125     {
7126       tree ftype = TREE_TYPE (arg);
7127       tree arg0 = strip_float_extensions (arg);
7128       tree newtype = TREE_TYPE (arg0);
7129       tree decl;
7130
7131       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
7132           && (decl = mathfn_built_in (newtype, fcode)))
7133         return build_call_expr_loc (loc, decl, 1,
7134                                 fold_convert_loc (loc, newtype, arg0));
7135     }
7136
7137   /* Canonicalize llround (x) to lround (x) on LP64 targets where
7138      sizeof (long long) == sizeof (long).  */
7139   if (TYPE_PRECISION (long_long_integer_type_node)
7140       == TYPE_PRECISION (long_integer_type_node))
7141     {
7142       tree newfn = NULL_TREE;
7143       switch (fcode)
7144         {
7145         CASE_FLT_FN (BUILT_IN_LLCEIL):
7146           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
7147           break;
7148
7149         CASE_FLT_FN (BUILT_IN_LLFLOOR):
7150           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
7151           break;
7152
7153         CASE_FLT_FN (BUILT_IN_LLROUND):
7154           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
7155           break;
7156
7157         CASE_FLT_FN (BUILT_IN_LLRINT):
7158           newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
7159           break;
7160
7161         default:
7162           break;
7163         }
7164
7165       if (newfn)
7166         {
7167           tree newcall = build_call_expr_loc (loc, newfn, 1, arg);
7168           return fold_convert_loc (loc,
7169                                    TREE_TYPE (TREE_TYPE (fndecl)), newcall);
7170         }
7171     }
7172
7173   return NULL_TREE;
7174 }
7175
7176 /* Fold call to builtin cabs, cabsf or cabsl with argument ARG.  TYPE is the
7177    return type.  Return NULL_TREE if no simplification can be made.  */
7178
7179 static tree
7180 fold_builtin_cabs (location_t loc, tree arg, tree type, tree fndecl)
7181 {
7182   tree res;
7183
7184   if (!validate_arg (arg, COMPLEX_TYPE)
7185       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
7186     return NULL_TREE;
7187
7188   /* Calculate the result when the argument is a constant.  */
7189   if (TREE_CODE (arg) == COMPLEX_CST
7190       && (res = do_mpfr_arg2 (TREE_REALPART (arg), TREE_IMAGPART (arg),
7191                               type, mpfr_hypot)))
7192     return res;
7193   
7194   if (TREE_CODE (arg) == COMPLEX_EXPR)
7195     {
7196       tree real = TREE_OPERAND (arg, 0);
7197       tree imag = TREE_OPERAND (arg, 1);
7198       
7199       /* If either part is zero, cabs is fabs of the other.  */
7200       if (real_zerop (real))
7201         return fold_build1_loc (loc, ABS_EXPR, type, imag);
7202       if (real_zerop (imag))
7203         return fold_build1_loc (loc, ABS_EXPR, type, real);
7204
7205       /* cabs(x+xi) -> fabs(x)*sqrt(2).  */
7206       if (flag_unsafe_math_optimizations
7207           && operand_equal_p (real, imag, OEP_PURE_SAME))
7208         {
7209           const REAL_VALUE_TYPE sqrt2_trunc
7210             = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
7211           STRIP_NOPS (real);
7212           return fold_build2_loc (loc, MULT_EXPR, type,
7213                               fold_build1_loc (loc, ABS_EXPR, type, real),
7214                               build_real (type, sqrt2_trunc));
7215         }
7216     }
7217
7218   /* Optimize cabs(-z) and cabs(conj(z)) as cabs(z).  */
7219   if (TREE_CODE (arg) == NEGATE_EXPR
7220       || TREE_CODE (arg) == CONJ_EXPR)
7221     return build_call_expr_loc (loc, fndecl, 1, TREE_OPERAND (arg, 0));
7222
7223   /* Don't do this when optimizing for size.  */
7224   if (flag_unsafe_math_optimizations
7225       && optimize && optimize_function_for_speed_p (cfun))
7226     {
7227       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7228
7229       if (sqrtfn != NULL_TREE)
7230         {
7231           tree rpart, ipart, result;
7232
7233           arg = builtin_save_expr (arg);
7234
7235           rpart = fold_build1_loc (loc, REALPART_EXPR, type, arg);
7236           ipart = fold_build1_loc (loc, IMAGPART_EXPR, type, arg);
7237
7238           rpart = builtin_save_expr (rpart);
7239           ipart = builtin_save_expr (ipart);
7240
7241           result = fold_build2_loc (loc, PLUS_EXPR, type,
7242                                 fold_build2_loc (loc, MULT_EXPR, type,
7243                                              rpart, rpart),
7244                                 fold_build2_loc (loc, MULT_EXPR, type,
7245                                              ipart, ipart));
7246
7247           return build_call_expr_loc (loc, sqrtfn, 1, result);
7248         }
7249     }
7250
7251   return NULL_TREE;
7252 }
7253
7254 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl with argument ARG.
7255    Return NULL_TREE if no simplification can be made.  */
7256
7257 static tree
7258 fold_builtin_sqrt (location_t loc, tree arg, tree type)
7259 {
7260
7261   enum built_in_function fcode;
7262   tree res;
7263
7264   if (!validate_arg (arg, REAL_TYPE))
7265     return NULL_TREE;
7266
7267   /* Calculate the result when the argument is a constant.  */
7268   if ((res = do_mpfr_arg1 (arg, type, mpfr_sqrt, &dconst0, NULL, true)))
7269     return res;
7270   
7271   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7272   fcode = builtin_mathfn_code (arg);
7273   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7274     {
7275       tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7276       arg = fold_build2_loc (loc, MULT_EXPR, type,
7277                          CALL_EXPR_ARG (arg, 0),
7278                          build_real (type, dconsthalf));
7279       return build_call_expr_loc (loc, expfn, 1, arg);
7280     }
7281
7282   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7283   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7284     {
7285       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7286
7287       if (powfn)
7288         {
7289           tree arg0 = CALL_EXPR_ARG (arg, 0);
7290           tree tree_root;
7291           /* The inner root was either sqrt or cbrt.  */
7292           /* This was a conditional expression but it triggered a bug
7293              in Sun C 5.5.  */
7294           REAL_VALUE_TYPE dconstroot;
7295           if (BUILTIN_SQRT_P (fcode))
7296             dconstroot = dconsthalf;
7297           else
7298             dconstroot = dconst_third ();
7299
7300           /* Adjust for the outer root.  */
7301           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7302           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7303           tree_root = build_real (type, dconstroot);
7304           return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7305         }
7306     }
7307
7308   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
7309   if (flag_unsafe_math_optimizations
7310       && (fcode == BUILT_IN_POW
7311           || fcode == BUILT_IN_POWF
7312           || fcode == BUILT_IN_POWL))
7313     {
7314       tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7315       tree arg0 = CALL_EXPR_ARG (arg, 0);
7316       tree arg1 = CALL_EXPR_ARG (arg, 1);
7317       tree narg1;
7318       if (!tree_expr_nonnegative_p (arg0))
7319         arg0 = build1 (ABS_EXPR, type, arg0);
7320       narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
7321                            build_real (type, dconsthalf));
7322       return build_call_expr_loc (loc, powfn, 2, arg0, narg1);
7323     }
7324
7325   return NULL_TREE;
7326 }
7327
7328 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl with argument ARG.
7329    Return NULL_TREE if no simplification can be made.  */
7330
7331 static tree
7332 fold_builtin_cbrt (location_t loc, tree arg, tree type)
7333 {
7334   const enum built_in_function fcode = builtin_mathfn_code (arg);
7335   tree res;
7336
7337   if (!validate_arg (arg, REAL_TYPE))
7338     return NULL_TREE;
7339
7340   /* Calculate the result when the argument is a constant.  */
7341   if ((res = do_mpfr_arg1 (arg, type, mpfr_cbrt, NULL, NULL, 0)))
7342     return res;
7343
7344   if (flag_unsafe_math_optimizations)
7345     {
7346       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7347       if (BUILTIN_EXPONENT_P (fcode))
7348         {
7349           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7350           const REAL_VALUE_TYPE third_trunc =
7351             real_value_truncate (TYPE_MODE (type), dconst_third ());
7352           arg = fold_build2_loc (loc, MULT_EXPR, type,
7353                              CALL_EXPR_ARG (arg, 0),
7354                              build_real (type, third_trunc));
7355           return build_call_expr_loc (loc, expfn, 1, arg);
7356         }
7357
7358       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7359       if (BUILTIN_SQRT_P (fcode))
7360         {
7361           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7362
7363           if (powfn)
7364             {
7365               tree arg0 = CALL_EXPR_ARG (arg, 0);
7366               tree tree_root;
7367               REAL_VALUE_TYPE dconstroot = dconst_third ();
7368
7369               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7370               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7371               tree_root = build_real (type, dconstroot);
7372               return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7373             }
7374         }
7375
7376       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7377       if (BUILTIN_CBRT_P (fcode))
7378         {
7379           tree arg0 = CALL_EXPR_ARG (arg, 0);
7380           if (tree_expr_nonnegative_p (arg0))
7381             {
7382               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7383
7384               if (powfn)
7385                 {
7386                   tree tree_root;
7387                   REAL_VALUE_TYPE dconstroot;
7388
7389                   real_arithmetic (&dconstroot, MULT_EXPR,
7390                                    dconst_third_ptr (), dconst_third_ptr ());
7391                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7392                   tree_root = build_real (type, dconstroot);
7393                   return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
7394                 }
7395             }
7396         }
7397
7398       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7399       if (fcode == BUILT_IN_POW 
7400           || fcode == BUILT_IN_POWF
7401           || fcode == BUILT_IN_POWL)
7402         {
7403           tree arg00 = CALL_EXPR_ARG (arg, 0);
7404           tree arg01 = CALL_EXPR_ARG (arg, 1);
7405           if (tree_expr_nonnegative_p (arg00))
7406             {
7407               tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
7408               const REAL_VALUE_TYPE dconstroot
7409                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
7410               tree narg01 = fold_build2_loc (loc, MULT_EXPR, type, arg01,
7411                                          build_real (type, dconstroot));
7412               return build_call_expr_loc (loc, powfn, 2, arg00, narg01);
7413             }
7414         }
7415     }
7416   return NULL_TREE;
7417 }
7418
7419 /* Fold function call to builtin cos, cosf, or cosl with argument ARG.
7420    TYPE is the type of the return value.  Return NULL_TREE if no
7421    simplification can be made.  */
7422
7423 static tree
7424 fold_builtin_cos (location_t loc,
7425                   tree arg, tree type, tree fndecl)
7426 {
7427   tree res, narg;
7428
7429   if (!validate_arg (arg, REAL_TYPE))
7430     return NULL_TREE;
7431
7432   /* Calculate the result when the argument is a constant.  */
7433   if ((res = do_mpfr_arg1 (arg, type, mpfr_cos, NULL, NULL, 0)))
7434     return res;
7435   
7436   /* Optimize cos(-x) into cos (x).  */
7437   if ((narg = fold_strip_sign_ops (arg)))
7438     return build_call_expr_loc (loc, fndecl, 1, narg);
7439
7440   return NULL_TREE;
7441 }
7442
7443 /* Fold function call to builtin cosh, coshf, or coshl with argument ARG.
7444    Return NULL_TREE if no simplification can be made.  */
7445
7446 static tree
7447 fold_builtin_cosh (location_t loc, tree arg, tree type, tree fndecl)
7448 {
7449   if (validate_arg (arg, REAL_TYPE))
7450     {
7451       tree res, narg;
7452
7453       /* Calculate the result when the argument is a constant.  */
7454       if ((res = do_mpfr_arg1 (arg, type, mpfr_cosh, NULL, NULL, 0)))
7455         return res;
7456   
7457       /* Optimize cosh(-x) into cosh (x).  */
7458       if ((narg = fold_strip_sign_ops (arg)))
7459         return build_call_expr_loc (loc, fndecl, 1, narg);
7460     }
7461   
7462   return NULL_TREE;
7463 }
7464
7465 /* Fold function call to builtin ccos (or ccosh if HYPER is TRUE) with
7466    argument ARG.  TYPE is the type of the return value.  Return
7467    NULL_TREE if no simplification can be made.  */
7468
7469 static tree
7470 fold_builtin_ccos (location_t loc,
7471                    tree arg, tree type ATTRIBUTE_UNUSED, tree fndecl,
7472                    bool hyper ATTRIBUTE_UNUSED)
7473 {
7474   if (validate_arg (arg, COMPLEX_TYPE)
7475       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
7476     {
7477       tree tmp;
7478
7479 #ifdef HAVE_mpc
7480       /* Calculate the result when the argument is a constant.  */
7481       if ((tmp = do_mpc_arg1 (arg, type, (hyper ? mpc_cosh : mpc_cos))))
7482         return tmp;
7483 #endif
7484   
7485       /* Optimize fn(-x) into fn(x).  */
7486       if ((tmp = fold_strip_sign_ops (arg)))
7487         return build_call_expr_loc (loc, fndecl, 1, tmp);
7488     }
7489
7490   return NULL_TREE;
7491 }
7492
7493 /* Fold function call to builtin tan, tanf, or tanl with argument ARG.
7494    Return NULL_TREE if no simplification can be made.  */
7495
7496 static tree
7497 fold_builtin_tan (tree arg, tree type)
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_tan, NULL, NULL, 0)))
7507     return res;
7508   
7509   /* Optimize tan(atan(x)) = x.  */
7510   fcode = builtin_mathfn_code (arg);
7511   if (flag_unsafe_math_optimizations
7512       && (fcode == BUILT_IN_ATAN
7513           || fcode == BUILT_IN_ATANF
7514           || fcode == BUILT_IN_ATANL))
7515     return CALL_EXPR_ARG (arg, 0);
7516
7517   return NULL_TREE;
7518 }
7519
7520 /* Fold function call to builtin sincos, sincosf, or sincosl.  Return
7521    NULL_TREE if no simplification can be made.  */
7522
7523 static tree
7524 fold_builtin_sincos (location_t loc,
7525                      tree arg0, tree arg1, tree arg2)
7526 {
7527   tree type;
7528   tree res, fn, call;
7529
7530   if (!validate_arg (arg0, REAL_TYPE)
7531       || !validate_arg (arg1, POINTER_TYPE)
7532       || !validate_arg (arg2, POINTER_TYPE))
7533     return NULL_TREE;
7534
7535   type = TREE_TYPE (arg0);
7536
7537   /* Calculate the result when the argument is a constant.  */
7538   if ((res = do_mpfr_sincos (arg0, arg1, arg2)))
7539     return res;
7540
7541   /* Canonicalize sincos to cexpi.  */
7542   if (!TARGET_C99_FUNCTIONS)
7543     return NULL_TREE;
7544   fn = mathfn_built_in (type, BUILT_IN_CEXPI);
7545   if (!fn)
7546     return NULL_TREE;
7547
7548   call = build_call_expr_loc (loc, fn, 1, arg0);
7549   call = builtin_save_expr (call);
7550
7551   return build2 (COMPOUND_EXPR, void_type_node,
7552                  build2 (MODIFY_EXPR, void_type_node,
7553                          build_fold_indirect_ref_loc (loc, arg1),
7554                          build1 (IMAGPART_EXPR, type, call)),
7555                  build2 (MODIFY_EXPR, void_type_node,
7556                          build_fold_indirect_ref_loc (loc, arg2),
7557                          build1 (REALPART_EXPR, type, call)));
7558 }
7559
7560 /* Fold function call to builtin cexp, cexpf, or cexpl.  Return
7561    NULL_TREE if no simplification can be made.  */
7562
7563 static tree
7564 fold_builtin_cexp (location_t loc, tree arg0, tree type)
7565 {
7566   tree rtype;
7567   tree realp, imagp, ifn;
7568 #ifdef HAVE_mpc
7569   tree res;
7570 #endif
7571
7572   if (!validate_arg (arg0, COMPLEX_TYPE)
7573       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
7574     return NULL_TREE;
7575
7576 #ifdef HAVE_mpc
7577   /* Calculate the result when the argument is a constant.  */
7578   if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
7579     return res;
7580 #endif
7581   
7582   rtype = TREE_TYPE (TREE_TYPE (arg0));
7583
7584   /* In case we can figure out the real part of arg0 and it is constant zero
7585      fold to cexpi.  */
7586   if (!TARGET_C99_FUNCTIONS)
7587     return NULL_TREE;
7588   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7589   if (!ifn)
7590     return NULL_TREE;
7591
7592   if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
7593       && real_zerop (realp))
7594     {
7595       tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
7596       return build_call_expr_loc (loc, ifn, 1, narg);
7597     }
7598
7599   /* In case we can easily decompose real and imaginary parts split cexp
7600      to exp (r) * cexpi (i).  */
7601   if (flag_unsafe_math_optimizations
7602       && realp)
7603     {
7604       tree rfn, rcall, icall;
7605
7606       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7607       if (!rfn)
7608         return NULL_TREE;
7609
7610       imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
7611       if (!imagp)
7612         return NULL_TREE;
7613
7614       icall = build_call_expr_loc (loc, ifn, 1, imagp);
7615       icall = builtin_save_expr (icall);
7616       rcall = build_call_expr_loc (loc, rfn, 1, realp);
7617       rcall = builtin_save_expr (rcall);
7618       return fold_build2_loc (loc, COMPLEX_EXPR, type,
7619                           fold_build2_loc (loc, MULT_EXPR, rtype,
7620                                        rcall,
7621                                        fold_build1_loc (loc, REALPART_EXPR,
7622                                                     rtype, icall)),
7623                           fold_build2_loc (loc, MULT_EXPR, rtype,
7624                                        rcall,
7625                                        fold_build1_loc (loc, IMAGPART_EXPR,
7626                                                     rtype, icall)));
7627     }
7628
7629   return NULL_TREE;
7630 }
7631
7632 /* Fold function call to builtin trunc, truncf or truncl with argument ARG.
7633    Return NULL_TREE if no simplification can be made.  */
7634
7635 static tree
7636 fold_builtin_trunc (location_t loc, tree fndecl, tree arg)
7637 {
7638   if (!validate_arg (arg, REAL_TYPE))
7639     return NULL_TREE;
7640
7641   /* Optimize trunc of constant value.  */
7642   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7643     {
7644       REAL_VALUE_TYPE r, x;
7645       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7646
7647       x = TREE_REAL_CST (arg);
7648       real_trunc (&r, TYPE_MODE (type), &x);
7649       return build_real (type, r);
7650     }
7651
7652   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7653 }
7654
7655 /* Fold function call to builtin floor, floorf or floorl with argument ARG.
7656    Return NULL_TREE if no simplification can be made.  */
7657
7658 static tree
7659 fold_builtin_floor (location_t loc, tree fndecl, tree arg)
7660 {
7661   if (!validate_arg (arg, REAL_TYPE))
7662     return NULL_TREE;
7663
7664   /* Optimize floor of constant value.  */
7665   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7666     {
7667       REAL_VALUE_TYPE x;
7668
7669       x = TREE_REAL_CST (arg);
7670       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7671         {
7672           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7673           REAL_VALUE_TYPE r;
7674
7675           real_floor (&r, TYPE_MODE (type), &x);
7676           return build_real (type, r);
7677         }
7678     }
7679
7680   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7681   if (tree_expr_nonnegative_p (arg))
7682     {
7683       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7684       if (truncfn)
7685         return build_call_expr_loc (loc, truncfn, 1, arg);
7686     }
7687
7688   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7689 }
7690
7691 /* Fold function call to builtin ceil, ceilf or ceill with argument ARG.
7692    Return NULL_TREE if no simplification can be made.  */
7693
7694 static tree
7695 fold_builtin_ceil (location_t loc, tree fndecl, tree arg)
7696 {
7697   if (!validate_arg (arg, REAL_TYPE))
7698     return NULL_TREE;
7699
7700   /* Optimize ceil of constant value.  */
7701   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7702     {
7703       REAL_VALUE_TYPE x;
7704
7705       x = TREE_REAL_CST (arg);
7706       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7707         {
7708           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7709           REAL_VALUE_TYPE r;
7710
7711           real_ceil (&r, TYPE_MODE (type), &x);
7712           return build_real (type, r);
7713         }
7714     }
7715
7716   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7717 }
7718
7719 /* Fold function call to builtin round, roundf or roundl with argument ARG.
7720    Return NULL_TREE if no simplification can be made.  */
7721
7722 static tree
7723 fold_builtin_round (location_t loc, tree fndecl, tree arg)
7724 {
7725   if (!validate_arg (arg, REAL_TYPE))
7726     return NULL_TREE;
7727
7728   /* Optimize round of constant value.  */
7729   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7730     {
7731       REAL_VALUE_TYPE x;
7732
7733       x = TREE_REAL_CST (arg);
7734       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7735         {
7736           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7737           REAL_VALUE_TYPE r;
7738
7739           real_round (&r, TYPE_MODE (type), &x);
7740           return build_real (type, r);
7741         }
7742     }
7743
7744   return fold_trunc_transparent_mathfn (loc, fndecl, arg);
7745 }
7746
7747 /* Fold function call to builtin lround, lroundf or lroundl (or the
7748    corresponding long long versions) and other rounding functions.  ARG
7749    is the argument to the call.  Return NULL_TREE if no simplification
7750    can be made.  */
7751
7752 static tree
7753 fold_builtin_int_roundingfn (location_t loc, tree fndecl, tree arg)
7754 {
7755   if (!validate_arg (arg, REAL_TYPE))
7756     return NULL_TREE;
7757
7758   /* Optimize lround of constant value.  */
7759   if (TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
7760     {
7761       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7762
7763       if (real_isfinite (&x))
7764         {
7765           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7766           tree ftype = TREE_TYPE (arg);
7767           unsigned HOST_WIDE_INT lo2;
7768           HOST_WIDE_INT hi, lo;
7769           REAL_VALUE_TYPE r;
7770
7771           switch (DECL_FUNCTION_CODE (fndecl))
7772             {
7773             CASE_FLT_FN (BUILT_IN_LFLOOR):
7774             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7775               real_floor (&r, TYPE_MODE (ftype), &x);
7776               break;
7777
7778             CASE_FLT_FN (BUILT_IN_LCEIL):
7779             CASE_FLT_FN (BUILT_IN_LLCEIL):
7780               real_ceil (&r, TYPE_MODE (ftype), &x);
7781               break;
7782
7783             CASE_FLT_FN (BUILT_IN_LROUND):
7784             CASE_FLT_FN (BUILT_IN_LLROUND):
7785               real_round (&r, TYPE_MODE (ftype), &x);
7786               break;
7787
7788             default:
7789               gcc_unreachable ();
7790             }
7791
7792           REAL_VALUE_TO_INT (&lo, &hi, r);
7793           if (!fit_double_type (lo, hi, &lo2, &hi, itype))
7794             return build_int_cst_wide (itype, lo2, hi);
7795         }
7796     }
7797
7798   switch (DECL_FUNCTION_CODE (fndecl))
7799     {
7800     CASE_FLT_FN (BUILT_IN_LFLOOR):
7801     CASE_FLT_FN (BUILT_IN_LLFLOOR):
7802       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
7803       if (tree_expr_nonnegative_p (arg))
7804         return fold_build1_loc (loc, FIX_TRUNC_EXPR,
7805                             TREE_TYPE (TREE_TYPE (fndecl)), arg);
7806       break;
7807     default:;
7808     }
7809
7810   return fold_fixed_mathfn (loc, fndecl, arg);
7811 }
7812
7813 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7814    and their long and long long variants (i.e. ffsl and ffsll).  ARG is
7815    the argument to the call.  Return NULL_TREE if no simplification can
7816    be made.  */
7817
7818 static tree
7819 fold_builtin_bitop (tree fndecl, tree arg)
7820 {
7821   if (!validate_arg (arg, INTEGER_TYPE))
7822     return NULL_TREE;
7823
7824   /* Optimize for constant argument.  */
7825   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7826     {
7827       HOST_WIDE_INT hi, width, result;
7828       unsigned HOST_WIDE_INT lo;
7829       tree type;
7830
7831       type = TREE_TYPE (arg);
7832       width = TYPE_PRECISION (type);
7833       lo = TREE_INT_CST_LOW (arg);
7834
7835       /* Clear all the bits that are beyond the type's precision.  */
7836       if (width > HOST_BITS_PER_WIDE_INT)
7837         {
7838           hi = TREE_INT_CST_HIGH (arg);
7839           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7840             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7841         }
7842       else
7843         {
7844           hi = 0;
7845           if (width < HOST_BITS_PER_WIDE_INT)
7846             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7847         }
7848
7849       switch (DECL_FUNCTION_CODE (fndecl))
7850         {
7851         CASE_INT_FN (BUILT_IN_FFS):
7852           if (lo != 0)
7853             result = exact_log2 (lo & -lo) + 1;
7854           else if (hi != 0)
7855             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7856           else
7857             result = 0;
7858           break;
7859
7860         CASE_INT_FN (BUILT_IN_CLZ):
7861           if (hi != 0)
7862             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7863           else if (lo != 0)
7864             result = width - floor_log2 (lo) - 1;
7865           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7866             result = width;
7867           break;
7868
7869         CASE_INT_FN (BUILT_IN_CTZ):
7870           if (lo != 0)
7871             result = exact_log2 (lo & -lo);
7872           else if (hi != 0)
7873             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7874           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7875             result = width;
7876           break;
7877
7878         CASE_INT_FN (BUILT_IN_POPCOUNT):
7879           result = 0;
7880           while (lo)
7881             result++, lo &= lo - 1;
7882           while (hi)
7883             result++, hi &= hi - 1;
7884           break;
7885
7886         CASE_INT_FN (BUILT_IN_PARITY):
7887           result = 0;
7888           while (lo)
7889             result++, lo &= lo - 1;
7890           while (hi)
7891             result++, hi &= hi - 1;
7892           result &= 1;
7893           break;
7894
7895         default:
7896           gcc_unreachable ();
7897         }
7898
7899       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7900     }
7901
7902   return NULL_TREE;
7903 }
7904
7905 /* Fold function call to builtin_bswap and the long and long long
7906    variants.  Return NULL_TREE if no simplification can be made.  */
7907 static tree
7908 fold_builtin_bswap (tree fndecl, tree arg)
7909 {
7910   if (! validate_arg (arg, INTEGER_TYPE))
7911     return NULL_TREE;
7912
7913   /* Optimize constant value.  */
7914   if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
7915     {
7916       HOST_WIDE_INT hi, width, r_hi = 0;
7917       unsigned HOST_WIDE_INT lo, r_lo = 0;
7918       tree type;
7919
7920       type = TREE_TYPE (arg);
7921       width = TYPE_PRECISION (type);
7922       lo = TREE_INT_CST_LOW (arg);
7923       hi = TREE_INT_CST_HIGH (arg);
7924
7925       switch (DECL_FUNCTION_CODE (fndecl))
7926         {
7927           case BUILT_IN_BSWAP32:
7928           case BUILT_IN_BSWAP64:
7929             {
7930               int s;
7931
7932               for (s = 0; s < width; s += 8)
7933                 {
7934                   int d = width - s - 8;
7935                   unsigned HOST_WIDE_INT byte;
7936
7937                   if (s < HOST_BITS_PER_WIDE_INT)
7938                     byte = (lo >> s) & 0xff;
7939                   else
7940                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7941
7942                   if (d < HOST_BITS_PER_WIDE_INT)
7943                     r_lo |= byte << d;
7944                   else
7945                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7946                 }
7947             }
7948
7949             break;
7950
7951         default:
7952           gcc_unreachable ();
7953         }
7954
7955       if (width < HOST_BITS_PER_WIDE_INT)
7956         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7957       else
7958         return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7959     }
7960
7961   return NULL_TREE;
7962 }
7963
7964 /* A subroutine of fold_builtin to fold the various logarithmic
7965    functions.  Return NULL_TREE if no simplification can me made.
7966    FUNC is the corresponding MPFR logarithm function.  */
7967
7968 static tree
7969 fold_builtin_logarithm (location_t loc, tree fndecl, tree arg,
7970                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7971 {
7972   if (validate_arg (arg, REAL_TYPE))
7973     {
7974       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7975       tree res;
7976       const enum built_in_function fcode = builtin_mathfn_code (arg);
7977
7978       /* Calculate the result when the argument is a constant.  */
7979       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7980         return res;
7981
7982       /* Special case, optimize logN(expN(x)) = x.  */
7983       if (flag_unsafe_math_optimizations
7984           && ((func == mpfr_log
7985                && (fcode == BUILT_IN_EXP
7986                    || fcode == BUILT_IN_EXPF
7987                    || fcode == BUILT_IN_EXPL))
7988               || (func == mpfr_log2
7989                   && (fcode == BUILT_IN_EXP2
7990                       || fcode == BUILT_IN_EXP2F
7991                       || fcode == BUILT_IN_EXP2L))
7992               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7993         return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
7994
7995       /* Optimize logN(func()) for various exponential functions.  We
7996          want to determine the value "x" and the power "exponent" in
7997          order to transform logN(x**exponent) into exponent*logN(x).  */
7998       if (flag_unsafe_math_optimizations)
7999         {
8000           tree exponent = 0, x = 0;
8001
8002           switch (fcode)
8003           {
8004           CASE_FLT_FN (BUILT_IN_EXP):
8005             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
8006             x = build_real (type, real_value_truncate (TYPE_MODE (type), 
8007                                                        dconst_e ()));
8008             exponent = CALL_EXPR_ARG (arg, 0);
8009             break;
8010           CASE_FLT_FN (BUILT_IN_EXP2):
8011             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
8012             x = build_real (type, dconst2);
8013             exponent = CALL_EXPR_ARG (arg, 0);
8014             break;
8015           CASE_FLT_FN (BUILT_IN_EXP10):
8016           CASE_FLT_FN (BUILT_IN_POW10):
8017             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
8018             {
8019               REAL_VALUE_TYPE dconst10;
8020               real_from_integer (&dconst10, VOIDmode, 10, 0, 0);
8021               x = build_real (type, dconst10);
8022             }
8023             exponent = CALL_EXPR_ARG (arg, 0);
8024             break;
8025           CASE_FLT_FN (BUILT_IN_SQRT):
8026             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
8027             x = CALL_EXPR_ARG (arg, 0);
8028             exponent = build_real (type, dconsthalf);
8029             break;
8030           CASE_FLT_FN (BUILT_IN_CBRT):
8031             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
8032             x = CALL_EXPR_ARG (arg, 0);
8033             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
8034                                                               dconst_third ()));
8035             break;
8036           CASE_FLT_FN (BUILT_IN_POW):
8037             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
8038             x = CALL_EXPR_ARG (arg, 0);
8039             exponent = CALL_EXPR_ARG (arg, 1);
8040             break;
8041           default:
8042             break;
8043           }
8044
8045           /* Now perform the optimization.  */
8046           if (x && exponent)
8047             {
8048               tree logfn = build_call_expr_loc (loc, fndecl, 1, x);
8049               return fold_build2_loc (loc, MULT_EXPR, type, exponent, logfn);
8050             }
8051         }
8052     }
8053
8054   return NULL_TREE;
8055 }
8056
8057 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
8058    NULL_TREE if no simplification can be made.  */
8059
8060 static tree
8061 fold_builtin_hypot (location_t loc, tree fndecl,
8062                     tree arg0, tree arg1, tree type)
8063 {
8064   tree res, narg0, narg1;
8065
8066   if (!validate_arg (arg0, REAL_TYPE)
8067       || !validate_arg (arg1, REAL_TYPE))
8068     return NULL_TREE;
8069
8070   /* Calculate the result when the argument is a constant.  */
8071   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
8072     return res;
8073   
8074   /* If either argument to hypot has a negate or abs, strip that off.
8075      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
8076   narg0 = fold_strip_sign_ops (arg0);
8077   narg1 = fold_strip_sign_ops (arg1);
8078   if (narg0 || narg1)
8079     {
8080       return build_call_expr_loc (loc, fndecl, 2, narg0 ? narg0 : arg0, 
8081                               narg1 ? narg1 : arg1);
8082     }
8083   
8084   /* If either argument is zero, hypot is fabs of the other.  */
8085   if (real_zerop (arg0))
8086     return fold_build1_loc (loc, ABS_EXPR, type, arg1);
8087   else if (real_zerop (arg1))
8088     return fold_build1_loc (loc, ABS_EXPR, type, arg0);
8089       
8090   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
8091   if (flag_unsafe_math_optimizations
8092       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8093     {
8094       const REAL_VALUE_TYPE sqrt2_trunc
8095         = real_value_truncate (TYPE_MODE (type), dconst_sqrt2 ());
8096       return fold_build2_loc (loc, MULT_EXPR, type,
8097                           fold_build1_loc (loc, ABS_EXPR, type, arg0),
8098                           build_real (type, sqrt2_trunc));
8099     }
8100
8101   return NULL_TREE;
8102 }
8103
8104
8105 /* Fold a builtin function call to pow, powf, or powl.  Return
8106    NULL_TREE if no simplification can be made.  */
8107 static tree
8108 fold_builtin_pow (location_t loc, tree fndecl, tree arg0, tree arg1, tree type)
8109 {
8110   tree res;
8111
8112   if (!validate_arg (arg0, REAL_TYPE)
8113        || !validate_arg (arg1, REAL_TYPE))
8114     return NULL_TREE;
8115
8116   /* Calculate the result when the argument is a constant.  */
8117   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
8118     return res;
8119
8120   /* Optimize pow(1.0,y) = 1.0.  */
8121   if (real_onep (arg0))
8122     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8123
8124   if (TREE_CODE (arg1) == REAL_CST
8125       && !TREE_OVERFLOW (arg1))
8126     {
8127       REAL_VALUE_TYPE cint;
8128       REAL_VALUE_TYPE c;
8129       HOST_WIDE_INT n;
8130
8131       c = TREE_REAL_CST (arg1);
8132
8133       /* Optimize pow(x,0.0) = 1.0.  */
8134       if (REAL_VALUES_EQUAL (c, dconst0))
8135         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8136                                  arg0);
8137
8138       /* Optimize pow(x,1.0) = x.  */
8139       if (REAL_VALUES_EQUAL (c, dconst1))
8140         return arg0;
8141
8142       /* Optimize pow(x,-1.0) = 1.0/x.  */
8143       if (REAL_VALUES_EQUAL (c, dconstm1))
8144         return fold_build2_loc (loc, RDIV_EXPR, type,
8145                             build_real (type, dconst1), arg0);
8146
8147       /* Optimize pow(x,0.5) = sqrt(x).  */
8148       if (flag_unsafe_math_optimizations
8149           && REAL_VALUES_EQUAL (c, dconsthalf))
8150         {
8151           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8152
8153           if (sqrtfn != NULL_TREE)
8154             return build_call_expr_loc (loc, sqrtfn, 1, arg0);
8155         }
8156
8157       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8158       if (flag_unsafe_math_optimizations)
8159         {
8160           const REAL_VALUE_TYPE dconstroot
8161             = real_value_truncate (TYPE_MODE (type), dconst_third ());
8162
8163           if (REAL_VALUES_EQUAL (c, dconstroot))
8164             {
8165               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8166               if (cbrtfn != NULL_TREE)
8167                 return build_call_expr_loc (loc, cbrtfn, 1, arg0);
8168             }
8169         }
8170
8171       /* Check for an integer exponent.  */
8172       n = real_to_integer (&c);
8173       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8174       if (real_identical (&c, &cint))
8175         {
8176           /* Attempt to evaluate pow at compile-time, unless this should
8177              raise an exception.  */
8178           if (TREE_CODE (arg0) == REAL_CST
8179               && !TREE_OVERFLOW (arg0)
8180               && (n > 0
8181                   || (!flag_trapping_math && !flag_errno_math)
8182                   || !REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), dconst0)))
8183             {
8184               REAL_VALUE_TYPE x;
8185               bool inexact;
8186
8187               x = TREE_REAL_CST (arg0);
8188               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8189               if (flag_unsafe_math_optimizations || !inexact)
8190                 return build_real (type, x);
8191             }
8192
8193           /* Strip sign ops from even integer powers.  */
8194           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8195             {
8196               tree narg0 = fold_strip_sign_ops (arg0);
8197               if (narg0)
8198                 return build_call_expr_loc (loc, fndecl, 2, narg0, arg1);
8199             }
8200         }
8201     }
8202
8203   if (flag_unsafe_math_optimizations)
8204     {
8205       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8206
8207       /* Optimize pow(expN(x),y) = expN(x*y).  */
8208       if (BUILTIN_EXPONENT_P (fcode))
8209         {
8210           tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg0), 0);
8211           tree arg = CALL_EXPR_ARG (arg0, 0);
8212           arg = fold_build2_loc (loc, MULT_EXPR, type, arg, arg1);
8213           return build_call_expr_loc (loc, expfn, 1, arg);
8214         }
8215
8216       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8217       if (BUILTIN_SQRT_P (fcode))
8218         {
8219           tree narg0 = CALL_EXPR_ARG (arg0, 0);
8220           tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8221                                     build_real (type, dconsthalf));
8222           return build_call_expr_loc (loc, fndecl, 2, narg0, narg1);
8223         }
8224
8225       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8226       if (BUILTIN_CBRT_P (fcode))
8227         {
8228           tree arg = CALL_EXPR_ARG (arg0, 0);
8229           if (tree_expr_nonnegative_p (arg))
8230             {
8231               const REAL_VALUE_TYPE dconstroot
8232                 = real_value_truncate (TYPE_MODE (type), dconst_third ());
8233               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg1,
8234                                         build_real (type, dconstroot));
8235               return build_call_expr_loc (loc, fndecl, 2, arg, narg1);
8236             }
8237         }
8238
8239       /* Optimize pow(pow(x,y),z) = pow(x,y*z) iff x is nonnegative.  */
8240       if (fcode == BUILT_IN_POW
8241           || fcode == BUILT_IN_POWF
8242           || fcode == BUILT_IN_POWL)
8243         {
8244           tree arg00 = CALL_EXPR_ARG (arg0, 0);
8245           if (tree_expr_nonnegative_p (arg00))
8246             {
8247               tree arg01 = CALL_EXPR_ARG (arg0, 1);
8248               tree narg1 = fold_build2_loc (loc, MULT_EXPR, type, arg01, arg1);
8249               return build_call_expr_loc (loc, fndecl, 2, arg00, narg1);
8250             }
8251         }
8252     }
8253
8254   return NULL_TREE;
8255 }
8256
8257 /* Fold a builtin function call to powi, powif, or powil with argument ARG.
8258    Return NULL_TREE if no simplification can be made.  */
8259 static tree
8260 fold_builtin_powi (location_t loc, tree fndecl ATTRIBUTE_UNUSED,
8261                    tree arg0, tree arg1, tree type)
8262 {
8263   if (!validate_arg (arg0, REAL_TYPE)
8264       || !validate_arg (arg1, INTEGER_TYPE))
8265     return NULL_TREE;
8266
8267   /* Optimize pow(1.0,y) = 1.0.  */
8268   if (real_onep (arg0))
8269     return omit_one_operand_loc (loc, type, build_real (type, dconst1), arg1);
8270
8271   if (host_integerp (arg1, 0))
8272     {
8273       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8274
8275       /* Evaluate powi at compile-time.  */
8276       if (TREE_CODE (arg0) == REAL_CST
8277           && !TREE_OVERFLOW (arg0))
8278         {
8279           REAL_VALUE_TYPE x;
8280           x = TREE_REAL_CST (arg0);
8281           real_powi (&x, TYPE_MODE (type), &x, c);
8282           return build_real (type, x);
8283         }
8284
8285       /* Optimize pow(x,0) = 1.0.  */
8286       if (c == 0)
8287         return omit_one_operand_loc (loc, type, build_real (type, dconst1),
8288                                  arg0);
8289
8290       /* Optimize pow(x,1) = x.  */
8291       if (c == 1)
8292         return arg0;
8293
8294       /* Optimize pow(x,-1) = 1.0/x.  */
8295       if (c == -1)
8296         return fold_build2_loc (loc, RDIV_EXPR, type,
8297                            build_real (type, dconst1), arg0);
8298     }
8299
8300   return NULL_TREE;
8301 }
8302
8303 /* A subroutine of fold_builtin to fold the various exponent
8304    functions.  Return NULL_TREE if no simplification can be made.
8305    FUNC is the corresponding MPFR exponent function.  */
8306
8307 static tree
8308 fold_builtin_exponent (location_t loc, tree fndecl, tree arg,
8309                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8310 {
8311   if (validate_arg (arg, REAL_TYPE))
8312     {
8313       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8314       tree res;
8315       
8316       /* Calculate the result when the argument is a constant.  */
8317       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8318         return res;
8319
8320       /* Optimize expN(logN(x)) = x.  */
8321       if (flag_unsafe_math_optimizations)
8322         {
8323           const enum built_in_function fcode = builtin_mathfn_code (arg);
8324
8325           if ((func == mpfr_exp
8326                && (fcode == BUILT_IN_LOG
8327                    || fcode == BUILT_IN_LOGF
8328                    || fcode == BUILT_IN_LOGL))
8329               || (func == mpfr_exp2
8330                   && (fcode == BUILT_IN_LOG2
8331                       || fcode == BUILT_IN_LOG2F
8332                       || fcode == BUILT_IN_LOG2L))
8333               || (func == mpfr_exp10
8334                   && (fcode == BUILT_IN_LOG10
8335                       || fcode == BUILT_IN_LOG10F
8336                       || fcode == BUILT_IN_LOG10L)))
8337             return fold_convert_loc (loc, type, CALL_EXPR_ARG (arg, 0));
8338         }
8339     }
8340
8341   return NULL_TREE;
8342 }
8343
8344 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8345
8346 static bool
8347 var_decl_component_p (tree var)
8348 {
8349   tree inner = var;
8350   while (handled_component_p (inner))
8351     inner = TREE_OPERAND (inner, 0);
8352   return SSA_VAR_P (inner);
8353 }
8354
8355 /* Fold function call to builtin memset.  Return
8356    NULL_TREE if no simplification can be made.  */
8357
8358 static tree
8359 fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
8360                      tree type, bool ignore)
8361 {
8362   tree var, ret, etype;
8363   unsigned HOST_WIDE_INT length, cval;
8364
8365   if (! validate_arg (dest, POINTER_TYPE)
8366       || ! validate_arg (c, INTEGER_TYPE)
8367       || ! validate_arg (len, INTEGER_TYPE))
8368     return NULL_TREE;
8369
8370   if (! host_integerp (len, 1))
8371     return NULL_TREE;
8372
8373   /* If the LEN parameter is zero, return DEST.  */
8374   if (integer_zerop (len))
8375     return omit_one_operand_loc (loc, type, dest, c);
8376
8377   if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8378     return NULL_TREE;
8379
8380   var = dest;
8381   STRIP_NOPS (var);
8382   if (TREE_CODE (var) != ADDR_EXPR)
8383     return NULL_TREE;
8384
8385   var = TREE_OPERAND (var, 0);
8386   if (TREE_THIS_VOLATILE (var))
8387     return NULL_TREE;
8388
8389   etype = TREE_TYPE (var);
8390   if (TREE_CODE (etype) == ARRAY_TYPE)
8391     etype = TREE_TYPE (etype);
8392
8393   if (!INTEGRAL_TYPE_P (etype)
8394       && !POINTER_TYPE_P (etype))
8395     return NULL_TREE;
8396
8397   if (! var_decl_component_p (var))
8398     return NULL_TREE;
8399
8400   length = tree_low_cst (len, 1);
8401   if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
8402       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8403          < (int) length)
8404     return NULL_TREE;
8405
8406   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8407     return NULL_TREE;
8408
8409   if (integer_zerop (c))
8410     cval = 0;
8411   else
8412     {
8413       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8414         return NULL_TREE;
8415
8416       cval = tree_low_cst (c, 1);
8417       cval &= 0xff;
8418       cval |= cval << 8;
8419       cval |= cval << 16;
8420       cval |= (cval << 31) << 1;
8421     }
8422
8423   ret = build_int_cst_type (etype, cval);
8424   var = build_fold_indirect_ref_loc (loc,
8425                                  fold_convert_loc (loc,
8426                                                    build_pointer_type (etype),
8427                                                    dest));
8428   ret = build2 (MODIFY_EXPR, etype, var, ret);
8429   if (ignore)
8430     return ret;
8431
8432   return omit_one_operand_loc (loc, type, dest, ret);
8433 }
8434
8435 /* Fold function call to builtin memset.  Return
8436    NULL_TREE if no simplification can be made.  */
8437
8438 static tree
8439 fold_builtin_bzero (location_t loc, tree dest, tree size, bool ignore)
8440 {
8441   if (! validate_arg (dest, POINTER_TYPE)
8442       || ! validate_arg (size, INTEGER_TYPE))
8443     return NULL_TREE;
8444
8445   if (!ignore)
8446     return NULL_TREE;
8447
8448   /* New argument list transforming bzero(ptr x, int y) to
8449      memset(ptr x, int 0, size_t y).   This is done this way
8450      so that if it isn't expanded inline, we fallback to
8451      calling bzero instead of memset.  */
8452
8453   return fold_builtin_memset (loc, dest, integer_zero_node,
8454                               fold_convert_loc (loc, sizetype, size),
8455                               void_type_node, ignore);
8456 }
8457
8458 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8459    NULL_TREE if no simplification can be made.
8460    If ENDP is 0, return DEST (like memcpy).
8461    If ENDP is 1, return DEST+LEN (like mempcpy).
8462    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8463    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8464    (memmove).   */
8465
8466 static tree
8467 fold_builtin_memory_op (location_t loc, tree dest, tree src,
8468                         tree len, tree type, bool ignore, int endp)
8469 {
8470   tree destvar, srcvar, expr;
8471
8472   if (! validate_arg (dest, POINTER_TYPE)
8473       || ! validate_arg (src, POINTER_TYPE)
8474       || ! validate_arg (len, INTEGER_TYPE))
8475     return NULL_TREE;
8476
8477   /* If the LEN parameter is zero, return DEST.  */
8478   if (integer_zerop (len))
8479     return omit_one_operand_loc (loc, type, dest, src);
8480
8481   /* If SRC and DEST are the same (and not volatile), return
8482      DEST{,+LEN,+LEN-1}.  */
8483   if (operand_equal_p (src, dest, 0))
8484     expr = len;
8485   else
8486     {
8487       tree srctype, desttype;
8488       int src_align, dest_align;
8489
8490       if (endp == 3)
8491         {
8492           src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8493           dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8494
8495           /* Both DEST and SRC must be pointer types. 
8496              ??? This is what old code did.  Is the testing for pointer types
8497              really mandatory?
8498
8499              If either SRC is readonly or length is 1, we can use memcpy.  */
8500           if (!dest_align || !src_align)
8501             return NULL_TREE;
8502           if (readonly_data_expr (src)
8503               || (host_integerp (len, 1)
8504                   && (MIN (src_align, dest_align) / BITS_PER_UNIT
8505                       >= tree_low_cst (len, 1))))
8506             {
8507               tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8508               if (!fn)
8509                 return NULL_TREE;
8510               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8511             }
8512
8513           /* If *src and *dest can't overlap, optimize into memcpy as well.  */
8514           srcvar = build_fold_indirect_ref_loc (loc, src);
8515           destvar = build_fold_indirect_ref_loc (loc, dest);
8516           if (srcvar
8517               && !TREE_THIS_VOLATILE (srcvar)
8518               && destvar
8519               && !TREE_THIS_VOLATILE (destvar))
8520             {
8521               tree src_base, dest_base, fn;
8522               HOST_WIDE_INT src_offset = 0, dest_offset = 0;
8523               HOST_WIDE_INT size = -1;
8524               HOST_WIDE_INT maxsize = -1;
8525
8526               src_base = srcvar;
8527               if (handled_component_p (src_base))
8528                 src_base = get_ref_base_and_extent (src_base, &src_offset,
8529                                                     &size, &maxsize);
8530               dest_base = destvar;
8531               if (handled_component_p (dest_base))
8532                 dest_base = get_ref_base_and_extent (dest_base, &dest_offset,
8533                                                      &size, &maxsize);
8534               if (host_integerp (len, 1))
8535                 {
8536                   maxsize = tree_low_cst (len, 1);
8537                   if (maxsize
8538                       > INTTYPE_MAXIMUM (HOST_WIDE_INT) / BITS_PER_UNIT)
8539                     maxsize = -1;
8540                   else
8541                     maxsize *= BITS_PER_UNIT;
8542                 }
8543               else
8544                 maxsize = -1;
8545               if (SSA_VAR_P (src_base)
8546                   && SSA_VAR_P (dest_base))
8547                 {
8548                   if (operand_equal_p (src_base, dest_base, 0)
8549                       && ranges_overlap_p (src_offset, maxsize,
8550                                            dest_offset, maxsize))
8551                     return NULL_TREE;
8552                 }
8553               else if (TREE_CODE (src_base) == INDIRECT_REF
8554                        && TREE_CODE (dest_base) == INDIRECT_REF)
8555                 {
8556                   if (! operand_equal_p (TREE_OPERAND (src_base, 0),
8557                                          TREE_OPERAND (dest_base, 0), 0)
8558                       || ranges_overlap_p (src_offset, maxsize,
8559                                            dest_offset, maxsize))
8560                     return NULL_TREE;
8561                 }
8562               else
8563                 return NULL_TREE;
8564
8565               fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8566               if (!fn)
8567                 return NULL_TREE;
8568               return build_call_expr_loc (loc, fn, 3, dest, src, len);
8569             }
8570           return NULL_TREE;
8571         }
8572
8573       if (!host_integerp (len, 0))
8574         return NULL_TREE;
8575       /* FIXME:
8576          This logic lose for arguments like (type *)malloc (sizeof (type)),
8577          since we strip the casts of up to VOID return value from malloc.
8578          Perhaps we ought to inherit type from non-VOID argument here?  */
8579       STRIP_NOPS (src);
8580       STRIP_NOPS (dest);
8581       /* As we fold (void *)(p + CST) to (void *)p + CST undo this here.  */
8582       if (TREE_CODE (src) == POINTER_PLUS_EXPR)
8583         {
8584           tree tem = TREE_OPERAND (src, 0);
8585           STRIP_NOPS (tem);
8586           if (tem != TREE_OPERAND (src, 0))
8587             src = build1 (NOP_EXPR, TREE_TYPE (tem), src);
8588         }
8589       if (TREE_CODE (dest) == POINTER_PLUS_EXPR)
8590         {
8591           tree tem = TREE_OPERAND (dest, 0);
8592           STRIP_NOPS (tem);
8593           if (tem != TREE_OPERAND (dest, 0))
8594             dest = build1 (NOP_EXPR, TREE_TYPE (tem), dest);
8595         }
8596       srctype = TREE_TYPE (TREE_TYPE (src));
8597       if (srctype
8598           && TREE_CODE (srctype) == ARRAY_TYPE
8599           && !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8600         {
8601           srctype = TREE_TYPE (srctype);
8602           STRIP_NOPS (src);
8603           src = build1 (NOP_EXPR, build_pointer_type (srctype), src);
8604         }
8605       desttype = TREE_TYPE (TREE_TYPE (dest));
8606       if (desttype
8607           && TREE_CODE (desttype) == ARRAY_TYPE
8608           && !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8609         {
8610           desttype = TREE_TYPE (desttype);
8611           STRIP_NOPS (dest);
8612           dest = build1 (NOP_EXPR, build_pointer_type (desttype), dest);
8613         }
8614       if (!srctype || !desttype
8615           || !TYPE_SIZE_UNIT (srctype)
8616           || !TYPE_SIZE_UNIT (desttype)
8617           || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8618           || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8619           || TYPE_VOLATILE (srctype)
8620           || TYPE_VOLATILE (desttype))
8621         return NULL_TREE;
8622
8623       src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8624       dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8625       if (dest_align < (int) TYPE_ALIGN (desttype)
8626           || src_align < (int) TYPE_ALIGN (srctype))
8627         return NULL_TREE;
8628
8629       if (!ignore)
8630         dest = builtin_save_expr (dest);
8631
8632       srcvar = NULL_TREE;
8633       if (tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len))
8634         {
8635           srcvar = build_fold_indirect_ref_loc (loc, src);
8636           if (TREE_THIS_VOLATILE (srcvar))
8637             return NULL_TREE;
8638           else if (!tree_int_cst_equal (tree_expr_size (srcvar), len))
8639             srcvar = NULL_TREE;
8640           /* With memcpy, it is possible to bypass aliasing rules, so without
8641              this check i.e. execute/20060930-2.c would be misoptimized,
8642              because it use conflicting alias set to hold argument for the
8643              memcpy call.  This check is probably unnecessary with
8644              -fno-strict-aliasing.  Similarly for destvar.  See also
8645              PR29286.  */
8646           else if (!var_decl_component_p (srcvar))
8647             srcvar = NULL_TREE;
8648         }
8649
8650       destvar = NULL_TREE;
8651       if (tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8652         {
8653           destvar = build_fold_indirect_ref_loc (loc, dest);
8654           if (TREE_THIS_VOLATILE (destvar))
8655             return NULL_TREE;
8656           else if (!tree_int_cst_equal (tree_expr_size (destvar), len))
8657             destvar = NULL_TREE;
8658           else if (!var_decl_component_p (destvar))
8659             destvar = NULL_TREE;
8660         }
8661
8662       if (srcvar == NULL_TREE && destvar == NULL_TREE)
8663         return NULL_TREE;
8664
8665       if (srcvar == NULL_TREE)
8666         {
8667           tree srcptype;
8668           if (TREE_ADDRESSABLE (TREE_TYPE (destvar)))
8669             return NULL_TREE;
8670
8671           srctype = build_qualified_type (desttype, 0);
8672           if (src_align < (int) TYPE_ALIGN (srctype))
8673             {
8674               if (AGGREGATE_TYPE_P (srctype)
8675                   || SLOW_UNALIGNED_ACCESS (TYPE_MODE (srctype), src_align))
8676                 return NULL_TREE;
8677
8678               srctype = build_variant_type_copy (srctype);
8679               TYPE_ALIGN (srctype) = src_align;
8680               TYPE_USER_ALIGN (srctype) = 1;
8681               TYPE_PACKED (srctype) = 1;
8682             }
8683           srcptype = build_pointer_type_for_mode (srctype, ptr_mode, true);
8684           src = fold_convert_loc (loc, srcptype, src);
8685           srcvar = build_fold_indirect_ref_loc (loc, src);
8686         }
8687       else if (destvar == NULL_TREE)
8688         {
8689           tree destptype;
8690           if (TREE_ADDRESSABLE (TREE_TYPE (srcvar)))
8691             return NULL_TREE;
8692
8693           desttype = build_qualified_type (srctype, 0);
8694           if (dest_align < (int) TYPE_ALIGN (desttype))
8695             {
8696               if (AGGREGATE_TYPE_P (desttype)
8697                   || SLOW_UNALIGNED_ACCESS (TYPE_MODE (desttype), dest_align))
8698                 return NULL_TREE;
8699
8700               desttype = build_variant_type_copy (desttype);
8701               TYPE_ALIGN (desttype) = dest_align;
8702               TYPE_USER_ALIGN (desttype) = 1;
8703               TYPE_PACKED (desttype) = 1;
8704             }
8705           destptype = build_pointer_type_for_mode (desttype, ptr_mode, true);
8706           dest = fold_convert_loc (loc, destptype, dest);
8707           destvar = build_fold_indirect_ref_loc (loc, dest);
8708         }
8709
8710       if (srctype == desttype
8711           || (gimple_in_ssa_p (cfun)
8712               && useless_type_conversion_p (desttype, srctype)))
8713         expr = srcvar;
8714       else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8715            || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8716           && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8717               || POINTER_TYPE_P (TREE_TYPE (destvar))))
8718         expr = fold_convert_loc (loc, TREE_TYPE (destvar), srcvar);
8719       else
8720         expr = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
8721                             TREE_TYPE (destvar), srcvar);
8722       expr = build2 (MODIFY_EXPR, TREE_TYPE (destvar), destvar, expr);
8723     }
8724
8725   if (ignore)
8726     return expr;
8727
8728   if (endp == 0 || endp == 3)
8729     return omit_one_operand_loc (loc, type, dest, expr);
8730
8731   if (expr == len)
8732     expr = NULL_TREE;
8733
8734   if (endp == 2)
8735     len = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (len), len,
8736                        ssize_int (1));
8737
8738   len = fold_convert_loc (loc, sizetype, len);
8739   dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8740   dest = fold_convert_loc (loc, type, dest);
8741   if (expr)
8742     dest = omit_one_operand_loc (loc, type, dest, expr);
8743   return dest;
8744 }
8745
8746 /* Fold function call to builtin strcpy with arguments DEST and SRC.
8747    If LEN is not NULL, it represents the length of the string to be
8748    copied.  Return NULL_TREE if no simplification can be made.  */
8749
8750 tree
8751 fold_builtin_strcpy (location_t loc, tree fndecl, tree dest, tree src, tree len)
8752 {
8753   tree fn;
8754
8755   if (!validate_arg (dest, POINTER_TYPE)
8756       || !validate_arg (src, POINTER_TYPE))
8757     return NULL_TREE;
8758
8759   /* If SRC and DEST are the same (and not volatile), return DEST.  */
8760   if (operand_equal_p (src, dest, 0))
8761     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
8762
8763   if (optimize_function_for_size_p (cfun))
8764     return NULL_TREE;
8765
8766   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8767   if (!fn)
8768     return NULL_TREE;
8769
8770   if (!len)
8771     {
8772       len = c_strlen (src, 1);
8773       if (! len || TREE_SIDE_EFFECTS (len))
8774         return NULL_TREE;
8775     }
8776
8777   len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8778   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8779                            build_call_expr_loc (loc, fn, 3, dest, src, len));
8780 }
8781
8782 /* Fold function call to builtin stpcpy with arguments DEST and SRC.
8783    Return NULL_TREE if no simplification can be made.  */
8784
8785 static tree
8786 fold_builtin_stpcpy (location_t loc, tree fndecl, tree dest, tree src)
8787 {
8788   tree fn, len, lenp1, call, type;
8789
8790   if (!validate_arg (dest, POINTER_TYPE)
8791       || !validate_arg (src, POINTER_TYPE))
8792     return NULL_TREE;
8793
8794   len = c_strlen (src, 1);
8795   if (!len
8796       || TREE_CODE (len) != INTEGER_CST)
8797     return NULL_TREE;
8798
8799   if (optimize_function_for_size_p (cfun)
8800       /* If length is zero it's small enough.  */
8801       && !integer_zerop (len))
8802     return NULL_TREE;
8803
8804   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8805   if (!fn)
8806     return NULL_TREE;
8807
8808   lenp1 = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
8809   /* We use dest twice in building our expression.  Save it from
8810      multiple expansions.  */
8811   dest = builtin_save_expr (dest);
8812   call = build_call_expr_loc (loc, fn, 3, dest, src, lenp1);
8813
8814   type = TREE_TYPE (TREE_TYPE (fndecl));
8815   len = fold_convert_loc (loc, sizetype, len);
8816   dest = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
8817   dest = fold_convert_loc (loc, type, dest);
8818   dest = omit_one_operand_loc (loc, type, dest, call);
8819   return dest;
8820 }
8821
8822 /* Fold function call to builtin strncpy with arguments DEST, SRC, and LEN.
8823    If SLEN is not NULL, it represents the length of the source string.
8824    Return NULL_TREE if no simplification can be made.  */
8825
8826 tree
8827 fold_builtin_strncpy (location_t loc, tree fndecl, tree dest,
8828                       tree src, tree len, tree slen)
8829 {
8830   tree fn;
8831
8832   if (!validate_arg (dest, POINTER_TYPE)
8833       || !validate_arg (src, POINTER_TYPE)
8834       || !validate_arg (len, INTEGER_TYPE))
8835     return NULL_TREE;
8836
8837   /* If the LEN parameter is zero, return DEST.  */
8838   if (integer_zerop (len))
8839     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8840
8841   /* We can't compare slen with len as constants below if len is not a
8842      constant.  */
8843   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8844     return NULL_TREE;
8845
8846   if (!slen)
8847     slen = c_strlen (src, 1);
8848
8849   /* Now, we must be passed a constant src ptr parameter.  */
8850   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8851     return NULL_TREE;
8852
8853   slen = size_binop_loc (loc, PLUS_EXPR, slen, ssize_int (1));
8854
8855   /* We do not support simplification of this case, though we do
8856      support it when expanding trees into RTL.  */
8857   /* FIXME: generate a call to __builtin_memset.  */
8858   if (tree_int_cst_lt (slen, len))
8859     return NULL_TREE;
8860
8861   /* OK transform into builtin memcpy.  */
8862   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8863   if (!fn)
8864     return NULL_TREE;
8865   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
8866                            build_call_expr_loc (loc, fn, 3, dest, src, len));
8867 }
8868
8869 /* Fold function call to builtin memchr.  ARG1, ARG2 and LEN are the
8870    arguments to the call, and TYPE is its return type.
8871    Return NULL_TREE if no simplification can be made.  */
8872
8873 static tree
8874 fold_builtin_memchr (location_t loc, tree arg1, tree arg2, tree len, tree type)
8875 {
8876   if (!validate_arg (arg1, POINTER_TYPE)
8877       || !validate_arg (arg2, INTEGER_TYPE)
8878       || !validate_arg (len, INTEGER_TYPE))
8879     return NULL_TREE;
8880   else
8881     {
8882       const char *p1;
8883
8884       if (TREE_CODE (arg2) != INTEGER_CST
8885           || !host_integerp (len, 1))
8886         return NULL_TREE;
8887
8888       p1 = c_getstr (arg1);
8889       if (p1 && compare_tree_int (len, strlen (p1) + 1) <= 0)
8890         {
8891           char c;
8892           const char *r;
8893           tree tem;
8894
8895           if (target_char_cast (arg2, &c))
8896             return NULL_TREE;
8897
8898           r = (char *) memchr (p1, c, tree_low_cst (len, 1));
8899
8900           if (r == NULL)
8901             return build_int_cst (TREE_TYPE (arg1), 0);
8902
8903           tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (arg1), arg1,
8904                              size_int (r - p1));
8905           return fold_convert_loc (loc, type, tem);
8906         }
8907       return NULL_TREE;
8908     }
8909 }
8910
8911 /* Fold function call to builtin memcmp with arguments ARG1 and ARG2.
8912    Return NULL_TREE if no simplification can be made.  */
8913
8914 static tree
8915 fold_builtin_memcmp (location_t loc, tree arg1, tree arg2, tree len)
8916 {
8917   const char *p1, *p2;
8918
8919   if (!validate_arg (arg1, POINTER_TYPE)
8920       || !validate_arg (arg2, POINTER_TYPE)
8921       || !validate_arg (len, INTEGER_TYPE))
8922     return NULL_TREE;
8923
8924   /* If the LEN parameter is zero, return zero.  */
8925   if (integer_zerop (len))
8926     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
8927                               arg1, arg2);
8928
8929   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8930   if (operand_equal_p (arg1, arg2, 0))
8931     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
8932
8933   p1 = c_getstr (arg1);
8934   p2 = c_getstr (arg2);
8935
8936   /* If all arguments are constant, and the value of len is not greater
8937      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8938   if (host_integerp (len, 1) && p1 && p2
8939       && compare_tree_int (len, strlen (p1) + 1) <= 0
8940       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8941     {
8942       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8943
8944       if (r > 0)
8945         return integer_one_node;
8946       else if (r < 0)
8947         return integer_minus_one_node;
8948       else
8949         return integer_zero_node;
8950     }
8951
8952   /* If len parameter is one, return an expression corresponding to
8953      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8954   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8955     {
8956       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8957       tree cst_uchar_ptr_node
8958         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8959
8960       tree ind1
8961         = fold_convert_loc (loc, integer_type_node,
8962                             build1 (INDIRECT_REF, cst_uchar_node,
8963                                     fold_convert_loc (loc,
8964                                                       cst_uchar_ptr_node,
8965                                                       arg1)));
8966       tree ind2
8967         = fold_convert_loc (loc, integer_type_node,
8968                             build1 (INDIRECT_REF, cst_uchar_node,
8969                                     fold_convert_loc (loc,
8970                                                       cst_uchar_ptr_node,
8971                                                       arg2)));
8972       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
8973     }
8974
8975   return NULL_TREE;
8976 }
8977
8978 /* Fold function call to builtin strcmp with arguments ARG1 and ARG2.
8979    Return NULL_TREE if no simplification can be made.  */
8980
8981 static tree
8982 fold_builtin_strcmp (location_t loc, tree arg1, tree arg2)
8983 {
8984   const char *p1, *p2;
8985
8986   if (!validate_arg (arg1, POINTER_TYPE)
8987       || !validate_arg (arg2, POINTER_TYPE))
8988     return NULL_TREE;
8989
8990   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8991   if (operand_equal_p (arg1, arg2, 0))
8992     return integer_zero_node;
8993
8994   p1 = c_getstr (arg1);
8995   p2 = c_getstr (arg2);
8996
8997   if (p1 && p2)
8998     {
8999       const int i = strcmp (p1, p2);
9000       if (i < 0)
9001         return integer_minus_one_node;
9002       else if (i > 0)
9003         return integer_one_node;
9004       else
9005         return integer_zero_node;
9006     }
9007
9008   /* If the second arg is "", return *(const unsigned char*)arg1.  */
9009   if (p2 && *p2 == '\0')
9010     {
9011       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9012       tree cst_uchar_ptr_node
9013         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9014
9015       return fold_convert_loc (loc, integer_type_node,
9016                                build1 (INDIRECT_REF, cst_uchar_node,
9017                                        fold_convert_loc (loc,
9018                                                          cst_uchar_ptr_node,
9019                                                          arg1)));
9020     }
9021
9022   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
9023   if (p1 && *p1 == '\0')
9024     {
9025       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9026       tree cst_uchar_ptr_node
9027         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9028
9029       tree temp
9030         = fold_convert_loc (loc, integer_type_node,
9031                             build1 (INDIRECT_REF, cst_uchar_node,
9032                                     fold_convert_loc (loc,
9033                                                       cst_uchar_ptr_node,
9034                                                       arg2)));
9035       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9036     }
9037
9038   return NULL_TREE;
9039 }
9040
9041 /* Fold function call to builtin strncmp with arguments ARG1, ARG2, and LEN.
9042    Return NULL_TREE if no simplification can be made.  */
9043
9044 static tree
9045 fold_builtin_strncmp (location_t loc, tree arg1, tree arg2, tree len)
9046 {
9047   const char *p1, *p2;
9048
9049   if (!validate_arg (arg1, POINTER_TYPE)
9050       || !validate_arg (arg2, POINTER_TYPE)
9051       || !validate_arg (len, INTEGER_TYPE))
9052     return NULL_TREE;
9053
9054   /* If the LEN parameter is zero, return zero.  */
9055   if (integer_zerop (len))
9056     return omit_two_operands_loc (loc, integer_type_node, integer_zero_node,
9057                               arg1, arg2);
9058
9059   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
9060   if (operand_equal_p (arg1, arg2, 0))
9061     return omit_one_operand_loc (loc, integer_type_node, integer_zero_node, len);
9062
9063   p1 = c_getstr (arg1);
9064   p2 = c_getstr (arg2);
9065
9066   if (host_integerp (len, 1) && p1 && p2)
9067     {
9068       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
9069       if (i > 0)
9070         return integer_one_node;
9071       else if (i < 0)
9072         return integer_minus_one_node;
9073       else
9074         return integer_zero_node;
9075     }
9076
9077   /* If the second arg is "", and the length is greater than zero,
9078      return *(const unsigned char*)arg1.  */
9079   if (p2 && *p2 == '\0'
9080       && TREE_CODE (len) == INTEGER_CST
9081       && tree_int_cst_sgn (len) == 1)
9082     {
9083       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9084       tree cst_uchar_ptr_node
9085         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9086
9087       return fold_convert_loc (loc, integer_type_node,
9088                                build1 (INDIRECT_REF, cst_uchar_node,
9089                                        fold_convert_loc (loc,
9090                                                          cst_uchar_ptr_node,
9091                                                          arg1)));
9092     }
9093
9094   /* If the first arg is "", and the length is greater than zero,
9095      return -*(const unsigned char*)arg2.  */
9096   if (p1 && *p1 == '\0'
9097       && TREE_CODE (len) == INTEGER_CST
9098       && tree_int_cst_sgn (len) == 1)
9099     {
9100       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9101       tree cst_uchar_ptr_node
9102         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9103
9104       tree temp = fold_convert_loc (loc, integer_type_node,
9105                                     build1 (INDIRECT_REF, cst_uchar_node,
9106                                             fold_convert_loc (loc,
9107                                                               cst_uchar_ptr_node,
9108                                                               arg2)));
9109       return fold_build1_loc (loc, NEGATE_EXPR, integer_type_node, temp);
9110     }
9111
9112   /* If len parameter is one, return an expression corresponding to
9113      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
9114   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
9115     {
9116       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9117       tree cst_uchar_ptr_node
9118         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
9119
9120       tree ind1 = fold_convert_loc (loc, integer_type_node,
9121                                     build1 (INDIRECT_REF, cst_uchar_node,
9122                                             fold_convert_loc (loc,
9123                                                               cst_uchar_ptr_node,
9124                                                               arg1)));
9125       tree ind2 = fold_convert_loc (loc, integer_type_node,
9126                                     build1 (INDIRECT_REF, cst_uchar_node,
9127                                             fold_convert_loc (loc,
9128                                                               cst_uchar_ptr_node,
9129                                                               arg2)));
9130       return fold_build2_loc (loc, MINUS_EXPR, integer_type_node, ind1, ind2);
9131     }
9132
9133   return NULL_TREE;
9134 }
9135
9136 /* Fold function call to builtin signbit, signbitf or signbitl with argument
9137    ARG.  Return NULL_TREE if no simplification can be made.  */
9138
9139 static tree
9140 fold_builtin_signbit (location_t loc, tree arg, tree type)
9141 {
9142   tree temp;
9143
9144   if (!validate_arg (arg, REAL_TYPE))
9145     return NULL_TREE;
9146
9147   /* If ARG is a compile-time constant, determine the result.  */
9148   if (TREE_CODE (arg) == REAL_CST
9149       && !TREE_OVERFLOW (arg))
9150     {
9151       REAL_VALUE_TYPE c;
9152
9153       c = TREE_REAL_CST (arg);
9154       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
9155       return fold_convert_loc (loc, type, temp);
9156     }
9157
9158   /* If ARG is non-negative, the result is always zero.  */
9159   if (tree_expr_nonnegative_p (arg))
9160     return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9161
9162   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
9163   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
9164     return fold_build2_loc (loc, LT_EXPR, type, arg,
9165                         build_real (TREE_TYPE (arg), dconst0));
9166
9167   return NULL_TREE;
9168 }
9169
9170 /* Fold function call to builtin copysign, copysignf or copysignl with
9171    arguments ARG1 and ARG2.  Return NULL_TREE if no simplification can
9172    be made.  */
9173
9174 static tree
9175 fold_builtin_copysign (location_t loc, tree fndecl,
9176                        tree arg1, tree arg2, tree type)
9177 {
9178   tree tem;
9179
9180   if (!validate_arg (arg1, REAL_TYPE)
9181       || !validate_arg (arg2, REAL_TYPE))
9182     return NULL_TREE;
9183
9184   /* copysign(X,X) is X.  */
9185   if (operand_equal_p (arg1, arg2, 0))
9186     return fold_convert_loc (loc, type, arg1);
9187
9188   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
9189   if (TREE_CODE (arg1) == REAL_CST
9190       && TREE_CODE (arg2) == REAL_CST
9191       && !TREE_OVERFLOW (arg1)
9192       && !TREE_OVERFLOW (arg2))
9193     {
9194       REAL_VALUE_TYPE c1, c2;
9195
9196       c1 = TREE_REAL_CST (arg1);
9197       c2 = TREE_REAL_CST (arg2);
9198       /* c1.sign := c2.sign.  */
9199       real_copysign (&c1, &c2);
9200       return build_real (type, c1);
9201     }
9202
9203   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
9204      Remember to evaluate Y for side-effects.  */
9205   if (tree_expr_nonnegative_p (arg2))
9206     return omit_one_operand_loc (loc, type,
9207                              fold_build1_loc (loc, ABS_EXPR, type, arg1),
9208                              arg2);
9209
9210   /* Strip sign changing operations for the first argument.  */
9211   tem = fold_strip_sign_ops (arg1);
9212   if (tem)
9213     return build_call_expr_loc (loc, fndecl, 2, tem, arg2);
9214
9215   return NULL_TREE;
9216 }
9217
9218 /* Fold a call to builtin isascii with argument ARG.  */
9219
9220 static tree
9221 fold_builtin_isascii (location_t loc, tree arg)
9222 {
9223   if (!validate_arg (arg, INTEGER_TYPE))
9224     return NULL_TREE;
9225   else
9226     {
9227       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
9228       arg = fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
9229                          build_int_cst (NULL_TREE,
9230                                         ~ (unsigned HOST_WIDE_INT) 0x7f));
9231       return fold_build2_loc (loc, EQ_EXPR, integer_type_node,
9232                           arg, integer_zero_node);
9233     }
9234 }
9235
9236 /* Fold a call to builtin toascii with argument ARG.  */
9237
9238 static tree
9239 fold_builtin_toascii (location_t loc, tree arg)
9240 {
9241   if (!validate_arg (arg, INTEGER_TYPE))
9242     return NULL_TREE;
9243       
9244   /* Transform toascii(c) -> (c & 0x7f).  */
9245   return fold_build2_loc (loc, BIT_AND_EXPR, integer_type_node, arg,
9246                       build_int_cst (NULL_TREE, 0x7f));
9247 }
9248
9249 /* Fold a call to builtin isdigit with argument ARG.  */
9250
9251 static tree
9252 fold_builtin_isdigit (location_t loc, tree arg)
9253 {
9254   if (!validate_arg (arg, INTEGER_TYPE))
9255     return NULL_TREE;
9256   else
9257     {
9258       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
9259       /* According to the C standard, isdigit is unaffected by locale.
9260          However, it definitely is affected by the target character set.  */
9261       unsigned HOST_WIDE_INT target_digit0
9262         = lang_hooks.to_target_charset ('0');
9263
9264       if (target_digit0 == 0)
9265         return NULL_TREE;
9266
9267       arg = fold_convert_loc (loc, unsigned_type_node, arg);
9268       arg = fold_build2 (MINUS_EXPR, unsigned_type_node, arg,
9269                          build_int_cst (unsigned_type_node, target_digit0));
9270       return fold_build2_loc (loc, LE_EXPR, integer_type_node, arg,
9271                           build_int_cst (unsigned_type_node, 9));
9272     }
9273 }
9274
9275 /* Fold a call to fabs, fabsf or fabsl with argument ARG.  */
9276
9277 static tree
9278 fold_builtin_fabs (location_t loc, tree arg, tree type)
9279 {
9280   if (!validate_arg (arg, REAL_TYPE))
9281     return NULL_TREE;
9282
9283   arg = fold_convert_loc (loc, type, arg);
9284   if (TREE_CODE (arg) == REAL_CST)
9285     return fold_abs_const (arg, type);
9286   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9287 }
9288
9289 /* Fold a call to abs, labs, llabs or imaxabs with argument ARG.  */
9290
9291 static tree
9292 fold_builtin_abs (location_t loc, tree arg, tree type)
9293 {
9294   if (!validate_arg (arg, INTEGER_TYPE))
9295     return NULL_TREE;
9296
9297   arg = fold_convert_loc (loc, type, arg);
9298   if (TREE_CODE (arg) == INTEGER_CST)
9299     return fold_abs_const (arg, type);
9300   return fold_build1_loc (loc, ABS_EXPR, type, arg);
9301 }
9302
9303 /* Fold a call to builtin fmin or fmax.  */
9304
9305 static tree
9306 fold_builtin_fmin_fmax (location_t loc, tree arg0, tree arg1,
9307                         tree type, bool max)
9308 {
9309   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, REAL_TYPE))
9310     {
9311       /* Calculate the result when the argument is a constant.  */
9312       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9313
9314       if (res)
9315         return res;
9316
9317       /* If either argument is NaN, return the other one.  Avoid the
9318          transformation if we get (and honor) a signalling NaN.  Using
9319          omit_one_operand() ensures we create a non-lvalue.  */
9320       if (TREE_CODE (arg0) == REAL_CST
9321           && real_isnan (&TREE_REAL_CST (arg0))
9322           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9323               || ! TREE_REAL_CST (arg0).signalling))
9324         return omit_one_operand_loc (loc, type, arg1, arg0);
9325       if (TREE_CODE (arg1) == REAL_CST
9326           && real_isnan (&TREE_REAL_CST (arg1))
9327           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9328               || ! TREE_REAL_CST (arg1).signalling))
9329         return omit_one_operand_loc (loc, type, arg0, arg1);
9330
9331       /* Transform fmin/fmax(x,x) -> x.  */
9332       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9333         return omit_one_operand_loc (loc, type, arg0, arg1);
9334       
9335       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9336          functions to return the numeric arg if the other one is NaN.
9337          These tree codes don't honor that, so only transform if
9338          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9339          handled, so we don't have to worry about it either.  */
9340       if (flag_finite_math_only)
9341         return fold_build2_loc (loc, (max ? MAX_EXPR : MIN_EXPR), type,
9342                             fold_convert_loc (loc, type, arg0),
9343                             fold_convert_loc (loc, type, arg1));
9344     }
9345   return NULL_TREE;
9346 }
9347
9348 /* Fold a call to builtin carg(a+bi) -> atan2(b,a).  */
9349
9350 static tree
9351 fold_builtin_carg (location_t loc, tree arg, tree type)
9352 {
9353   if (validate_arg (arg, COMPLEX_TYPE)
9354       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE)
9355     {
9356       tree atan2_fn = mathfn_built_in (type, BUILT_IN_ATAN2);
9357       
9358       if (atan2_fn)
9359         {
9360           tree new_arg = builtin_save_expr (arg);
9361           tree r_arg = fold_build1_loc (loc, REALPART_EXPR, type, new_arg);
9362           tree i_arg = fold_build1_loc (loc, IMAGPART_EXPR, type, new_arg);
9363           return build_call_expr_loc (loc, atan2_fn, 2, i_arg, r_arg);
9364         }
9365     }
9366   
9367   return NULL_TREE;
9368 }
9369
9370 /* Fold a call to builtin logb/ilogb.  */
9371
9372 static tree
9373 fold_builtin_logb (location_t loc, tree arg, tree rettype)
9374 {
9375   if (! validate_arg (arg, REAL_TYPE))
9376     return NULL_TREE;
9377   
9378   STRIP_NOPS (arg);
9379       
9380   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9381     {
9382       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9383           
9384       switch (value->cl)
9385       {
9386       case rvc_nan:
9387       case rvc_inf:
9388         /* If arg is Inf or NaN and we're logb, return it.  */
9389         if (TREE_CODE (rettype) == REAL_TYPE)
9390           return fold_convert_loc (loc, rettype, arg);
9391         /* Fall through... */
9392       case rvc_zero:
9393         /* Zero may set errno and/or raise an exception for logb, also
9394            for ilogb we don't know FP_ILOGB0.  */
9395         return NULL_TREE;
9396       case rvc_normal:
9397         /* For normal numbers, proceed iff radix == 2.  In GCC,
9398            normalized significands are in the range [0.5, 1.0).  We
9399            want the exponent as if they were [1.0, 2.0) so get the
9400            exponent and subtract 1.  */
9401         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9402           return fold_convert_loc (loc, rettype,
9403                                    build_int_cst (NULL_TREE,
9404                                                   REAL_EXP (value)-1));
9405         break;
9406       }
9407     }
9408   
9409   return NULL_TREE;
9410 }
9411
9412 /* Fold a call to builtin significand, if radix == 2.  */
9413
9414 static tree
9415 fold_builtin_significand (location_t loc, tree arg, tree rettype)
9416 {
9417   if (! validate_arg (arg, REAL_TYPE))
9418     return NULL_TREE;
9419   
9420   STRIP_NOPS (arg);
9421       
9422   if (TREE_CODE (arg) == REAL_CST && ! TREE_OVERFLOW (arg))
9423     {
9424       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg);
9425           
9426       switch (value->cl)
9427       {
9428       case rvc_zero:
9429       case rvc_nan:
9430       case rvc_inf:
9431         /* If arg is +-0, +-Inf or +-NaN, then return it.  */
9432         return fold_convert_loc (loc, rettype, arg);
9433       case rvc_normal:
9434         /* For normal numbers, proceed iff radix == 2.  */
9435         if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)))->b == 2)
9436           {
9437             REAL_VALUE_TYPE result = *value;
9438             /* In GCC, normalized significands are in the range [0.5,
9439                1.0).  We want them to be [1.0, 2.0) so set the
9440                exponent to 1.  */
9441             SET_REAL_EXP (&result, 1);
9442             return build_real (rettype, result);
9443           }
9444         break;
9445       }
9446     }
9447   
9448   return NULL_TREE;
9449 }
9450
9451 /* Fold a call to builtin frexp, we can assume the base is 2.  */
9452
9453 static tree
9454 fold_builtin_frexp (location_t loc, tree arg0, tree arg1, tree rettype)
9455 {
9456   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9457     return NULL_TREE;
9458   
9459   STRIP_NOPS (arg0);
9460       
9461   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9462     return NULL_TREE;
9463   
9464   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9465
9466   /* Proceed if a valid pointer type was passed in.  */
9467   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == integer_type_node)
9468     {
9469       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9470       tree frac, exp;
9471           
9472       switch (value->cl)
9473       {
9474       case rvc_zero:
9475         /* For +-0, return (*exp = 0, +-0).  */
9476         exp = integer_zero_node;
9477         frac = arg0;
9478         break;
9479       case rvc_nan:
9480       case rvc_inf:
9481         /* For +-NaN or +-Inf, *exp is unspecified, return arg0.  */
9482         return omit_one_operand_loc (loc, rettype, arg0, arg1);
9483       case rvc_normal:
9484         {
9485           /* Since the frexp function always expects base 2, and in
9486              GCC normalized significands are already in the range
9487              [0.5, 1.0), we have exactly what frexp wants.  */
9488           REAL_VALUE_TYPE frac_rvt = *value;
9489           SET_REAL_EXP (&frac_rvt, 0);
9490           frac = build_real (rettype, frac_rvt);
9491           exp = build_int_cst (NULL_TREE, REAL_EXP (value));
9492         }
9493         break;
9494       default:
9495         gcc_unreachable ();
9496       }
9497                 
9498       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9499       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1, exp);
9500       TREE_SIDE_EFFECTS (arg1) = 1;
9501       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1, frac);
9502     }
9503
9504   return NULL_TREE;
9505 }
9506
9507 /* Fold a call to builtin ldexp or scalbn/scalbln.  If LDEXP is true
9508    then we can assume the base is two.  If it's false, then we have to
9509    check the mode of the TYPE parameter in certain cases.  */
9510
9511 static tree
9512 fold_builtin_load_exponent (location_t loc, tree arg0, tree arg1,
9513                             tree type, bool ldexp)
9514 {
9515   if (validate_arg (arg0, REAL_TYPE) && validate_arg (arg1, INTEGER_TYPE))
9516     {
9517       STRIP_NOPS (arg0);
9518       STRIP_NOPS (arg1);
9519
9520       /* If arg0 is 0, Inf or NaN, or if arg1 is 0, then return arg0.  */
9521       if (real_zerop (arg0) || integer_zerop (arg1)
9522           || (TREE_CODE (arg0) == REAL_CST
9523               && !real_isfinite (&TREE_REAL_CST (arg0))))
9524         return omit_one_operand_loc (loc, type, arg0, arg1);
9525       
9526       /* If both arguments are constant, then try to evaluate it.  */
9527       if ((ldexp || REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2)
9528           && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
9529           && host_integerp (arg1, 0))
9530         {
9531           /* Bound the maximum adjustment to twice the range of the
9532              mode's valid exponents.  Use abs to ensure the range is
9533              positive as a sanity check.  */
9534           const long max_exp_adj = 2 * 
9535             labs (REAL_MODE_FORMAT (TYPE_MODE (type))->emax
9536                  - REAL_MODE_FORMAT (TYPE_MODE (type))->emin);
9537
9538           /* Get the user-requested adjustment.  */
9539           const HOST_WIDE_INT req_exp_adj = tree_low_cst (arg1, 0);
9540           
9541           /* The requested adjustment must be inside this range.  This
9542              is a preliminary cap to avoid things like overflow, we
9543              may still fail to compute the result for other reasons.  */
9544           if (-max_exp_adj < req_exp_adj && req_exp_adj < max_exp_adj)
9545             {
9546               REAL_VALUE_TYPE initial_result;
9547               
9548               real_ldexp (&initial_result, &TREE_REAL_CST (arg0), req_exp_adj);
9549
9550               /* Ensure we didn't overflow.  */
9551               if (! real_isinf (&initial_result))
9552                 {
9553                   const REAL_VALUE_TYPE trunc_result
9554                     = real_value_truncate (TYPE_MODE (type), initial_result);
9555                   
9556                   /* Only proceed if the target mode can hold the
9557                      resulting value.  */
9558                   if (REAL_VALUES_EQUAL (initial_result, trunc_result))
9559                     return build_real (type, trunc_result);
9560                 }
9561             }
9562         }
9563     }
9564
9565   return NULL_TREE;
9566 }
9567
9568 /* Fold a call to builtin modf.  */
9569
9570 static tree
9571 fold_builtin_modf (location_t loc, tree arg0, tree arg1, tree rettype)
9572 {
9573   if (! validate_arg (arg0, REAL_TYPE) || ! validate_arg (arg1, POINTER_TYPE))
9574     return NULL_TREE;
9575   
9576   STRIP_NOPS (arg0);
9577       
9578   if (!(TREE_CODE (arg0) == REAL_CST && ! TREE_OVERFLOW (arg0)))
9579     return NULL_TREE;
9580   
9581   arg1 = build_fold_indirect_ref_loc (loc, arg1);
9582
9583   /* Proceed if a valid pointer type was passed in.  */
9584   if (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) == TYPE_MAIN_VARIANT (rettype))
9585     {
9586       const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (arg0);
9587       REAL_VALUE_TYPE trunc, frac;
9588
9589       switch (value->cl)
9590       {
9591       case rvc_nan:
9592       case rvc_zero:
9593         /* For +-NaN or +-0, return (*arg1 = arg0, arg0).  */
9594         trunc = frac = *value;
9595         break;
9596       case rvc_inf:
9597         /* For +-Inf, return (*arg1 = arg0, +-0).  */
9598         frac = dconst0;
9599         frac.sign = value->sign;
9600         trunc = *value;
9601         break;
9602       case rvc_normal:
9603         /* Return (*arg1 = trunc(arg0), arg0-trunc(arg0)).  */
9604         real_trunc (&trunc, VOIDmode, value);
9605         real_arithmetic (&frac, MINUS_EXPR, value, &trunc);
9606         /* If the original number was negative and already
9607            integral, then the fractional part is -0.0.  */
9608         if (value->sign && frac.cl == rvc_zero)
9609           frac.sign = value->sign;
9610         break;
9611       }
9612               
9613       /* Create the COMPOUND_EXPR (*arg1 = trunc, frac). */
9614       arg1 = fold_build2_loc (loc, MODIFY_EXPR, rettype, arg1,
9615                           build_real (rettype, trunc));
9616       TREE_SIDE_EFFECTS (arg1) = 1;
9617       return fold_build2_loc (loc, COMPOUND_EXPR, rettype, arg1,
9618                           build_real (rettype, frac));
9619     }
9620   
9621   return NULL_TREE;
9622 }
9623
9624 /* Given a location LOC, an interclass builtin function decl FNDECL
9625    and its single argument ARG, return an folded expression computing
9626    the same, or NULL_TREE if we either couldn't or didn't want to fold
9627    (the latter happen if there's an RTL instruction available).  */
9628
9629 static tree
9630 fold_builtin_interclass_mathfn (location_t loc, tree fndecl, tree arg)
9631 {
9632   enum machine_mode mode;
9633
9634   if (!validate_arg (arg, REAL_TYPE))
9635     return NULL_TREE;
9636
9637   if (interclass_mathfn_icode (arg, fndecl) != CODE_FOR_nothing)
9638     return NULL_TREE;
9639
9640   mode = TYPE_MODE (TREE_TYPE (arg));
9641
9642   /* If there is no optab, try generic code.  */
9643   switch (DECL_FUNCTION_CODE (fndecl))
9644     {
9645       tree result;
9646
9647     CASE_FLT_FN (BUILT_IN_ISINF):
9648       {
9649         /* isinf(x) -> isgreater(fabs(x),DBL_MAX).  */
9650         tree const isgr_fn = built_in_decls[BUILT_IN_ISGREATER];
9651         tree const type = TREE_TYPE (arg);
9652         REAL_VALUE_TYPE r;
9653         char buf[128];
9654
9655         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9656         real_from_string (&r, buf);
9657         result = build_call_expr (isgr_fn, 2,
9658                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9659                                   build_real (type, r));
9660         return result;
9661       }
9662     CASE_FLT_FN (BUILT_IN_FINITE):
9663     case BUILT_IN_ISFINITE:
9664       {
9665         /* isfinite(x) -> islessequal(fabs(x),DBL_MAX).  */
9666         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9667         tree const type = TREE_TYPE (arg);
9668         REAL_VALUE_TYPE r;
9669         char buf[128];
9670
9671         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9672         real_from_string (&r, buf);
9673         result = build_call_expr (isle_fn, 2,
9674                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9675                                   build_real (type, r));
9676         /*result = fold_build2_loc (loc, UNGT_EXPR,
9677                                   TREE_TYPE (TREE_TYPE (fndecl)),
9678                                   fold_build1_loc (loc, ABS_EXPR, type, arg),
9679                                   build_real (type, r));
9680         result = fold_build1_loc (loc, TRUTH_NOT_EXPR,
9681                                   TREE_TYPE (TREE_TYPE (fndecl)),
9682                                   result);*/
9683         return result;
9684       }
9685     case BUILT_IN_ISNORMAL:
9686       {
9687         /* isnormal(x) -> isgreaterequal(fabs(x),DBL_MIN) &
9688            islessequal(fabs(x),DBL_MAX).  */
9689         tree const isle_fn = built_in_decls[BUILT_IN_ISLESSEQUAL];
9690         tree const isge_fn = built_in_decls[BUILT_IN_ISGREATEREQUAL];
9691         tree const type = TREE_TYPE (arg);
9692         REAL_VALUE_TYPE rmax, rmin;
9693         char buf[128];
9694
9695         get_max_float (REAL_MODE_FORMAT (mode), buf, sizeof (buf));
9696         real_from_string (&rmax, buf);
9697         sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9698         real_from_string (&rmin, buf);
9699         arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9700         result = build_call_expr (isle_fn, 2, arg,
9701                                   build_real (type, rmax));
9702         result = fold_build2 (BIT_AND_EXPR, integer_type_node, result,
9703                               build_call_expr (isge_fn, 2, arg,
9704                                                build_real (type, rmin)));
9705         return result;
9706       }
9707     default:
9708       break;
9709     }
9710
9711   return NULL_TREE;
9712 }
9713
9714 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9715    ARG is the argument for the call.  */
9716
9717 static tree
9718 fold_builtin_classify (location_t loc, tree fndecl, tree arg, int builtin_index)
9719 {
9720   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9721   REAL_VALUE_TYPE r;
9722
9723   if (!validate_arg (arg, REAL_TYPE))
9724     return NULL_TREE;
9725
9726   switch (builtin_index)
9727     {
9728     case BUILT_IN_ISINF:
9729       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9730         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9731
9732       if (TREE_CODE (arg) == REAL_CST)
9733         {
9734           r = TREE_REAL_CST (arg);
9735           if (real_isinf (&r))
9736             return real_compare (GT_EXPR, &r, &dconst0)
9737                    ? integer_one_node : integer_minus_one_node;
9738           else
9739             return integer_zero_node;
9740         }
9741
9742       return NULL_TREE;
9743
9744     case BUILT_IN_ISINF_SIGN:
9745       {
9746         /* isinf_sign(x) -> isinf(x) ? (signbit(x) ? -1 : 1) : 0 */
9747         /* In a boolean context, GCC will fold the inner COND_EXPR to
9748            1.  So e.g. "if (isinf_sign(x))" would be folded to just
9749            "if (isinf(x) ? 1 : 0)" which becomes "if (isinf(x))". */
9750         tree signbit_fn = mathfn_built_in_1 (TREE_TYPE (arg), BUILT_IN_SIGNBIT, 0);
9751         tree isinf_fn = built_in_decls[BUILT_IN_ISINF];
9752         tree tmp = NULL_TREE;
9753
9754         arg = builtin_save_expr (arg);
9755
9756         if (signbit_fn && isinf_fn)
9757           {
9758             tree signbit_call = build_call_expr_loc (loc, signbit_fn, 1, arg);
9759             tree isinf_call = build_call_expr_loc (loc, isinf_fn, 1, arg);
9760
9761             signbit_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
9762                                         signbit_call, integer_zero_node);
9763             isinf_call = fold_build2_loc (loc, NE_EXPR, integer_type_node,
9764                                       isinf_call, integer_zero_node);
9765             
9766             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node, signbit_call,
9767                                integer_minus_one_node, integer_one_node);
9768             tmp = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9769                                isinf_call, tmp,
9770                                integer_zero_node);
9771           }
9772
9773         return tmp;
9774       }
9775
9776     case BUILT_IN_ISFINITE:
9777       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9778           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9779         return omit_one_operand_loc (loc, type, integer_one_node, arg);
9780
9781       if (TREE_CODE (arg) == REAL_CST)
9782         {
9783           r = TREE_REAL_CST (arg);
9784           return real_isfinite (&r) ? integer_one_node : integer_zero_node;
9785         }
9786
9787       return NULL_TREE;
9788
9789     case BUILT_IN_ISNAN:
9790       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9791         return omit_one_operand_loc (loc, type, integer_zero_node, arg);
9792
9793       if (TREE_CODE (arg) == REAL_CST)
9794         {
9795           r = TREE_REAL_CST (arg);
9796           return real_isnan (&r) ? integer_one_node : integer_zero_node;
9797         }
9798
9799       arg = builtin_save_expr (arg);
9800       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg, arg);
9801
9802     default:
9803       gcc_unreachable ();
9804     }
9805 }
9806
9807 /* Fold a call to __builtin_fpclassify(int, int, int, int, int, ...).
9808    This builtin will generate code to return the appropriate floating
9809    point classification depending on the value of the floating point
9810    number passed in.  The possible return values must be supplied as
9811    int arguments to the call in the following order: FP_NAN, FP_INFINITE,
9812    FP_NORMAL, FP_SUBNORMAL and FP_ZERO.  The ellipses is for exactly
9813    one floating point argument which is "type generic".  */
9814
9815 static tree
9816 fold_builtin_fpclassify (location_t loc, tree exp)
9817 {
9818   tree fp_nan, fp_infinite, fp_normal, fp_subnormal, fp_zero,
9819     arg, type, res, tmp;
9820   enum machine_mode mode;
9821   REAL_VALUE_TYPE r;
9822   char buf[128];
9823   
9824   /* Verify the required arguments in the original call.  */
9825   if (!validate_arglist (exp, INTEGER_TYPE, INTEGER_TYPE,
9826                          INTEGER_TYPE, INTEGER_TYPE,
9827                          INTEGER_TYPE, REAL_TYPE, VOID_TYPE))
9828     return NULL_TREE;
9829   
9830   fp_nan = CALL_EXPR_ARG (exp, 0);
9831   fp_infinite = CALL_EXPR_ARG (exp, 1);
9832   fp_normal = CALL_EXPR_ARG (exp, 2);
9833   fp_subnormal = CALL_EXPR_ARG (exp, 3);
9834   fp_zero = CALL_EXPR_ARG (exp, 4);
9835   arg = CALL_EXPR_ARG (exp, 5);
9836   type = TREE_TYPE (arg);
9837   mode = TYPE_MODE (type);
9838   arg = builtin_save_expr (fold_build1_loc (loc, ABS_EXPR, type, arg));
9839
9840   /* fpclassify(x) -> 
9841        isnan(x) ? FP_NAN :
9842          (fabs(x) == Inf ? FP_INFINITE :
9843            (fabs(x) >= DBL_MIN ? FP_NORMAL :
9844              (x == 0 ? FP_ZERO : FP_SUBNORMAL))).  */
9845   
9846   tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
9847                      build_real (type, dconst0));
9848   res = fold_build3_loc (loc, COND_EXPR, integer_type_node,
9849                      tmp, fp_zero, fp_subnormal);
9850
9851   sprintf (buf, "0x1p%d", REAL_MODE_FORMAT (mode)->emin - 1);
9852   real_from_string (&r, buf);
9853   tmp = fold_build2_loc (loc, GE_EXPR, integer_type_node,
9854                      arg, build_real (type, r));
9855   res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, fp_normal, res);
9856   
9857   if (HONOR_INFINITIES (mode))
9858     {
9859       real_inf (&r);
9860       tmp = fold_build2_loc (loc, EQ_EXPR, integer_type_node, arg,
9861                          build_real (type, r));
9862       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp,
9863                          fp_infinite, res);
9864     }
9865
9866   if (HONOR_NANS (mode))
9867     {
9868       tmp = fold_build2_loc (loc, ORDERED_EXPR, integer_type_node, arg, arg);
9869       res = fold_build3_loc (loc, COND_EXPR, integer_type_node, tmp, res, fp_nan);
9870     }
9871   
9872   return res;
9873 }
9874
9875 /* Fold a call to an unordered comparison function such as
9876    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
9877    being called and ARG0 and ARG1 are the arguments for the call.
9878    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9879    the opposite of the desired result.  UNORDERED_CODE is used
9880    for modes that can hold NaNs and ORDERED_CODE is used for
9881    the rest.  */
9882
9883 static tree
9884 fold_builtin_unordered_cmp (location_t loc, tree fndecl, tree arg0, tree arg1,
9885                             enum tree_code unordered_code,
9886                             enum tree_code ordered_code)
9887 {
9888   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9889   enum tree_code code;
9890   tree type0, type1;
9891   enum tree_code code0, code1;
9892   tree cmp_type = NULL_TREE;
9893
9894   type0 = TREE_TYPE (arg0);
9895   type1 = TREE_TYPE (arg1);
9896
9897   code0 = TREE_CODE (type0);
9898   code1 = TREE_CODE (type1);
9899
9900   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9901     /* Choose the wider of two real types.  */
9902     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9903       ? type0 : type1;
9904   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9905     cmp_type = type0;
9906   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9907     cmp_type = type1;
9908
9909   arg0 = fold_convert_loc (loc, cmp_type, arg0);
9910   arg1 = fold_convert_loc (loc, cmp_type, arg1);
9911
9912   if (unordered_code == UNORDERED_EXPR)
9913     {
9914       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9915         return omit_two_operands_loc (loc, type, integer_zero_node, arg0, arg1);
9916       return fold_build2_loc (loc, UNORDERED_EXPR, type, arg0, arg1);
9917     }
9918
9919   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9920                                                    : ordered_code;
9921   return fold_build1_loc (loc, TRUTH_NOT_EXPR, type,
9922                       fold_build2_loc (loc, code, type, arg0, arg1));
9923 }
9924
9925 /* Fold a call to built-in function FNDECL with 0 arguments.
9926    IGNORE is true if the result of the function call is ignored.  This
9927    function returns NULL_TREE if no simplification was possible.  */
9928
9929 static tree
9930 fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
9931 {
9932   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9933   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9934   switch (fcode)
9935     {
9936     CASE_FLT_FN (BUILT_IN_INF):
9937     case BUILT_IN_INFD32:
9938     case BUILT_IN_INFD64:
9939     case BUILT_IN_INFD128:
9940       return fold_builtin_inf (loc, type, true);
9941
9942     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9943       return fold_builtin_inf (loc, type, false);
9944
9945     case BUILT_IN_CLASSIFY_TYPE:
9946       return fold_builtin_classify_type (NULL_TREE);
9947
9948     default:
9949       break;
9950     }
9951   return NULL_TREE;
9952 }
9953
9954 /* Fold a call to built-in function FNDECL with 1 argument, ARG0.
9955    IGNORE is true if the result of the function call is ignored.  This
9956    function returns NULL_TREE if no simplification was possible.  */
9957
9958 static tree
9959 fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
9960 {
9961   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9962   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
9963   switch (fcode)
9964     {
9965
9966     case BUILT_IN_CONSTANT_P:
9967       {
9968         tree val = fold_builtin_constant_p (arg0);
9969
9970         /* Gimplification will pull the CALL_EXPR for the builtin out of
9971            an if condition.  When not optimizing, we'll not CSE it back.
9972            To avoid link error types of regressions, return false now.  */
9973         if (!val && !optimize)
9974           val = integer_zero_node;
9975
9976         return val;
9977       }
9978
9979     case BUILT_IN_CLASSIFY_TYPE:
9980       return fold_builtin_classify_type (arg0);
9981
9982     case BUILT_IN_STRLEN:
9983       return fold_builtin_strlen (loc, arg0);
9984
9985     CASE_FLT_FN (BUILT_IN_FABS):
9986       return fold_builtin_fabs (loc, arg0, type);
9987
9988     case BUILT_IN_ABS:
9989     case BUILT_IN_LABS:
9990     case BUILT_IN_LLABS:
9991     case BUILT_IN_IMAXABS:
9992       return fold_builtin_abs (loc, arg0, type);
9993
9994     CASE_FLT_FN (BUILT_IN_CONJ):
9995       if (validate_arg (arg0, COMPLEX_TYPE)
9996         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
9997         return fold_build1_loc (loc, CONJ_EXPR, type, arg0);
9998     break;
9999
10000     CASE_FLT_FN (BUILT_IN_CREAL):
10001       if (validate_arg (arg0, COMPLEX_TYPE)
10002         && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10003         return non_lvalue_loc (loc, fold_build1_loc (loc, REALPART_EXPR, type, arg0));;
10004     break;
10005
10006     CASE_FLT_FN (BUILT_IN_CIMAG):
10007       if (validate_arg (arg0, COMPLEX_TYPE)
10008           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
10009         return non_lvalue_loc (loc, fold_build1_loc (loc, IMAGPART_EXPR, type, arg0));
10010     break;
10011
10012     CASE_FLT_FN (BUILT_IN_CCOS):
10013       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ false);
10014     
10015     CASE_FLT_FN (BUILT_IN_CCOSH):
10016       return fold_builtin_ccos(loc, arg0, type, fndecl, /*hyper=*/ true);
10017     
10018 #ifdef HAVE_mpc
10019     CASE_FLT_FN (BUILT_IN_CSIN):
10020       if (validate_arg (arg0, COMPLEX_TYPE)
10021           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10022         return do_mpc_arg1 (arg0, type, mpc_sin);
10023     break;
10024     
10025     CASE_FLT_FN (BUILT_IN_CSINH):
10026       if (validate_arg (arg0, COMPLEX_TYPE)
10027           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10028         return do_mpc_arg1 (arg0, type, mpc_sinh);
10029     break;
10030     
10031     CASE_FLT_FN (BUILT_IN_CTAN):
10032       if (validate_arg (arg0, COMPLEX_TYPE)
10033           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10034         return do_mpc_arg1 (arg0, type, mpc_tan);
10035     break;
10036     
10037     CASE_FLT_FN (BUILT_IN_CTANH):
10038       if (validate_arg (arg0, COMPLEX_TYPE)
10039           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10040         return do_mpc_arg1 (arg0, type, mpc_tanh);
10041     break;
10042     
10043     CASE_FLT_FN (BUILT_IN_CLOG):
10044       if (validate_arg (arg0, COMPLEX_TYPE)
10045           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10046         return do_mpc_arg1 (arg0, type, mpc_log);
10047     break;
10048     
10049     CASE_FLT_FN (BUILT_IN_CSQRT):
10050       if (validate_arg (arg0, COMPLEX_TYPE)
10051           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10052         return do_mpc_arg1 (arg0, type, mpc_sqrt);
10053     break;
10054     
10055 #ifdef HAVE_mpc_arc
10056     CASE_FLT_FN (BUILT_IN_CASIN):
10057       if (validate_arg (arg0, COMPLEX_TYPE)
10058           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10059         return do_mpc_arg1 (arg0, type, mpc_asin);
10060     break;
10061     
10062     CASE_FLT_FN (BUILT_IN_CACOS):
10063       if (validate_arg (arg0, COMPLEX_TYPE)
10064           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10065         return do_mpc_arg1 (arg0, type, mpc_acos);
10066     break;
10067     
10068     CASE_FLT_FN (BUILT_IN_CATAN):
10069       if (validate_arg (arg0, COMPLEX_TYPE)
10070           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10071         return do_mpc_arg1 (arg0, type, mpc_atan);
10072     break;
10073     
10074     CASE_FLT_FN (BUILT_IN_CASINH):
10075       if (validate_arg (arg0, COMPLEX_TYPE)
10076           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10077         return do_mpc_arg1 (arg0, type, mpc_asinh);
10078     break;
10079     
10080     CASE_FLT_FN (BUILT_IN_CACOSH):
10081       if (validate_arg (arg0, COMPLEX_TYPE)
10082           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10083         return do_mpc_arg1 (arg0, type, mpc_acosh);
10084     break;
10085     
10086     CASE_FLT_FN (BUILT_IN_CATANH):
10087       if (validate_arg (arg0, COMPLEX_TYPE)
10088           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE) 
10089         return do_mpc_arg1 (arg0, type, mpc_atanh);
10090     break;
10091 #endif /* HAVE_mpc_arc */
10092 #endif /* HAVE_mpc */
10093     
10094     CASE_FLT_FN (BUILT_IN_CABS):
10095       return fold_builtin_cabs (loc, arg0, type, fndecl);
10096
10097     CASE_FLT_FN (BUILT_IN_CARG):
10098       return fold_builtin_carg (loc, arg0, type);
10099
10100     CASE_FLT_FN (BUILT_IN_SQRT):
10101       return fold_builtin_sqrt (loc, arg0, type);
10102
10103     CASE_FLT_FN (BUILT_IN_CBRT):
10104       return fold_builtin_cbrt (loc, arg0, type);
10105
10106     CASE_FLT_FN (BUILT_IN_ASIN):
10107       if (validate_arg (arg0, REAL_TYPE))
10108         return do_mpfr_arg1 (arg0, type, mpfr_asin,
10109                              &dconstm1, &dconst1, true);
10110     break;
10111
10112     CASE_FLT_FN (BUILT_IN_ACOS):
10113       if (validate_arg (arg0, REAL_TYPE))
10114         return do_mpfr_arg1 (arg0, type, mpfr_acos,
10115                              &dconstm1, &dconst1, true);
10116     break;
10117
10118     CASE_FLT_FN (BUILT_IN_ATAN):
10119       if (validate_arg (arg0, REAL_TYPE))
10120         return do_mpfr_arg1 (arg0, type, mpfr_atan, NULL, NULL, 0);
10121     break;
10122
10123     CASE_FLT_FN (BUILT_IN_ASINH):
10124       if (validate_arg (arg0, REAL_TYPE))
10125         return do_mpfr_arg1 (arg0, type, mpfr_asinh, NULL, NULL, 0);
10126     break;
10127
10128     CASE_FLT_FN (BUILT_IN_ACOSH):
10129       if (validate_arg (arg0, REAL_TYPE))
10130         return do_mpfr_arg1 (arg0, type, mpfr_acosh,
10131                              &dconst1, NULL, true);
10132     break;
10133
10134     CASE_FLT_FN (BUILT_IN_ATANH):
10135       if (validate_arg (arg0, REAL_TYPE))
10136         return do_mpfr_arg1 (arg0, type, mpfr_atanh,
10137                              &dconstm1, &dconst1, false);
10138     break;
10139
10140     CASE_FLT_FN (BUILT_IN_SIN):
10141       if (validate_arg (arg0, REAL_TYPE))
10142         return do_mpfr_arg1 (arg0, type, mpfr_sin, NULL, NULL, 0);
10143     break;
10144
10145     CASE_FLT_FN (BUILT_IN_COS):
10146       return fold_builtin_cos (loc, arg0, type, fndecl);
10147
10148     CASE_FLT_FN (BUILT_IN_TAN):
10149       return fold_builtin_tan (arg0, type);
10150
10151     CASE_FLT_FN (BUILT_IN_CEXP):
10152       return fold_builtin_cexp (loc, arg0, type);
10153
10154     CASE_FLT_FN (BUILT_IN_CEXPI):
10155       if (validate_arg (arg0, REAL_TYPE))
10156         return do_mpfr_sincos (arg0, NULL_TREE, NULL_TREE);
10157     break;
10158
10159     CASE_FLT_FN (BUILT_IN_SINH):
10160       if (validate_arg (arg0, REAL_TYPE))
10161         return do_mpfr_arg1 (arg0, type, mpfr_sinh, NULL, NULL, 0);
10162     break;
10163
10164     CASE_FLT_FN (BUILT_IN_COSH):
10165       return fold_builtin_cosh (loc, arg0, type, fndecl);
10166
10167     CASE_FLT_FN (BUILT_IN_TANH):
10168       if (validate_arg (arg0, REAL_TYPE))
10169         return do_mpfr_arg1 (arg0, type, mpfr_tanh, NULL, NULL, 0);
10170     break;
10171
10172     CASE_FLT_FN (BUILT_IN_ERF):
10173       if (validate_arg (arg0, REAL_TYPE))
10174         return do_mpfr_arg1 (arg0, type, mpfr_erf, NULL, NULL, 0);
10175     break;
10176
10177     CASE_FLT_FN (BUILT_IN_ERFC):
10178       if (validate_arg (arg0, REAL_TYPE))
10179         return do_mpfr_arg1 (arg0, type, mpfr_erfc, NULL, NULL, 0);
10180     break;
10181
10182     CASE_FLT_FN (BUILT_IN_TGAMMA):
10183       if (validate_arg (arg0, REAL_TYPE))
10184         return do_mpfr_arg1 (arg0, type, mpfr_gamma, NULL, NULL, 0);
10185     break;
10186  
10187     CASE_FLT_FN (BUILT_IN_EXP):
10188       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp);
10189
10190     CASE_FLT_FN (BUILT_IN_EXP2):
10191       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp2);
10192
10193     CASE_FLT_FN (BUILT_IN_EXP10):
10194     CASE_FLT_FN (BUILT_IN_POW10):
10195       return fold_builtin_exponent (loc, fndecl, arg0, mpfr_exp10);
10196
10197     CASE_FLT_FN (BUILT_IN_EXPM1):
10198       if (validate_arg (arg0, REAL_TYPE))
10199         return do_mpfr_arg1 (arg0, type, mpfr_expm1, NULL, NULL, 0);
10200     break;
10201  
10202     CASE_FLT_FN (BUILT_IN_LOG):
10203     return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log);
10204
10205     CASE_FLT_FN (BUILT_IN_LOG2):
10206       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log2);
10207
10208     CASE_FLT_FN (BUILT_IN_LOG10):
10209       return fold_builtin_logarithm (loc, fndecl, arg0, mpfr_log10);
10210
10211     CASE_FLT_FN (BUILT_IN_LOG1P):
10212       if (validate_arg (arg0, REAL_TYPE))
10213         return do_mpfr_arg1 (arg0, type, mpfr_log1p,
10214                              &dconstm1, NULL, false);
10215     break;
10216
10217     CASE_FLT_FN (BUILT_IN_J0):
10218       if (validate_arg (arg0, REAL_TYPE))
10219         return do_mpfr_arg1 (arg0, type, mpfr_j0,
10220                              NULL, NULL, 0);
10221     break;
10222
10223     CASE_FLT_FN (BUILT_IN_J1):
10224       if (validate_arg (arg0, REAL_TYPE))
10225         return do_mpfr_arg1 (arg0, type, mpfr_j1,
10226                              NULL, NULL, 0);
10227     break;
10228
10229     CASE_FLT_FN (BUILT_IN_Y0):
10230       if (validate_arg (arg0, REAL_TYPE))
10231         return do_mpfr_arg1 (arg0, type, mpfr_y0,
10232                              &dconst0, NULL, false);
10233     break;
10234
10235     CASE_FLT_FN (BUILT_IN_Y1):
10236       if (validate_arg (arg0, REAL_TYPE))
10237         return do_mpfr_arg1 (arg0, type, mpfr_y1,
10238                              &dconst0, NULL, false);
10239     break;
10240
10241     CASE_FLT_FN (BUILT_IN_NAN):
10242     case BUILT_IN_NAND32:
10243     case BUILT_IN_NAND64:
10244     case BUILT_IN_NAND128:
10245       return fold_builtin_nan (arg0, type, true);
10246
10247     CASE_FLT_FN (BUILT_IN_NANS):
10248       return fold_builtin_nan (arg0, type, false);
10249
10250     CASE_FLT_FN (BUILT_IN_FLOOR):
10251       return fold_builtin_floor (loc, fndecl, arg0);
10252
10253     CASE_FLT_FN (BUILT_IN_CEIL):
10254       return fold_builtin_ceil (loc, fndecl, arg0);
10255
10256     CASE_FLT_FN (BUILT_IN_TRUNC):
10257       return fold_builtin_trunc (loc, fndecl, arg0);
10258
10259     CASE_FLT_FN (BUILT_IN_ROUND):
10260       return fold_builtin_round (loc, fndecl, arg0);
10261
10262     CASE_FLT_FN (BUILT_IN_NEARBYINT):
10263     CASE_FLT_FN (BUILT_IN_RINT):
10264       return fold_trunc_transparent_mathfn (loc, fndecl, arg0);
10265
10266     CASE_FLT_FN (BUILT_IN_LCEIL):
10267     CASE_FLT_FN (BUILT_IN_LLCEIL):
10268     CASE_FLT_FN (BUILT_IN_LFLOOR):
10269     CASE_FLT_FN (BUILT_IN_LLFLOOR):
10270     CASE_FLT_FN (BUILT_IN_LROUND):
10271     CASE_FLT_FN (BUILT_IN_LLROUND):
10272       return fold_builtin_int_roundingfn (loc, fndecl, arg0);
10273
10274     CASE_FLT_FN (BUILT_IN_LRINT):
10275     CASE_FLT_FN (BUILT_IN_LLRINT):
10276       return fold_fixed_mathfn (loc, fndecl, arg0);
10277
10278     case BUILT_IN_BSWAP32:
10279     case BUILT_IN_BSWAP64:
10280       return fold_builtin_bswap (fndecl, arg0);
10281
10282     CASE_INT_FN (BUILT_IN_FFS):
10283     CASE_INT_FN (BUILT_IN_CLZ):
10284     CASE_INT_FN (BUILT_IN_CTZ):
10285     CASE_INT_FN (BUILT_IN_POPCOUNT):
10286     CASE_INT_FN (BUILT_IN_PARITY):
10287       return fold_builtin_bitop (fndecl, arg0);
10288
10289     CASE_FLT_FN (BUILT_IN_SIGNBIT):
10290       return fold_builtin_signbit (loc, arg0, type);
10291
10292     CASE_FLT_FN (BUILT_IN_SIGNIFICAND):
10293       return fold_builtin_significand (loc, arg0, type);
10294
10295     CASE_FLT_FN (BUILT_IN_ILOGB):
10296     CASE_FLT_FN (BUILT_IN_LOGB):
10297       return fold_builtin_logb (loc, arg0, type);
10298
10299     case BUILT_IN_ISASCII:
10300       return fold_builtin_isascii (loc, arg0);
10301
10302     case BUILT_IN_TOASCII:
10303       return fold_builtin_toascii (loc, arg0);
10304
10305     case BUILT_IN_ISDIGIT:
10306       return fold_builtin_isdigit (loc, arg0);
10307
10308     CASE_FLT_FN (BUILT_IN_FINITE):
10309     case BUILT_IN_FINITED32:
10310     case BUILT_IN_FINITED64:
10311     case BUILT_IN_FINITED128:
10312     case BUILT_IN_ISFINITE:
10313       {
10314         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISFINITE);
10315         if (ret)
10316           return ret;
10317         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10318       }
10319
10320     CASE_FLT_FN (BUILT_IN_ISINF):
10321     case BUILT_IN_ISINFD32:
10322     case BUILT_IN_ISINFD64:
10323     case BUILT_IN_ISINFD128:
10324       {
10325         tree ret = fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF);
10326         if (ret)
10327           return ret;
10328         return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10329       }
10330
10331     case BUILT_IN_ISNORMAL:
10332       return fold_builtin_interclass_mathfn (loc, fndecl, arg0);
10333
10334     case BUILT_IN_ISINF_SIGN:
10335       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISINF_SIGN);
10336
10337     CASE_FLT_FN (BUILT_IN_ISNAN):
10338     case BUILT_IN_ISNAND32:
10339     case BUILT_IN_ISNAND64:
10340     case BUILT_IN_ISNAND128:
10341       return fold_builtin_classify (loc, fndecl, arg0, BUILT_IN_ISNAN);
10342
10343     case BUILT_IN_PRINTF:
10344     case BUILT_IN_PRINTF_UNLOCKED:
10345     case BUILT_IN_VPRINTF:
10346       return fold_builtin_printf (loc, fndecl, arg0, NULL_TREE, ignore, fcode);
10347
10348     default:
10349       break;
10350     }
10351
10352   return NULL_TREE;
10353
10354 }
10355
10356 /* Fold a call to built-in function FNDECL with 2 arguments, ARG0 and ARG1.
10357    IGNORE is true if the result of the function call is ignored.  This
10358    function returns NULL_TREE if no simplification was possible.  */
10359
10360 static tree
10361 fold_builtin_2 (location_t loc, tree fndecl, tree arg0, tree arg1, bool ignore)
10362 {
10363   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10364   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10365
10366   switch (fcode)
10367     {
10368     CASE_FLT_FN (BUILT_IN_JN):
10369       if (validate_arg (arg0, INTEGER_TYPE)
10370           && validate_arg (arg1, REAL_TYPE))
10371         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_jn, NULL, 0);
10372     break;
10373
10374     CASE_FLT_FN (BUILT_IN_YN):
10375       if (validate_arg (arg0, INTEGER_TYPE)
10376           && validate_arg (arg1, REAL_TYPE))
10377         return do_mpfr_bessel_n (arg0, arg1, type, mpfr_yn,
10378                                  &dconst0, false);
10379     break;
10380
10381     CASE_FLT_FN (BUILT_IN_DREM):
10382     CASE_FLT_FN (BUILT_IN_REMAINDER):
10383       if (validate_arg (arg0, REAL_TYPE)
10384           && validate_arg(arg1, REAL_TYPE))
10385         return do_mpfr_arg2 (arg0, arg1, type, mpfr_remainder);
10386     break;
10387
10388     CASE_FLT_FN_REENT (BUILT_IN_GAMMA): /* GAMMA_R */
10389     CASE_FLT_FN_REENT (BUILT_IN_LGAMMA): /* LGAMMA_R */
10390       if (validate_arg (arg0, REAL_TYPE)
10391           && validate_arg(arg1, POINTER_TYPE))
10392         return do_mpfr_lgamma_r (arg0, arg1, type);
10393     break;
10394
10395     CASE_FLT_FN (BUILT_IN_ATAN2):
10396       if (validate_arg (arg0, REAL_TYPE)
10397           && validate_arg(arg1, REAL_TYPE))
10398         return do_mpfr_arg2 (arg0, arg1, type, mpfr_atan2);
10399     break;
10400
10401     CASE_FLT_FN (BUILT_IN_FDIM):
10402       if (validate_arg (arg0, REAL_TYPE)
10403           && validate_arg(arg1, REAL_TYPE))
10404         return do_mpfr_arg2 (arg0, arg1, type, mpfr_dim);
10405     break;
10406
10407     CASE_FLT_FN (BUILT_IN_HYPOT):
10408       return fold_builtin_hypot (loc, fndecl, arg0, arg1, type);
10409
10410 #ifdef HAVE_mpc_pow
10411     CASE_FLT_FN (BUILT_IN_CPOW):
10412       if (validate_arg (arg0, COMPLEX_TYPE)
10413           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
10414           && validate_arg (arg1, COMPLEX_TYPE)
10415           && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE) 
10416         return do_mpc_arg2 (arg0, arg1, type, /*do_nonfinite=*/ 0, mpc_pow);
10417     break;
10418 #endif
10419
10420     CASE_FLT_FN (BUILT_IN_LDEXP):
10421       return fold_builtin_load_exponent (loc, arg0, arg1, type, /*ldexp=*/true);
10422     CASE_FLT_FN (BUILT_IN_SCALBN):
10423     CASE_FLT_FN (BUILT_IN_SCALBLN):
10424       return fold_builtin_load_exponent (loc, arg0, arg1,
10425                                          type, /*ldexp=*/false);
10426
10427     CASE_FLT_FN (BUILT_IN_FREXP):
10428       return fold_builtin_frexp (loc, arg0, arg1, type);
10429
10430     CASE_FLT_FN (BUILT_IN_MODF):
10431       return fold_builtin_modf (loc, arg0, arg1, type);
10432
10433     case BUILT_IN_BZERO:
10434       return fold_builtin_bzero (loc, arg0, arg1, ignore);
10435
10436     case BUILT_IN_FPUTS:
10437       return fold_builtin_fputs (loc, arg0, arg1, ignore, false, NULL_TREE);
10438
10439     case BUILT_IN_FPUTS_UNLOCKED:
10440       return fold_builtin_fputs (loc, arg0, arg1, ignore, true, NULL_TREE);
10441
10442     case BUILT_IN_STRSTR:
10443       return fold_builtin_strstr (loc, arg0, arg1, type);
10444
10445     case BUILT_IN_STRCAT:
10446       return fold_builtin_strcat (loc, arg0, arg1);
10447
10448     case BUILT_IN_STRSPN:
10449       return fold_builtin_strspn (loc, arg0, arg1);
10450
10451     case BUILT_IN_STRCSPN:
10452       return fold_builtin_strcspn (loc, arg0, arg1);
10453
10454     case BUILT_IN_STRCHR:
10455     case BUILT_IN_INDEX:
10456       return fold_builtin_strchr (loc, arg0, arg1, type);
10457
10458     case BUILT_IN_STRRCHR:
10459     case BUILT_IN_RINDEX:
10460       return fold_builtin_strrchr (loc, arg0, arg1, type);
10461
10462     case BUILT_IN_STRCPY:
10463       return fold_builtin_strcpy (loc, fndecl, arg0, arg1, NULL_TREE);
10464
10465     case BUILT_IN_STPCPY:
10466       if (ignore)
10467         {
10468           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10469           if (!fn)
10470             break;
10471
10472           return build_call_expr_loc (loc, fn, 2, arg0, arg1);
10473         }
10474       else
10475         return fold_builtin_stpcpy (loc, fndecl, arg0, arg1);
10476       break;
10477
10478     case BUILT_IN_STRCMP:
10479       return fold_builtin_strcmp (loc, arg0, arg1);
10480
10481     case BUILT_IN_STRPBRK:
10482       return fold_builtin_strpbrk (loc, arg0, arg1, type);
10483
10484     case BUILT_IN_EXPECT:
10485       return fold_builtin_expect (loc, arg0, arg1);
10486
10487     CASE_FLT_FN (BUILT_IN_POW):
10488       return fold_builtin_pow (loc, fndecl, arg0, arg1, type);
10489
10490     CASE_FLT_FN (BUILT_IN_POWI):
10491       return fold_builtin_powi (loc, fndecl, arg0, arg1, type);
10492
10493     CASE_FLT_FN (BUILT_IN_COPYSIGN):
10494       return fold_builtin_copysign (loc, fndecl, arg0, arg1, type);
10495
10496     CASE_FLT_FN (BUILT_IN_FMIN):
10497       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/false);
10498
10499     CASE_FLT_FN (BUILT_IN_FMAX):
10500       return fold_builtin_fmin_fmax (loc, arg0, arg1, type, /*max=*/true);
10501
10502     case BUILT_IN_ISGREATER:
10503       return fold_builtin_unordered_cmp (loc, fndecl,
10504                                          arg0, arg1, UNLE_EXPR, LE_EXPR);
10505     case BUILT_IN_ISGREATEREQUAL:
10506       return fold_builtin_unordered_cmp (loc, fndecl,
10507                                          arg0, arg1, UNLT_EXPR, LT_EXPR);
10508     case BUILT_IN_ISLESS:
10509       return fold_builtin_unordered_cmp (loc, fndecl,
10510                                          arg0, arg1, UNGE_EXPR, GE_EXPR);
10511     case BUILT_IN_ISLESSEQUAL:
10512       return fold_builtin_unordered_cmp (loc, fndecl,
10513                                          arg0, arg1, UNGT_EXPR, GT_EXPR);
10514     case BUILT_IN_ISLESSGREATER:
10515       return fold_builtin_unordered_cmp (loc, fndecl,
10516                                          arg0, arg1, UNEQ_EXPR, EQ_EXPR);
10517     case BUILT_IN_ISUNORDERED:
10518       return fold_builtin_unordered_cmp (loc, fndecl,
10519                                          arg0, arg1, UNORDERED_EXPR,
10520                                          NOP_EXPR);
10521
10522       /* We do the folding for va_start in the expander.  */
10523     case BUILT_IN_VA_START:
10524       break;
10525
10526     case BUILT_IN_SPRINTF:
10527       return fold_builtin_sprintf (loc, arg0, arg1, NULL_TREE, ignore);
10528
10529     case BUILT_IN_OBJECT_SIZE:
10530       return fold_builtin_object_size (arg0, arg1);
10531
10532     case BUILT_IN_PRINTF:
10533     case BUILT_IN_PRINTF_UNLOCKED:
10534     case BUILT_IN_VPRINTF:
10535       return fold_builtin_printf (loc, fndecl, arg0, arg1, ignore, fcode);
10536
10537     case BUILT_IN_PRINTF_CHK:
10538     case BUILT_IN_VPRINTF_CHK:
10539       if (!validate_arg (arg0, INTEGER_TYPE)
10540           || TREE_SIDE_EFFECTS (arg0))
10541         return NULL_TREE;
10542       else
10543         return fold_builtin_printf (loc, fndecl,
10544                                     arg1, NULL_TREE, ignore, fcode);
10545     break;
10546
10547     case BUILT_IN_FPRINTF:
10548     case BUILT_IN_FPRINTF_UNLOCKED:
10549     case BUILT_IN_VFPRINTF:
10550       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, NULL_TREE,
10551                                    ignore, fcode);
10552
10553     default:
10554       break;
10555     }
10556   return NULL_TREE;
10557 }
10558
10559 /* Fold a call to built-in function FNDECL with 3 arguments, ARG0, ARG1,
10560    and ARG2.  IGNORE is true if the result of the function call is ignored.
10561    This function returns NULL_TREE if no simplification was possible.  */
10562
10563 static tree
10564 fold_builtin_3 (location_t loc, tree fndecl,
10565                 tree arg0, tree arg1, tree arg2, bool ignore)
10566 {
10567   tree type = TREE_TYPE (TREE_TYPE (fndecl));
10568   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10569   switch (fcode)
10570     {
10571
10572     CASE_FLT_FN (BUILT_IN_SINCOS):
10573       return fold_builtin_sincos (loc, arg0, arg1, arg2);
10574
10575     CASE_FLT_FN (BUILT_IN_FMA):
10576       if (validate_arg (arg0, REAL_TYPE)
10577           && validate_arg(arg1, REAL_TYPE)
10578           && validate_arg(arg2, REAL_TYPE))
10579         return do_mpfr_arg3 (arg0, arg1, arg2, type, mpfr_fma);
10580     break;
10581
10582     CASE_FLT_FN (BUILT_IN_REMQUO):
10583       if (validate_arg (arg0, REAL_TYPE)
10584           && validate_arg(arg1, REAL_TYPE)
10585           && validate_arg(arg2, POINTER_TYPE))
10586         return do_mpfr_remquo (arg0, arg1, arg2);
10587     break;
10588
10589     case BUILT_IN_MEMSET:
10590       return fold_builtin_memset (loc, arg0, arg1, arg2, type, ignore);
10591
10592     case BUILT_IN_BCOPY:
10593       return fold_builtin_memory_op (loc, arg1, arg0, arg2,
10594                                      void_type_node, true, /*endp=*/3);
10595
10596     case BUILT_IN_MEMCPY:
10597       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10598                                      type, ignore, /*endp=*/0);
10599
10600     case BUILT_IN_MEMPCPY:
10601       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10602                                      type, ignore, /*endp=*/1);
10603
10604     case BUILT_IN_MEMMOVE:
10605       return fold_builtin_memory_op (loc, arg0, arg1, arg2,
10606                                      type, ignore, /*endp=*/3);
10607
10608     case BUILT_IN_STRNCAT:
10609       return fold_builtin_strncat (loc, arg0, arg1, arg2);
10610
10611     case BUILT_IN_STRNCPY:
10612       return fold_builtin_strncpy (loc, fndecl, arg0, arg1, arg2, NULL_TREE);
10613
10614     case BUILT_IN_STRNCMP:
10615       return fold_builtin_strncmp (loc, arg0, arg1, arg2);
10616
10617     case BUILT_IN_MEMCHR:
10618       return fold_builtin_memchr (loc, arg0, arg1, arg2, type);
10619
10620     case BUILT_IN_BCMP:
10621     case BUILT_IN_MEMCMP:
10622       return fold_builtin_memcmp (loc, arg0, arg1, arg2);;
10623
10624     case BUILT_IN_SPRINTF:
10625       return fold_builtin_sprintf (loc, arg0, arg1, arg2, ignore);
10626
10627     case BUILT_IN_STRCPY_CHK:
10628     case BUILT_IN_STPCPY_CHK:
10629       return fold_builtin_stxcpy_chk (loc, fndecl, arg0, arg1, arg2, NULL_TREE,
10630                                       ignore, fcode);
10631
10632     case BUILT_IN_STRCAT_CHK:
10633       return fold_builtin_strcat_chk (loc, fndecl, arg0, arg1, arg2);
10634
10635     case BUILT_IN_PRINTF_CHK:
10636     case BUILT_IN_VPRINTF_CHK:
10637       if (!validate_arg (arg0, INTEGER_TYPE)
10638           || TREE_SIDE_EFFECTS (arg0))
10639         return NULL_TREE;
10640       else
10641         return fold_builtin_printf (loc, fndecl, arg1, arg2, ignore, fcode);
10642     break;
10643
10644     case BUILT_IN_FPRINTF:
10645     case BUILT_IN_FPRINTF_UNLOCKED:
10646     case BUILT_IN_VFPRINTF:
10647       return fold_builtin_fprintf (loc, fndecl, arg0, arg1, arg2,
10648                                    ignore, fcode);
10649
10650     case BUILT_IN_FPRINTF_CHK:
10651     case BUILT_IN_VFPRINTF_CHK:
10652       if (!validate_arg (arg1, INTEGER_TYPE)
10653           || TREE_SIDE_EFFECTS (arg1))
10654         return NULL_TREE;
10655       else
10656         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, NULL_TREE,
10657                                      ignore, fcode);
10658
10659     default:
10660       break;
10661     }
10662   return NULL_TREE;
10663 }
10664
10665 /* Fold a call to built-in function FNDECL with 4 arguments, ARG0, ARG1,
10666    ARG2, and ARG3.  IGNORE is true if the result of the function call is
10667    ignored.  This function returns NULL_TREE if no simplification was
10668    possible.  */
10669  
10670 static tree
10671 fold_builtin_4 (location_t loc, tree fndecl,
10672                 tree arg0, tree arg1, tree arg2, tree arg3, bool ignore)
10673 {
10674   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10675
10676   switch (fcode)
10677     {
10678     case BUILT_IN_MEMCPY_CHK:
10679     case BUILT_IN_MEMPCPY_CHK:
10680     case BUILT_IN_MEMMOVE_CHK:
10681     case BUILT_IN_MEMSET_CHK:
10682       return fold_builtin_memory_chk (loc, fndecl, arg0, arg1, arg2, arg3,
10683                                       NULL_TREE, ignore,
10684                                       DECL_FUNCTION_CODE (fndecl));
10685
10686     case BUILT_IN_STRNCPY_CHK:
10687       return fold_builtin_strncpy_chk (loc, arg0, arg1, arg2, arg3, NULL_TREE);
10688
10689     case BUILT_IN_STRNCAT_CHK:
10690       return fold_builtin_strncat_chk (loc, fndecl, arg0, arg1, arg2, arg3);
10691
10692     case BUILT_IN_FPRINTF_CHK:
10693     case BUILT_IN_VFPRINTF_CHK:
10694       if (!validate_arg (arg1, INTEGER_TYPE)
10695           || TREE_SIDE_EFFECTS (arg1))
10696         return NULL_TREE;
10697       else
10698         return fold_builtin_fprintf (loc, fndecl, arg0, arg2, arg3,
10699                                      ignore, fcode);
10700     break;
10701
10702     default:
10703       break;
10704     }
10705   return NULL_TREE;
10706 }
10707
10708 /* Fold a call to built-in function FNDECL.  ARGS is an array of NARGS
10709     arguments, where NARGS <= 4.  IGNORE is true if the result of the
10710     function call is ignored.  This function returns NULL_TREE if no
10711     simplification was possible.  Note that this only folds builtins with
10712     fixed argument patterns.  Foldings that do varargs-to-varargs
10713     transformations, or that match calls with more than 4 arguments,
10714     need to be handled with fold_builtin_varargs instead.  */
10715  
10716 #define MAX_ARGS_TO_FOLD_BUILTIN 4
10717  
10718 static tree
10719 fold_builtin_n (location_t loc, tree fndecl, tree *args, int nargs, bool ignore)
10720 {
10721   tree ret = NULL_TREE;
10722
10723   switch (nargs)
10724     {
10725     case 0:
10726       ret = fold_builtin_0 (loc, fndecl, ignore);
10727       break;
10728     case 1:
10729       ret = fold_builtin_1 (loc, fndecl, args[0], ignore);
10730       break;
10731     case 2:
10732       ret = fold_builtin_2 (loc, fndecl, args[0], args[1], ignore);
10733       break;
10734     case 3:
10735       ret = fold_builtin_3 (loc, fndecl, args[0], args[1], args[2], ignore);
10736       break;
10737     case 4:
10738       ret = fold_builtin_4 (loc, fndecl, args[0], args[1], args[2], args[3],
10739                             ignore);
10740       break;
10741     default:
10742       break;
10743     }
10744   if (ret)
10745     {
10746       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10747       SET_EXPR_LOCATION (ret, loc);
10748       TREE_NO_WARNING (ret) = 1;
10749       return ret;
10750     }
10751   return NULL_TREE;
10752 }
10753
10754 /* Builtins with folding operations that operate on "..." arguments
10755    need special handling; we need to store the arguments in a convenient
10756    data structure before attempting any folding.  Fortunately there are
10757    only a few builtins that fall into this category.  FNDECL is the
10758    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
10759    result of the function call is ignored.  */
10760
10761 static tree
10762 fold_builtin_varargs (location_t loc, tree fndecl, tree exp,
10763                       bool ignore ATTRIBUTE_UNUSED)
10764 {
10765   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
10766   tree ret = NULL_TREE;
10767
10768   switch (fcode)
10769     {
10770     case BUILT_IN_SPRINTF_CHK:
10771     case BUILT_IN_VSPRINTF_CHK:
10772       ret = fold_builtin_sprintf_chk (loc, exp, fcode);
10773       break;
10774
10775     case BUILT_IN_SNPRINTF_CHK:
10776     case BUILT_IN_VSNPRINTF_CHK:
10777       ret = fold_builtin_snprintf_chk (loc, exp, NULL_TREE, fcode);
10778       break;
10779
10780     case BUILT_IN_FPCLASSIFY:
10781       ret = fold_builtin_fpclassify (loc, exp);
10782       break;
10783
10784     default:
10785       break;
10786     }
10787   if (ret)
10788     {
10789       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
10790       SET_EXPR_LOCATION (ret, loc);
10791       TREE_NO_WARNING (ret) = 1;
10792       return ret;
10793     }
10794   return NULL_TREE;
10795 }
10796
10797 /* Return true if FNDECL shouldn't be folded right now.
10798    If a built-in function has an inline attribute always_inline
10799    wrapper, defer folding it after always_inline functions have
10800    been inlined, otherwise e.g. -D_FORTIFY_SOURCE checking
10801    might not be performed.  */
10802
10803 static bool
10804 avoid_folding_inline_builtin (tree fndecl)
10805 {
10806   return (DECL_DECLARED_INLINE_P (fndecl)
10807           && DECL_DISREGARD_INLINE_LIMITS (fndecl)
10808           && cfun
10809           && !cfun->always_inline_functions_inlined
10810           && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fndecl)));
10811 }
10812
10813 /* A wrapper function for builtin folding that prevents warnings for
10814    "statement without effect" and the like, caused by removing the
10815    call node earlier than the warning is generated.  */
10816
10817 tree
10818 fold_call_expr (location_t loc, tree exp, bool ignore)
10819 {
10820   tree ret = NULL_TREE;
10821   tree fndecl = get_callee_fndecl (exp);
10822   if (fndecl
10823       && TREE_CODE (fndecl) == FUNCTION_DECL
10824       && DECL_BUILT_IN (fndecl)
10825       /* If CALL_EXPR_VA_ARG_PACK is set, the arguments aren't finalized
10826          yet.  Defer folding until we see all the arguments
10827          (after inlining).  */
10828       && !CALL_EXPR_VA_ARG_PACK (exp))
10829     {
10830       int nargs = call_expr_nargs (exp);
10831
10832       /* Before gimplification CALL_EXPR_VA_ARG_PACK is not set, but
10833          instead last argument is __builtin_va_arg_pack ().  Defer folding
10834          even in that case, until arguments are finalized.  */
10835       if (nargs && TREE_CODE (CALL_EXPR_ARG (exp, nargs - 1)) == CALL_EXPR)
10836         {
10837           tree fndecl2 = get_callee_fndecl (CALL_EXPR_ARG (exp, nargs - 1));
10838           if (fndecl2
10839               && TREE_CODE (fndecl2) == FUNCTION_DECL
10840               && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10841               && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10842             return NULL_TREE;
10843         }
10844
10845       if (avoid_folding_inline_builtin (fndecl))
10846         return NULL_TREE;
10847
10848       /* FIXME: Don't use a list in this interface.  */
10849       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10850           return targetm.fold_builtin (fndecl, CALL_EXPR_ARGS (exp), ignore);
10851       else
10852         {
10853           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
10854             {
10855               tree *args = CALL_EXPR_ARGP (exp);
10856               ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
10857             }
10858           if (!ret)
10859             ret = fold_builtin_varargs (loc, fndecl, exp, ignore);
10860           if (ret)
10861             return ret;
10862         }
10863     }
10864   return NULL_TREE;
10865 }
10866  
10867 /* Conveniently construct a function call expression.  FNDECL names the
10868     function to be called and ARGLIST is a TREE_LIST of arguments.  */
10869  
10870 tree
10871 build_function_call_expr (location_t loc, tree fndecl, tree arglist)
10872 {
10873   tree fntype = TREE_TYPE (fndecl);
10874   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10875   int n = list_length (arglist);
10876   tree *argarray = (tree *) alloca (n * sizeof (tree));
10877   int i;
10878
10879   for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
10880     argarray[i] = TREE_VALUE (arglist);
10881   return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
10882 }
10883
10884 /* Conveniently construct a function call expression.  FNDECL names the
10885    function to be called, N is the number of arguments, and the "..."
10886    parameters are the argument expressions.  */
10887  
10888 tree
10889 build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
10890 {
10891   va_list ap;
10892   tree fntype = TREE_TYPE (fndecl);
10893   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10894   tree *argarray = (tree *) alloca (n * sizeof (tree));
10895   int i;
10896
10897   va_start (ap, n);
10898   for (i = 0; i < n; i++)
10899     argarray[i] = va_arg (ap, tree);
10900   va_end (ap);
10901   return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
10902 }
10903
10904 /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
10905    N arguments are passed in the array ARGARRAY.  */
10906
10907 tree
10908 fold_builtin_call_array (location_t loc, tree type,
10909                          tree fn,
10910                          int n,
10911                          tree *argarray)
10912 {
10913   tree ret = NULL_TREE;
10914   int i;
10915    tree exp;
10916
10917   if (TREE_CODE (fn) == ADDR_EXPR)
10918   {
10919     tree fndecl = TREE_OPERAND (fn, 0);
10920     if (TREE_CODE (fndecl) == FUNCTION_DECL
10921         && DECL_BUILT_IN (fndecl))
10922       {
10923         /* If last argument is __builtin_va_arg_pack (), arguments to this
10924            function are not finalized yet.  Defer folding until they are.  */
10925         if (n && TREE_CODE (argarray[n - 1]) == CALL_EXPR)
10926           {
10927             tree fndecl2 = get_callee_fndecl (argarray[n - 1]);
10928             if (fndecl2
10929                 && TREE_CODE (fndecl2) == FUNCTION_DECL
10930                 && DECL_BUILT_IN_CLASS (fndecl2) == BUILT_IN_NORMAL
10931                 && DECL_FUNCTION_CODE (fndecl2) == BUILT_IN_VA_ARG_PACK)
10932               return build_call_array_loc (loc, type, fn, n, argarray);
10933           }
10934         if (avoid_folding_inline_builtin (fndecl))
10935           return build_call_array_loc (loc, type, fn, n, argarray);
10936         if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
10937           {
10938             tree arglist = NULL_TREE;
10939             for (i = n - 1; i >= 0; i--)
10940               arglist = tree_cons (NULL_TREE, argarray[i], arglist);
10941             ret = targetm.fold_builtin (fndecl, arglist, false);
10942             if (ret)
10943               return ret;
10944             return build_call_array_loc (loc, type, fn, n, argarray);
10945           }
10946         else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
10947           {
10948             /* First try the transformations that don't require consing up
10949                an exp.  */
10950             ret = fold_builtin_n (loc, fndecl, argarray, n, false);
10951             if (ret)
10952               return ret;
10953           }
10954
10955         /* If we got this far, we need to build an exp.  */
10956         exp = build_call_array_loc (loc, type, fn, n, argarray);
10957         ret = fold_builtin_varargs (loc, fndecl, exp, false);
10958         return ret ? ret : exp;
10959       }
10960   }
10961
10962   return build_call_array_loc (loc, type, fn, n, argarray);
10963 }
10964
10965 /* Construct a new CALL_EXPR using the tail of the argument list of EXP
10966    along with N new arguments specified as the "..." parameters.  SKIP
10967    is the number of arguments in EXP to be omitted.  This function is used
10968    to do varargs-to-varargs transformations.  */
10969
10970 static tree
10971 rewrite_call_expr (location_t loc, tree exp, int skip, tree fndecl, int n, ...)
10972 {
10973   int oldnargs = call_expr_nargs (exp);
10974   int nargs = oldnargs - skip + n;
10975   tree fntype = TREE_TYPE (fndecl);
10976   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
10977   tree *buffer;
10978
10979   if (n > 0)
10980     {
10981       int i, j;
10982       va_list ap;
10983
10984       buffer = XALLOCAVEC (tree, nargs);
10985       va_start (ap, n);
10986       for (i = 0; i < n; i++)
10987         buffer[i] = va_arg (ap, tree);
10988       va_end (ap);
10989       for (j = skip; j < oldnargs; j++, i++)
10990         buffer[i] = CALL_EXPR_ARG (exp, j);
10991     }
10992   else 
10993     buffer = CALL_EXPR_ARGP (exp) + skip;
10994
10995   return fold (build_call_array_loc (loc, TREE_TYPE (exp), fn, nargs, buffer));
10996 }
10997
10998 /* Validate a single argument ARG against a tree code CODE representing
10999    a type.  */
11000   
11001 static bool
11002 validate_arg (const_tree arg, enum tree_code code)
11003 {
11004   if (!arg)
11005     return false;
11006   else if (code == POINTER_TYPE)
11007     return POINTER_TYPE_P (TREE_TYPE (arg));
11008   else if (code == INTEGER_TYPE)
11009     return INTEGRAL_TYPE_P (TREE_TYPE (arg));
11010   return code == TREE_CODE (TREE_TYPE (arg));
11011 }
11012
11013 /* This function validates the types of a function call argument list
11014    against a specified list of tree_codes.  If the last specifier is a 0,
11015    that represents an ellipses, otherwise the last specifier must be a
11016    VOID_TYPE.
11017
11018    This is the GIMPLE version of validate_arglist.  Eventually we want to
11019    completely convert builtins.c to work from GIMPLEs and the tree based
11020    validate_arglist will then be removed.  */
11021
11022 bool
11023 validate_gimple_arglist (const_gimple call, ...)
11024 {
11025   enum tree_code code;
11026   bool res = 0;
11027   va_list ap;
11028   const_tree arg;
11029   size_t i;
11030
11031   va_start (ap, call);
11032   i = 0;
11033
11034   do
11035     {
11036       code = (enum tree_code) va_arg (ap, int);
11037       switch (code)
11038         {
11039         case 0:
11040           /* This signifies an ellipses, any further arguments are all ok.  */
11041           res = true;
11042           goto end;
11043         case VOID_TYPE:
11044           /* This signifies an endlink, if no arguments remain, return
11045              true, otherwise return false.  */
11046           res = (i == gimple_call_num_args (call));
11047           goto end;
11048         default:
11049           /* If no parameters remain or the parameter's code does not
11050              match the specified code, return false.  Otherwise continue
11051              checking any remaining arguments.  */
11052           arg = gimple_call_arg (call, i++);
11053           if (!validate_arg (arg, code))
11054             goto end;
11055           break;
11056         }
11057     }
11058   while (1);
11059
11060   /* We need gotos here since we can only have one VA_CLOSE in a
11061      function.  */
11062  end: ;
11063   va_end (ap);
11064
11065   return res;
11066 }
11067
11068 /* This function validates the types of a function call argument list
11069    against a specified list of tree_codes.  If the last specifier is a 0,
11070    that represents an ellipses, otherwise the last specifier must be a
11071    VOID_TYPE.  */
11072
11073 bool
11074 validate_arglist (const_tree callexpr, ...)
11075 {
11076   enum tree_code code;
11077   bool res = 0;
11078   va_list ap;
11079   const_call_expr_arg_iterator iter;
11080   const_tree arg;
11081
11082   va_start (ap, callexpr);
11083   init_const_call_expr_arg_iterator (callexpr, &iter);
11084
11085   do
11086     {
11087       code = (enum tree_code) va_arg (ap, int);
11088       switch (code)
11089         {
11090         case 0:
11091           /* This signifies an ellipses, any further arguments are all ok.  */
11092           res = true;
11093           goto end;
11094         case VOID_TYPE:
11095           /* This signifies an endlink, if no arguments remain, return
11096              true, otherwise return false.  */
11097           res = !more_const_call_expr_args_p (&iter);
11098           goto end;
11099         default:
11100           /* If no parameters remain or the parameter's code does not
11101              match the specified code, return false.  Otherwise continue
11102              checking any remaining arguments.  */
11103           arg = next_const_call_expr_arg (&iter);
11104           if (!validate_arg (arg, code))
11105             goto end;
11106           break;
11107         }
11108     }
11109   while (1);
11110
11111   /* We need gotos here since we can only have one VA_CLOSE in a
11112      function.  */
11113  end: ;
11114   va_end (ap);
11115
11116   return res;
11117 }
11118
11119 /* Default target-specific builtin expander that does nothing.  */
11120
11121 rtx
11122 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
11123                         rtx target ATTRIBUTE_UNUSED,
11124                         rtx subtarget ATTRIBUTE_UNUSED,
11125                         enum machine_mode mode ATTRIBUTE_UNUSED,
11126                         int ignore ATTRIBUTE_UNUSED)
11127 {
11128   return NULL_RTX;
11129 }
11130
11131 /* Returns true is EXP represents data that would potentially reside
11132    in a readonly section.  */
11133
11134 static bool
11135 readonly_data_expr (tree exp)
11136 {
11137   STRIP_NOPS (exp);
11138
11139   if (TREE_CODE (exp) != ADDR_EXPR)
11140     return false;
11141
11142   exp = get_base_address (TREE_OPERAND (exp, 0));
11143   if (!exp)
11144     return false;
11145
11146   /* Make sure we call decl_readonly_section only for trees it
11147      can handle (since it returns true for everything it doesn't
11148      understand).  */
11149   if (TREE_CODE (exp) == STRING_CST
11150       || TREE_CODE (exp) == CONSTRUCTOR
11151       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
11152     return decl_readonly_section (exp, 0);
11153   else
11154     return false;
11155 }
11156
11157 /* Simplify a call to the strstr builtin.  S1 and S2 are the arguments
11158    to the call, and TYPE is its return type.
11159
11160    Return NULL_TREE if no simplification was possible, otherwise return the
11161    simplified form of the call as a tree.
11162
11163    The simplified form may be a constant or other expression which
11164    computes the same value, but in a more efficient manner (including
11165    calls to other builtin functions).
11166
11167    The call may contain arguments which need to be evaluated, but
11168    which are not useful to determine the result of the call.  In
11169    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11170    COMPOUND_EXPR will be an argument which must be evaluated.
11171    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11172    COMPOUND_EXPR in the chain will contain the tree for the simplified
11173    form of the builtin function call.  */
11174
11175 static tree
11176 fold_builtin_strstr (location_t loc, tree s1, tree s2, tree type)
11177 {
11178   if (!validate_arg (s1, POINTER_TYPE)
11179       || !validate_arg (s2, POINTER_TYPE))
11180     return NULL_TREE;
11181   else
11182     {
11183       tree fn;
11184       const char *p1, *p2;
11185
11186       p2 = c_getstr (s2);
11187       if (p2 == NULL)
11188         return NULL_TREE;
11189
11190       p1 = c_getstr (s1);
11191       if (p1 != NULL)
11192         {
11193           const char *r = strstr (p1, p2);
11194           tree tem;
11195
11196           if (r == NULL)
11197             return build_int_cst (TREE_TYPE (s1), 0);
11198
11199           /* Return an offset into the constant string argument.  */
11200           tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
11201                              s1, size_int (r - p1));
11202           return fold_convert_loc (loc, type, tem);
11203         }
11204
11205       /* The argument is const char *, and the result is char *, so we need
11206          a type conversion here to avoid a warning.  */
11207       if (p2[0] == '\0')
11208         return fold_convert_loc (loc, type, s1);
11209
11210       if (p2[1] != '\0')
11211         return NULL_TREE;
11212
11213       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11214       if (!fn)
11215         return NULL_TREE;
11216
11217       /* New argument list transforming strstr(s1, s2) to
11218          strchr(s1, s2[0]).  */
11219       return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11220     }
11221 }
11222
11223 /* Simplify a call to the strchr builtin.  S1 and S2 are the arguments to
11224    the call, and TYPE is its return type.
11225
11226    Return NULL_TREE if no simplification was possible, otherwise return the
11227    simplified form of the call as a tree.
11228
11229    The simplified form may be a constant or other expression which
11230    computes the same value, but in a more efficient manner (including
11231    calls to other builtin functions).
11232
11233    The call may contain arguments which need to be evaluated, but
11234    which are not useful to determine the result of the call.  In
11235    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11236    COMPOUND_EXPR will be an argument which must be evaluated.
11237    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11238    COMPOUND_EXPR in the chain will contain the tree for the simplified
11239    form of the builtin function call.  */
11240
11241 static tree
11242 fold_builtin_strchr (location_t loc, tree s1, tree s2, tree type)
11243 {
11244   if (!validate_arg (s1, POINTER_TYPE)
11245       || !validate_arg (s2, INTEGER_TYPE))
11246     return NULL_TREE;
11247   else
11248     {
11249       const char *p1;
11250
11251       if (TREE_CODE (s2) != INTEGER_CST)
11252         return NULL_TREE;
11253
11254       p1 = c_getstr (s1);
11255       if (p1 != NULL)
11256         {
11257           char c;
11258           const char *r;
11259           tree tem;
11260
11261           if (target_char_cast (s2, &c))
11262             return NULL_TREE;
11263
11264           r = strchr (p1, c);
11265
11266           if (r == NULL)
11267             return build_int_cst (TREE_TYPE (s1), 0);
11268
11269           /* Return an offset into the constant string argument.  */
11270           tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
11271                              s1, size_int (r - p1));
11272           return fold_convert_loc (loc, type, tem);
11273         }
11274       return NULL_TREE;
11275     }
11276 }
11277
11278 /* Simplify a call to the strrchr builtin.  S1 and S2 are the arguments to
11279    the call, and TYPE is its return type.
11280
11281    Return NULL_TREE if no simplification was possible, otherwise return the
11282    simplified form of the call as a tree.
11283
11284    The simplified form may be a constant or other expression which
11285    computes the same value, but in a more efficient manner (including
11286    calls to other builtin functions).
11287
11288    The call may contain arguments which need to be evaluated, but
11289    which are not useful to determine the result of the call.  In
11290    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11291    COMPOUND_EXPR will be an argument which must be evaluated.
11292    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11293    COMPOUND_EXPR in the chain will contain the tree for the simplified
11294    form of the builtin function call.  */
11295
11296 static tree
11297 fold_builtin_strrchr (location_t loc, tree s1, tree s2, tree type)
11298 {
11299   if (!validate_arg (s1, POINTER_TYPE)
11300       || !validate_arg (s2, INTEGER_TYPE))
11301     return NULL_TREE;
11302   else
11303     {
11304       tree fn;
11305       const char *p1;
11306
11307       if (TREE_CODE (s2) != INTEGER_CST)
11308         return NULL_TREE;
11309
11310       p1 = c_getstr (s1);
11311       if (p1 != NULL)
11312         {
11313           char c;
11314           const char *r;
11315           tree tem;
11316
11317           if (target_char_cast (s2, &c))
11318             return NULL_TREE;
11319
11320           r = strrchr (p1, c);
11321
11322           if (r == NULL)
11323             return build_int_cst (TREE_TYPE (s1), 0);
11324
11325           /* Return an offset into the constant string argument.  */
11326           tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
11327                              s1, size_int (r - p1));
11328           return fold_convert_loc (loc, type, tem);
11329         }
11330
11331       if (! integer_zerop (s2))
11332         return NULL_TREE;
11333
11334       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11335       if (!fn)
11336         return NULL_TREE;
11337
11338       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
11339       return build_call_expr_loc (loc, fn, 2, s1, s2);
11340     }
11341 }
11342
11343 /* Simplify a call to the strpbrk builtin.  S1 and S2 are the arguments
11344    to the call, and TYPE is its return type.
11345
11346    Return NULL_TREE if no simplification was possible, otherwise return the
11347    simplified form of the call as a tree.
11348
11349    The simplified form may be a constant or other expression which
11350    computes the same value, but in a more efficient manner (including
11351    calls to other builtin functions).
11352
11353    The call may contain arguments which need to be evaluated, but
11354    which are not useful to determine the result of the call.  In
11355    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11356    COMPOUND_EXPR will be an argument which must be evaluated.
11357    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11358    COMPOUND_EXPR in the chain will contain the tree for the simplified
11359    form of the builtin function call.  */
11360
11361 static tree
11362 fold_builtin_strpbrk (location_t loc, tree s1, tree s2, tree type)
11363 {
11364   if (!validate_arg (s1, POINTER_TYPE)
11365       || !validate_arg (s2, POINTER_TYPE))
11366     return NULL_TREE;
11367   else
11368     {
11369       tree fn;
11370       const char *p1, *p2;
11371
11372       p2 = c_getstr (s2);
11373       if (p2 == NULL)
11374         return NULL_TREE;
11375
11376       p1 = c_getstr (s1);
11377       if (p1 != NULL)
11378         {
11379           const char *r = strpbrk (p1, p2);
11380           tree tem;
11381
11382           if (r == NULL)
11383             return build_int_cst (TREE_TYPE (s1), 0);
11384
11385           /* Return an offset into the constant string argument.  */
11386           tem = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (s1),
11387                              s1, size_int (r - p1));
11388           return fold_convert_loc (loc, type, tem);
11389         }
11390
11391       if (p2[0] == '\0')
11392         /* strpbrk(x, "") == NULL.
11393            Evaluate and ignore s1 in case it had side-effects.  */
11394         return omit_one_operand_loc (loc, TREE_TYPE (s1), integer_zero_node, s1);
11395
11396       if (p2[1] != '\0')
11397         return NULL_TREE;  /* Really call strpbrk.  */
11398
11399       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
11400       if (!fn)
11401         return NULL_TREE;
11402
11403       /* New argument list transforming strpbrk(s1, s2) to
11404          strchr(s1, s2[0]).  */
11405       return build_call_expr_loc (loc, fn, 2, s1, build_int_cst (NULL_TREE, p2[0]));
11406     }
11407 }
11408
11409 /* Simplify a call to the strcat builtin.  DST and SRC are the arguments
11410    to the call.
11411
11412    Return NULL_TREE if no simplification was possible, otherwise return the
11413    simplified form of the call as a tree.
11414
11415    The simplified form may be a constant or other expression which
11416    computes the same value, but in a more efficient manner (including
11417    calls to other builtin functions).
11418
11419    The call may contain arguments which need to be evaluated, but
11420    which are not useful to determine the result of the call.  In
11421    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11422    COMPOUND_EXPR will be an argument which must be evaluated.
11423    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11424    COMPOUND_EXPR in the chain will contain the tree for the simplified
11425    form of the builtin function call.  */
11426
11427 static tree
11428 fold_builtin_strcat (location_t loc ATTRIBUTE_UNUSED, tree dst, tree src)
11429 {
11430   if (!validate_arg (dst, POINTER_TYPE)
11431       || !validate_arg (src, POINTER_TYPE))
11432     return NULL_TREE;
11433   else
11434     {
11435       const char *p = c_getstr (src);
11436
11437       /* If the string length is zero, return the dst parameter.  */
11438       if (p && *p == '\0')
11439         return dst;
11440
11441       if (optimize_insn_for_speed_p ())
11442         {
11443           /* See if we can store by pieces into (dst + strlen(dst)).  */
11444           tree newdst, call;
11445           tree strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11446           tree strcpy_fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11447
11448           if (!strlen_fn || !strcpy_fn)
11449             return NULL_TREE;
11450
11451           /* If we don't have a movstr we don't want to emit an strcpy
11452              call.  We have to do that if the length of the source string
11453              isn't computable (in that case we can use memcpy probably
11454              later expanding to a sequence of mov instructions).  If we 
11455              have movstr instructions we can emit strcpy calls.  */
11456           if (!HAVE_movstr)
11457             {
11458               tree len = c_strlen (src, 1);
11459               if (! len || TREE_SIDE_EFFECTS (len))
11460                 return NULL_TREE;
11461             }
11462
11463           /* Stabilize the argument list.  */
11464           dst = builtin_save_expr (dst);
11465
11466           /* Create strlen (dst).  */
11467           newdst = build_call_expr_loc (loc, strlen_fn, 1, dst);
11468           /* Create (dst p+ strlen (dst)).  */
11469
11470           newdst = fold_build2_loc (loc, POINTER_PLUS_EXPR,
11471                                 TREE_TYPE (dst), dst, newdst);
11472           newdst = builtin_save_expr (newdst);
11473
11474           call = build_call_expr_loc (loc, strcpy_fn, 2, newdst, src);
11475           return build2 (COMPOUND_EXPR, TREE_TYPE (dst), call, dst);
11476         }
11477       return NULL_TREE;
11478     }
11479 }
11480
11481 /* Simplify a call to the strncat builtin.  DST, SRC, and LEN are the
11482    arguments to the call.
11483
11484    Return NULL_TREE if no simplification was possible, otherwise return the
11485    simplified form of the call as a tree.
11486
11487    The simplified form may be a constant or other expression which
11488    computes the same value, but in a more efficient manner (including
11489    calls to other builtin functions).
11490
11491    The call may contain arguments which need to be evaluated, but
11492    which are not useful to determine the result of the call.  In
11493    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11494    COMPOUND_EXPR will be an argument which must be evaluated.
11495    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11496    COMPOUND_EXPR in the chain will contain the tree for the simplified
11497    form of the builtin function call.  */
11498
11499 static tree
11500 fold_builtin_strncat (location_t loc, tree dst, tree src, tree len)
11501 {
11502   if (!validate_arg (dst, POINTER_TYPE)
11503       || !validate_arg (src, POINTER_TYPE)
11504       || !validate_arg (len, INTEGER_TYPE))
11505     return NULL_TREE;
11506   else
11507     {
11508       const char *p = c_getstr (src);
11509
11510       /* If the requested length is zero, or the src parameter string
11511          length is zero, return the dst parameter.  */
11512       if (integer_zerop (len) || (p && *p == '\0'))
11513         return omit_two_operands_loc (loc, TREE_TYPE (dst), dst, src, len);
11514
11515       /* If the requested len is greater than or equal to the string
11516          length, call strcat.  */
11517       if (TREE_CODE (len) == INTEGER_CST && p
11518           && compare_tree_int (len, strlen (p)) >= 0)
11519         {
11520           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
11521
11522           /* If the replacement _DECL isn't initialized, don't do the
11523              transformation.  */
11524           if (!fn)
11525             return NULL_TREE;
11526
11527           return build_call_expr_loc (loc, fn, 2, dst, src);
11528         }
11529       return NULL_TREE;
11530     }
11531 }
11532
11533 /* Simplify a call to the strspn builtin.  S1 and S2 are the arguments
11534    to the call.
11535
11536    Return NULL_TREE if no simplification was possible, otherwise return the
11537    simplified form of the call as a tree.
11538
11539    The simplified form may be a constant or other expression which
11540    computes the same value, but in a more efficient manner (including
11541    calls to other builtin functions).
11542
11543    The call may contain arguments which need to be evaluated, but
11544    which are not useful to determine the result of the call.  In
11545    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11546    COMPOUND_EXPR will be an argument which must be evaluated.
11547    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11548    COMPOUND_EXPR in the chain will contain the tree for the simplified
11549    form of the builtin function call.  */
11550
11551 static tree
11552 fold_builtin_strspn (location_t loc, tree s1, tree s2)
11553 {
11554   if (!validate_arg (s1, POINTER_TYPE)
11555       || !validate_arg (s2, POINTER_TYPE))
11556     return NULL_TREE;
11557   else
11558     {
11559       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11560
11561       /* If both arguments are constants, evaluate at compile-time.  */
11562       if (p1 && p2)
11563         {
11564           const size_t r = strspn (p1, p2);
11565           return size_int (r);
11566         }
11567
11568       /* If either argument is "", return NULL_TREE.  */
11569       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
11570         /* Evaluate and ignore both arguments in case either one has
11571            side-effects.  */
11572         return omit_two_operands_loc (loc, size_type_node, size_zero_node,
11573                                   s1, s2);
11574       return NULL_TREE;
11575     }
11576 }
11577
11578 /* Simplify a call to the strcspn builtin.  S1 and S2 are the arguments
11579    to the call.
11580
11581    Return NULL_TREE if no simplification was possible, otherwise return the
11582    simplified form of the call as a tree.
11583
11584    The simplified form may be a constant or other expression which
11585    computes the same value, but in a more efficient manner (including
11586    calls to other builtin functions).
11587
11588    The call may contain arguments which need to be evaluated, but
11589    which are not useful to determine the result of the call.  In
11590    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
11591    COMPOUND_EXPR will be an argument which must be evaluated.
11592    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
11593    COMPOUND_EXPR in the chain will contain the tree for the simplified
11594    form of the builtin function call.  */
11595
11596 static tree
11597 fold_builtin_strcspn (location_t loc, tree s1, tree s2)
11598 {
11599   if (!validate_arg (s1, POINTER_TYPE)
11600       || !validate_arg (s2, POINTER_TYPE))
11601     return NULL_TREE;
11602   else
11603     {
11604       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
11605
11606       /* If both arguments are constants, evaluate at compile-time.  */
11607       if (p1 && p2)
11608         {
11609           const size_t r = strcspn (p1, p2);
11610           return size_int (r);
11611         }
11612
11613       /* If the first argument is "", return NULL_TREE.  */
11614       if (p1 && *p1 == '\0')
11615         {
11616           /* Evaluate and ignore argument s2 in case it has
11617              side-effects.  */
11618           return omit_one_operand_loc (loc, size_type_node,
11619                                    size_zero_node, s2);
11620         }
11621
11622       /* If the second argument is "", return __builtin_strlen(s1).  */
11623       if (p2 && *p2 == '\0')
11624         {
11625           tree fn = implicit_built_in_decls[BUILT_IN_STRLEN];
11626
11627           /* If the replacement _DECL isn't initialized, don't do the
11628              transformation.  */
11629           if (!fn)
11630             return NULL_TREE;
11631
11632           return build_call_expr_loc (loc, fn, 1, s1);
11633         }
11634       return NULL_TREE;
11635     }
11636 }
11637
11638 /* Fold a call to the fputs builtin.  ARG0 and ARG1 are the arguments
11639    to the call.  IGNORE is true if the value returned
11640    by the builtin will be ignored.  UNLOCKED is true is true if this
11641    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
11642    the known length of the string.  Return NULL_TREE if no simplification
11643    was possible.  */
11644
11645 tree
11646 fold_builtin_fputs (location_t loc, tree arg0, tree arg1,
11647                     bool ignore, bool unlocked, tree len)
11648 {
11649   /* If we're using an unlocked function, assume the other unlocked
11650      functions exist explicitly.  */
11651   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
11652     : implicit_built_in_decls[BUILT_IN_FPUTC];
11653   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
11654     : implicit_built_in_decls[BUILT_IN_FWRITE];
11655
11656   /* If the return value is used, don't do the transformation.  */
11657   if (!ignore)
11658     return NULL_TREE;
11659
11660   /* Verify the arguments in the original call.  */
11661   if (!validate_arg (arg0, POINTER_TYPE)
11662       || !validate_arg (arg1, POINTER_TYPE))
11663     return NULL_TREE;
11664
11665   if (! len)
11666     len = c_strlen (arg0, 0);
11667
11668   /* Get the length of the string passed to fputs.  If the length
11669      can't be determined, punt.  */
11670   if (!len
11671       || TREE_CODE (len) != INTEGER_CST)
11672     return NULL_TREE;
11673
11674   switch (compare_tree_int (len, 1))
11675     {
11676     case -1: /* length is 0, delete the call entirely .  */
11677       return omit_one_operand_loc (loc, integer_type_node,
11678                                integer_zero_node, arg1);;
11679
11680     case 0: /* length is 1, call fputc.  */
11681       {
11682         const char *p = c_getstr (arg0);
11683
11684         if (p != NULL)
11685           {
11686             if (fn_fputc)
11687               return build_call_expr_loc (loc, fn_fputc, 2,
11688                                       build_int_cst (NULL_TREE, p[0]), arg1);
11689             else
11690               return NULL_TREE;
11691           }
11692       }
11693       /* FALLTHROUGH */
11694     case 1: /* length is greater than 1, call fwrite.  */
11695       {
11696         /* If optimizing for size keep fputs.  */
11697         if (optimize_function_for_size_p (cfun))
11698           return NULL_TREE;
11699         /* New argument list transforming fputs(string, stream) to
11700            fwrite(string, 1, len, stream).  */
11701         if (fn_fwrite)
11702           return build_call_expr_loc (loc, fn_fwrite, 4, arg0,
11703                                   size_one_node, len, arg1);
11704         else
11705           return NULL_TREE;
11706       }
11707     default:
11708       gcc_unreachable ();
11709     }
11710   return NULL_TREE;
11711 }
11712
11713 /* Fold the next_arg or va_start call EXP. Returns true if there was an error
11714    produced.  False otherwise.  This is done so that we don't output the error
11715    or warning twice or three times.  */
11716
11717 bool
11718 fold_builtin_next_arg (tree exp, bool va_start_p)
11719 {
11720   tree fntype = TREE_TYPE (current_function_decl);
11721   int nargs = call_expr_nargs (exp);
11722   tree arg;
11723
11724   if (TYPE_ARG_TYPES (fntype) == 0
11725       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
11726           == void_type_node))
11727     {
11728       error ("%<va_start%> used in function with fixed args");
11729       return true;
11730     }
11731
11732   if (va_start_p)
11733     {
11734       if (va_start_p && (nargs != 2))
11735         {
11736           error ("wrong number of arguments to function %<va_start%>");
11737           return true;
11738         }
11739       arg = CALL_EXPR_ARG (exp, 1);
11740     }
11741   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
11742      when we checked the arguments and if needed issued a warning.  */
11743   else
11744     {
11745       if (nargs == 0)
11746         {
11747           /* Evidently an out of date version of <stdarg.h>; can't validate
11748              va_start's second argument, but can still work as intended.  */
11749           warning (0, "%<__builtin_next_arg%> called without an argument");
11750           return true;
11751         }
11752       else if (nargs > 1)
11753         {
11754           error ("wrong number of arguments to function %<__builtin_next_arg%>");
11755           return true;
11756         }
11757       arg = CALL_EXPR_ARG (exp, 0);
11758     }
11759
11760   if (TREE_CODE (arg) == SSA_NAME)
11761     arg = SSA_NAME_VAR (arg);
11762
11763   /* We destructively modify the call to be __builtin_va_start (ap, 0)
11764      or __builtin_next_arg (0) the first time we see it, after checking 
11765      the arguments and if needed issuing a warning.  */
11766   if (!integer_zerop (arg))
11767     {
11768       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
11769
11770       /* Strip off all nops for the sake of the comparison.  This
11771          is not quite the same as STRIP_NOPS.  It does more.
11772          We must also strip off INDIRECT_EXPR for C++ reference
11773          parameters.  */
11774       while (CONVERT_EXPR_P (arg)
11775              || TREE_CODE (arg) == INDIRECT_REF)
11776         arg = TREE_OPERAND (arg, 0);
11777       if (arg != last_parm)
11778         {
11779           /* FIXME: Sometimes with the tree optimizers we can get the
11780              not the last argument even though the user used the last
11781              argument.  We just warn and set the arg to be the last
11782              argument so that we will get wrong-code because of
11783              it.  */
11784           warning (0, "second parameter of %<va_start%> not last named argument");
11785         }
11786
11787       /* Undefined by C99 7.15.1.4p4 (va_start):
11788          "If the parameter parmN is declared with the register storage
11789          class, with a function or array type, or with a type that is
11790          not compatible with the type that results after application of
11791          the default argument promotions, the behavior is undefined."
11792       */
11793       else if (DECL_REGISTER (arg))
11794         warning (0, "undefined behaviour when second parameter of "
11795                  "%<va_start%> is declared with %<register%> storage");
11796
11797       /* We want to verify the second parameter just once before the tree
11798          optimizers are run and then avoid keeping it in the tree,
11799          as otherwise we could warn even for correct code like:
11800          void foo (int i, ...)
11801          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
11802       if (va_start_p)
11803         CALL_EXPR_ARG (exp, 1) = integer_zero_node;
11804       else
11805         CALL_EXPR_ARG (exp, 0) = integer_zero_node;
11806     }
11807   return false;
11808 }
11809
11810
11811 /* Simplify a call to the sprintf builtin with arguments DEST, FMT, and ORIG.
11812    ORIG may be null if this is a 2-argument call.  We don't attempt to
11813    simplify calls with more than 3 arguments.
11814
11815    Return NULL_TREE if no simplification was possible, otherwise return the
11816    simplified form of the call as a tree.  If IGNORED is true, it means that
11817    the caller does not use the returned value of the function.  */
11818
11819 static tree
11820 fold_builtin_sprintf (location_t loc, tree dest, tree fmt,
11821                       tree orig, int ignored)
11822 {
11823   tree call, retval;
11824   const char *fmt_str = NULL;
11825
11826   /* Verify the required arguments in the original call.  We deal with two
11827      types of sprintf() calls: 'sprintf (str, fmt)' and
11828      'sprintf (dest, "%s", orig)'.  */
11829   if (!validate_arg (dest, POINTER_TYPE)
11830       || !validate_arg (fmt, POINTER_TYPE))
11831     return NULL_TREE;
11832   if (orig && !validate_arg (orig, POINTER_TYPE))
11833     return NULL_TREE;
11834
11835   /* Check whether the format is a literal string constant.  */
11836   fmt_str = c_getstr (fmt);
11837   if (fmt_str == NULL)
11838     return NULL_TREE;
11839
11840   call = NULL_TREE;
11841   retval = NULL_TREE;
11842
11843   if (!init_target_chars ())
11844     return NULL_TREE;
11845
11846   /* If the format doesn't contain % args or %%, use strcpy.  */
11847   if (strchr (fmt_str, target_percent) == NULL)
11848     {
11849       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11850
11851       if (!fn)
11852         return NULL_TREE;
11853
11854       /* Don't optimize sprintf (buf, "abc", ptr++).  */
11855       if (orig)
11856         return NULL_TREE;
11857
11858       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
11859          'format' is known to contain no % formats.  */
11860       call = build_call_expr_loc (loc, fn, 2, dest, fmt);
11861       if (!ignored)
11862         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
11863     }
11864
11865   /* If the format is "%s", use strcpy if the result isn't used.  */
11866   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
11867     {
11868       tree fn;
11869       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
11870
11871       if (!fn)
11872         return NULL_TREE;
11873
11874       /* Don't crash on sprintf (str1, "%s").  */
11875       if (!orig)
11876         return NULL_TREE;
11877
11878       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
11879       if (!ignored)
11880         {
11881           retval = c_strlen (orig, 1);
11882           if (!retval || TREE_CODE (retval) != INTEGER_CST)
11883             return NULL_TREE;
11884         }
11885       call = build_call_expr_loc (loc, fn, 2, dest, orig);
11886     }
11887
11888   if (call && retval)
11889     {
11890       retval = fold_convert_loc
11891         (loc, TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
11892          retval);
11893       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
11894     }
11895   else
11896     return call;
11897 }
11898
11899 /* Expand a call EXP to __builtin_object_size.  */
11900
11901 rtx
11902 expand_builtin_object_size (tree exp)
11903 {
11904   tree ost;
11905   int object_size_type;
11906   tree fndecl = get_callee_fndecl (exp);
11907
11908   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
11909     {
11910       error ("%Kfirst argument of %D must be a pointer, second integer constant",
11911              exp, fndecl);
11912       expand_builtin_trap ();
11913       return const0_rtx;
11914     }
11915
11916   ost = CALL_EXPR_ARG (exp, 1);
11917   STRIP_NOPS (ost);
11918
11919   if (TREE_CODE (ost) != INTEGER_CST
11920       || tree_int_cst_sgn (ost) < 0
11921       || compare_tree_int (ost, 3) > 0)
11922     {
11923       error ("%Klast argument of %D is not integer constant between 0 and 3",
11924              exp, fndecl);
11925       expand_builtin_trap ();
11926       return const0_rtx;
11927     }
11928
11929   object_size_type = tree_low_cst (ost, 0);
11930
11931   return object_size_type < 2 ? constm1_rtx : const0_rtx;
11932 }
11933
11934 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
11935    FCODE is the BUILT_IN_* to use.
11936    Return NULL_RTX if we failed; the caller should emit a normal call,
11937    otherwise try to get the result in TARGET, if convenient (and in
11938    mode MODE if that's convenient).  */
11939
11940 static rtx
11941 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
11942                            enum built_in_function fcode)
11943 {
11944   tree dest, src, len, size;
11945
11946   if (!validate_arglist (exp,
11947                          POINTER_TYPE,
11948                          fcode == BUILT_IN_MEMSET_CHK
11949                          ? INTEGER_TYPE : POINTER_TYPE,
11950                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
11951     return NULL_RTX;
11952
11953   dest = CALL_EXPR_ARG (exp, 0);
11954   src = CALL_EXPR_ARG (exp, 1);
11955   len = CALL_EXPR_ARG (exp, 2);
11956   size = CALL_EXPR_ARG (exp, 3);
11957
11958   if (! host_integerp (size, 1))
11959     return NULL_RTX;
11960
11961   if (host_integerp (len, 1) || integer_all_onesp (size))
11962     {
11963       tree fn;
11964
11965       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
11966         {
11967           warning_at (tree_nonartificial_location (exp),
11968                       0, "%Kcall to %D will always overflow destination buffer",
11969                       exp, get_callee_fndecl (exp));
11970           return NULL_RTX;
11971         }
11972
11973       fn = NULL_TREE;
11974       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
11975          mem{cpy,pcpy,move,set} is available.  */
11976       switch (fcode)
11977         {
11978         case BUILT_IN_MEMCPY_CHK:
11979           fn = built_in_decls[BUILT_IN_MEMCPY];
11980           break;
11981         case BUILT_IN_MEMPCPY_CHK:
11982           fn = built_in_decls[BUILT_IN_MEMPCPY];
11983           break;
11984         case BUILT_IN_MEMMOVE_CHK:
11985           fn = built_in_decls[BUILT_IN_MEMMOVE];
11986           break;
11987         case BUILT_IN_MEMSET_CHK:
11988           fn = built_in_decls[BUILT_IN_MEMSET];
11989           break;
11990         default:
11991           break;
11992         }
11993
11994       if (! fn)
11995         return NULL_RTX;
11996
11997       fn = build_call_nofold (fn, 3, dest, src, len);
11998       gcc_assert (TREE_CODE (fn) == CALL_EXPR);
11999       CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12000       return expand_expr (fn, target, mode, EXPAND_NORMAL);
12001     }
12002   else if (fcode == BUILT_IN_MEMSET_CHK)
12003     return NULL_RTX;
12004   else
12005     {
12006       unsigned int dest_align
12007         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
12008
12009       /* If DEST is not a pointer type, call the normal function.  */
12010       if (dest_align == 0)
12011         return NULL_RTX;
12012
12013       /* If SRC and DEST are the same (and not volatile), do nothing.  */
12014       if (operand_equal_p (src, dest, 0))
12015         {
12016           tree expr;
12017
12018           if (fcode != BUILT_IN_MEMPCPY_CHK)
12019             {
12020               /* Evaluate and ignore LEN in case it has side-effects.  */
12021               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
12022               return expand_expr (dest, target, mode, EXPAND_NORMAL);
12023             }
12024
12025           expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (dest), dest, len);
12026           return expand_expr (expr, target, mode, EXPAND_NORMAL);
12027         }
12028
12029       /* __memmove_chk special case.  */
12030       if (fcode == BUILT_IN_MEMMOVE_CHK)
12031         {
12032           unsigned int src_align
12033             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
12034
12035           if (src_align == 0)
12036             return NULL_RTX;
12037
12038           /* If src is categorized for a readonly section we can use
12039              normal __memcpy_chk.  */
12040           if (readonly_data_expr (src))
12041             {
12042               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12043               if (!fn)
12044                 return NULL_RTX;
12045               fn = build_call_nofold (fn, 4, dest, src, len, size);
12046               gcc_assert (TREE_CODE (fn) == CALL_EXPR);
12047               CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
12048               return expand_expr (fn, target, mode, EXPAND_NORMAL);
12049             }
12050         }
12051       return NULL_RTX;
12052     }
12053 }
12054
12055 /* Emit warning if a buffer overflow is detected at compile time.  */
12056
12057 static void
12058 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
12059 {
12060   int is_strlen = 0;
12061   tree len, size;
12062   location_t loc = tree_nonartificial_location (exp);
12063
12064   switch (fcode)
12065     {
12066     case BUILT_IN_STRCPY_CHK:
12067     case BUILT_IN_STPCPY_CHK:
12068     /* For __strcat_chk the warning will be emitted only if overflowing
12069        by at least strlen (dest) + 1 bytes.  */
12070     case BUILT_IN_STRCAT_CHK:
12071       len = CALL_EXPR_ARG (exp, 1);
12072       size = CALL_EXPR_ARG (exp, 2);
12073       is_strlen = 1;
12074       break;
12075     case BUILT_IN_STRNCAT_CHK:
12076     case BUILT_IN_STRNCPY_CHK:
12077       len = CALL_EXPR_ARG (exp, 2);
12078       size = CALL_EXPR_ARG (exp, 3);
12079       break;
12080     case BUILT_IN_SNPRINTF_CHK:
12081     case BUILT_IN_VSNPRINTF_CHK:
12082       len = CALL_EXPR_ARG (exp, 1);
12083       size = CALL_EXPR_ARG (exp, 3);
12084       break;
12085     default:
12086       gcc_unreachable ();
12087     }
12088
12089   if (!len || !size)
12090     return;
12091
12092   if (! host_integerp (size, 1) || integer_all_onesp (size))
12093     return;
12094
12095   if (is_strlen)
12096     {
12097       len = c_strlen (len, 1);
12098       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12099         return;
12100     }
12101   else if (fcode == BUILT_IN_STRNCAT_CHK)
12102     {
12103       tree src = CALL_EXPR_ARG (exp, 1);
12104       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
12105         return;
12106       src = c_strlen (src, 1);
12107       if (! src || ! host_integerp (src, 1))
12108         {
12109           warning_at (loc, 0, "%Kcall to %D might overflow destination buffer",
12110                       exp, get_callee_fndecl (exp));
12111           return;
12112         }
12113       else if (tree_int_cst_lt (src, size))
12114         return;
12115     }
12116   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
12117     return;
12118
12119   warning_at (loc, 0, "%Kcall to %D will always overflow destination buffer",
12120               exp, get_callee_fndecl (exp));
12121 }
12122
12123 /* Emit warning if a buffer overflow is detected at compile time
12124    in __sprintf_chk/__vsprintf_chk calls.  */
12125
12126 static void
12127 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
12128 {
12129   tree size, len, fmt;
12130   const char *fmt_str;
12131   int nargs = call_expr_nargs (exp);
12132
12133   /* Verify the required arguments in the original call.  */
12134   
12135   if (nargs < 4)
12136     return;
12137   size = CALL_EXPR_ARG (exp, 2);
12138   fmt = CALL_EXPR_ARG (exp, 3);
12139
12140   if (! host_integerp (size, 1) || integer_all_onesp (size))
12141     return;
12142
12143   /* Check whether the format is a literal string constant.  */
12144   fmt_str = c_getstr (fmt);
12145   if (fmt_str == NULL)
12146     return;
12147
12148   if (!init_target_chars ())
12149     return;
12150
12151   /* If the format doesn't contain % args or %%, we know its size.  */
12152   if (strchr (fmt_str, target_percent) == 0)
12153     len = build_int_cstu (size_type_node, strlen (fmt_str));
12154   /* If the format is "%s" and first ... argument is a string literal,
12155      we know it too.  */
12156   else if (fcode == BUILT_IN_SPRINTF_CHK
12157            && strcmp (fmt_str, target_percent_s) == 0)
12158     {
12159       tree arg;
12160
12161       if (nargs < 5)
12162         return;
12163       arg = CALL_EXPR_ARG (exp, 4);
12164       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
12165         return;
12166
12167       len = c_strlen (arg, 1);
12168       if (!len || ! host_integerp (len, 1))
12169         return;
12170     }
12171   else
12172     return;
12173
12174   if (! tree_int_cst_lt (len, size))
12175     warning_at (tree_nonartificial_location (exp),
12176                 0, "%Kcall to %D will always overflow destination buffer",
12177                 exp, get_callee_fndecl (exp));
12178 }
12179
12180 /* Emit warning if a free is called with address of a variable.  */
12181
12182 static void
12183 maybe_emit_free_warning (tree exp)
12184 {
12185   tree arg = CALL_EXPR_ARG (exp, 0);
12186
12187   STRIP_NOPS (arg);
12188   if (TREE_CODE (arg) != ADDR_EXPR)
12189     return;
12190
12191   arg = get_base_address (TREE_OPERAND (arg, 0));
12192   if (arg == NULL || INDIRECT_REF_P (arg))
12193     return;
12194
12195   if (SSA_VAR_P (arg))
12196     warning_at (tree_nonartificial_location (exp),
12197                 0, "%Kattempt to free a non-heap object %qD", exp, arg);
12198   else
12199     warning_at (tree_nonartificial_location (exp),
12200                 0, "%Kattempt to free a non-heap object", exp);
12201 }
12202
12203 /* Fold a call to __builtin_object_size with arguments PTR and OST,
12204    if possible.  */
12205
12206 tree
12207 fold_builtin_object_size (tree ptr, tree ost)
12208 {
12209   tree ret = NULL_TREE;
12210   int object_size_type;
12211
12212   if (!validate_arg (ptr, POINTER_TYPE)
12213       || !validate_arg (ost, INTEGER_TYPE))
12214     return NULL_TREE;
12215
12216   STRIP_NOPS (ost);
12217
12218   if (TREE_CODE (ost) != INTEGER_CST
12219       || tree_int_cst_sgn (ost) < 0
12220       || compare_tree_int (ost, 3) > 0)
12221     return NULL_TREE;
12222
12223   object_size_type = tree_low_cst (ost, 0);
12224
12225   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
12226      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
12227      and (size_t) 0 for types 2 and 3.  */
12228   if (TREE_SIDE_EFFECTS (ptr))
12229     return build_int_cst_type (size_type_node, object_size_type < 2 ? -1 : 0);
12230
12231   if (TREE_CODE (ptr) == ADDR_EXPR)
12232     ret = build_int_cstu (size_type_node,
12233                           compute_builtin_object_size (ptr, object_size_type));
12234
12235   else if (TREE_CODE (ptr) == SSA_NAME)
12236     {
12237       unsigned HOST_WIDE_INT bytes;
12238
12239       /* If object size is not known yet, delay folding until
12240        later.  Maybe subsequent passes will help determining
12241        it.  */
12242       bytes = compute_builtin_object_size (ptr, object_size_type);
12243       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
12244                                              ? -1 : 0))
12245         ret = build_int_cstu (size_type_node, bytes);
12246     }
12247
12248   if (ret)
12249     {
12250       unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (ret);
12251       HOST_WIDE_INT high = TREE_INT_CST_HIGH (ret);
12252       if (fit_double_type (low, high, &low, &high, TREE_TYPE (ret)))
12253         ret = NULL_TREE;
12254     }
12255
12256   return ret;
12257 }
12258
12259 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
12260    DEST, SRC, LEN, and SIZE are the arguments to the call.
12261    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
12262    code of the builtin.  If MAXLEN is not NULL, it is maximum length
12263    passed as third argument.  */
12264
12265 tree
12266 fold_builtin_memory_chk (location_t loc, tree fndecl,
12267                          tree dest, tree src, tree len, tree size,
12268                          tree maxlen, bool ignore,
12269                          enum built_in_function fcode)
12270 {
12271   tree fn;
12272
12273   if (!validate_arg (dest, POINTER_TYPE)
12274       || !validate_arg (src,
12275                         (fcode == BUILT_IN_MEMSET_CHK
12276                          ? INTEGER_TYPE : POINTER_TYPE))
12277       || !validate_arg (len, INTEGER_TYPE)
12278       || !validate_arg (size, INTEGER_TYPE))
12279     return NULL_TREE;
12280
12281   /* If SRC and DEST are the same (and not volatile), return DEST
12282      (resp. DEST+LEN for __mempcpy_chk).  */
12283   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
12284     {
12285       if (fcode != BUILT_IN_MEMPCPY_CHK)
12286         return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12287                                  dest, len);
12288       else
12289         {
12290           tree temp = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dest),
12291                                    dest, len);
12292           return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), temp);
12293         }
12294     }
12295
12296   if (! host_integerp (size, 1))
12297     return NULL_TREE;
12298
12299   if (! integer_all_onesp (size))
12300     {
12301       if (! host_integerp (len, 1))
12302         {
12303           /* If LEN is not constant, try MAXLEN too.
12304              For MAXLEN only allow optimizing into non-_ocs function
12305              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12306           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12307             {
12308               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
12309                 {
12310                   /* (void) __mempcpy_chk () can be optimized into
12311                      (void) __memcpy_chk ().  */
12312                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12313                   if (!fn)
12314                     return NULL_TREE;
12315
12316                   return build_call_expr_loc (loc, fn, 4, dest, src, len, size);
12317                 }
12318               return NULL_TREE;
12319             }
12320         }
12321       else
12322         maxlen = len;
12323
12324       if (tree_int_cst_lt (size, maxlen))
12325         return NULL_TREE;
12326     }
12327
12328   fn = NULL_TREE;
12329   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
12330      mem{cpy,pcpy,move,set} is available.  */
12331   switch (fcode)
12332     {
12333     case BUILT_IN_MEMCPY_CHK:
12334       fn = built_in_decls[BUILT_IN_MEMCPY];
12335       break;
12336     case BUILT_IN_MEMPCPY_CHK:
12337       fn = built_in_decls[BUILT_IN_MEMPCPY];
12338       break;
12339     case BUILT_IN_MEMMOVE_CHK:
12340       fn = built_in_decls[BUILT_IN_MEMMOVE];
12341       break;
12342     case BUILT_IN_MEMSET_CHK:
12343       fn = built_in_decls[BUILT_IN_MEMSET];
12344       break;
12345     default:
12346       break;
12347     }
12348
12349   if (!fn)
12350     return NULL_TREE;
12351
12352   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12353 }
12354
12355 /* Fold a call to the __st[rp]cpy_chk builtin.
12356    DEST, SRC, and SIZE are the arguments to the call.
12357    IGNORE is true if return value can be ignored.  FCODE is the BUILT_IN_*
12358    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
12359    strings passed as second argument.  */
12360
12361 tree
12362 fold_builtin_stxcpy_chk (location_t loc, tree fndecl, tree dest,
12363                          tree src, tree size,
12364                          tree maxlen, bool ignore,
12365                          enum built_in_function fcode)
12366 {
12367   tree len, fn;
12368
12369   if (!validate_arg (dest, POINTER_TYPE)
12370       || !validate_arg (src, POINTER_TYPE)
12371       || !validate_arg (size, INTEGER_TYPE))
12372     return NULL_TREE;
12373
12374   /* If SRC and DEST are the same (and not volatile), return DEST.  */
12375   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
12376     return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest);
12377
12378   if (! host_integerp (size, 1))
12379     return NULL_TREE;
12380
12381   if (! integer_all_onesp (size))
12382     {
12383       len = c_strlen (src, 1);
12384       if (! len || ! host_integerp (len, 1))
12385         {
12386           /* If LEN is not constant, try MAXLEN too.
12387              For MAXLEN only allow optimizing into non-_ocs function
12388              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12389           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12390             {
12391               if (fcode == BUILT_IN_STPCPY_CHK)
12392                 {
12393                   if (! ignore)
12394                     return NULL_TREE;
12395
12396                   /* If return value of __stpcpy_chk is ignored,
12397                      optimize into __strcpy_chk.  */
12398                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
12399                   if (!fn)
12400                     return NULL_TREE;
12401
12402                   return build_call_expr_loc (loc, fn, 3, dest, src, size);
12403                 }
12404
12405               if (! len || TREE_SIDE_EFFECTS (len))
12406                 return NULL_TREE;
12407
12408               /* If c_strlen returned something, but not a constant,
12409                  transform __strcpy_chk into __memcpy_chk.  */
12410               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
12411               if (!fn)
12412                 return NULL_TREE;
12413
12414               len = size_binop_loc (loc, PLUS_EXPR, len, ssize_int (1));
12415               return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)),
12416                                        build_call_expr_loc (loc, fn, 4,
12417                                                         dest, src, len, size));
12418             }
12419         }
12420       else
12421         maxlen = len;
12422
12423       if (! tree_int_cst_lt (maxlen, size))
12424         return NULL_TREE;
12425     }
12426
12427   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
12428   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
12429                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
12430   if (!fn)
12431     return NULL_TREE;
12432
12433   return build_call_expr_loc (loc, fn, 2, dest, src);
12434 }
12435
12436 /* Fold a call to the __strncpy_chk builtin.  DEST, SRC, LEN, and SIZE
12437    are the arguments to the call.  If MAXLEN is not NULL, it is maximum
12438    length passed as third argument.  */
12439
12440 tree
12441 fold_builtin_strncpy_chk (location_t loc, tree dest, tree src,
12442                           tree len, tree size, tree maxlen)
12443 {
12444   tree fn;
12445
12446   if (!validate_arg (dest, POINTER_TYPE)
12447       || !validate_arg (src, POINTER_TYPE)
12448       || !validate_arg (len, INTEGER_TYPE)
12449       || !validate_arg (size, INTEGER_TYPE))
12450     return NULL_TREE;
12451
12452   if (! host_integerp (size, 1))
12453     return NULL_TREE;
12454
12455   if (! integer_all_onesp (size))
12456     {
12457       if (! host_integerp (len, 1))
12458         {
12459           /* If LEN is not constant, try MAXLEN too.
12460              For MAXLEN only allow optimizing into non-_ocs function
12461              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12462           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12463             return NULL_TREE;
12464         }
12465       else
12466         maxlen = len;
12467
12468       if (tree_int_cst_lt (size, maxlen))
12469         return NULL_TREE;
12470     }
12471
12472   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
12473   fn = built_in_decls[BUILT_IN_STRNCPY];
12474   if (!fn)
12475     return NULL_TREE;
12476
12477   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12478 }
12479
12480 /* Fold a call to the __strcat_chk builtin FNDECL.  DEST, SRC, and SIZE
12481    are the arguments to the call.  */
12482
12483 static tree
12484 fold_builtin_strcat_chk (location_t loc, tree fndecl, tree dest,
12485                          tree src, tree size)
12486 {
12487   tree fn;
12488   const char *p;
12489
12490   if (!validate_arg (dest, POINTER_TYPE)
12491       || !validate_arg (src, POINTER_TYPE)
12492       || !validate_arg (size, INTEGER_TYPE))
12493     return NULL_TREE;
12494
12495   p = c_getstr (src);
12496   /* If the SRC parameter is "", return DEST.  */
12497   if (p && *p == '\0')
12498     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12499
12500   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
12501     return NULL_TREE;
12502
12503   /* If __builtin_strcat_chk is used, assume strcat is available.  */
12504   fn = built_in_decls[BUILT_IN_STRCAT];
12505   if (!fn)
12506     return NULL_TREE;
12507
12508   return build_call_expr_loc (loc, fn, 2, dest, src);
12509 }
12510
12511 /* Fold a call to the __strncat_chk builtin with arguments DEST, SRC,
12512    LEN, and SIZE.  */
12513
12514 static tree
12515 fold_builtin_strncat_chk (location_t loc, tree fndecl,
12516                           tree dest, tree src, tree len, tree size)
12517 {
12518   tree fn;
12519   const char *p;
12520
12521   if (!validate_arg (dest, POINTER_TYPE)
12522       || !validate_arg (src, POINTER_TYPE)
12523       || !validate_arg (size, INTEGER_TYPE)
12524       || !validate_arg (size, INTEGER_TYPE))
12525     return NULL_TREE;
12526
12527   p = c_getstr (src);
12528   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
12529   if (p && *p == '\0')
12530     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
12531   else if (integer_zerop (len))
12532     return omit_one_operand_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
12533
12534   if (! host_integerp (size, 1))
12535     return NULL_TREE;
12536
12537   if (! integer_all_onesp (size))
12538     {
12539       tree src_len = c_strlen (src, 1);
12540       if (src_len
12541           && host_integerp (src_len, 1)
12542           && host_integerp (len, 1)
12543           && ! tree_int_cst_lt (len, src_len))
12544         {
12545           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
12546           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
12547           if (!fn)
12548             return NULL_TREE;
12549
12550           return build_call_expr_loc (loc, fn, 3, dest, src, size);
12551         }
12552       return NULL_TREE;
12553     }
12554
12555   /* If __builtin_strncat_chk is used, assume strncat is available.  */
12556   fn = built_in_decls[BUILT_IN_STRNCAT];
12557   if (!fn)
12558     return NULL_TREE;
12559
12560   return build_call_expr_loc (loc, fn, 3, dest, src, len);
12561 }
12562
12563 /* Fold a call EXP to __{,v}sprintf_chk.  Return NULL_TREE if
12564    a normal call should be emitted rather than expanding the function
12565    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
12566
12567 static tree
12568 fold_builtin_sprintf_chk (location_t loc, tree exp,
12569                           enum built_in_function fcode)
12570 {
12571   tree dest, size, len, fn, fmt, flag;
12572   const char *fmt_str;
12573   int nargs = call_expr_nargs (exp);
12574
12575   /* Verify the required arguments in the original call.  */
12576   if (nargs < 4)
12577     return NULL_TREE;
12578   dest = CALL_EXPR_ARG (exp, 0);
12579   if (!validate_arg (dest, POINTER_TYPE))
12580     return NULL_TREE;
12581   flag = CALL_EXPR_ARG (exp, 1);
12582   if (!validate_arg (flag, INTEGER_TYPE))
12583     return NULL_TREE;
12584   size = CALL_EXPR_ARG (exp, 2);
12585   if (!validate_arg (size, INTEGER_TYPE))
12586     return NULL_TREE;
12587   fmt = CALL_EXPR_ARG (exp, 3);
12588   if (!validate_arg (fmt, POINTER_TYPE))
12589     return NULL_TREE;
12590
12591   if (! host_integerp (size, 1))
12592     return NULL_TREE;
12593
12594   len = NULL_TREE;
12595
12596   if (!init_target_chars ())
12597     return NULL_TREE;
12598
12599   /* Check whether the format is a literal string constant.  */
12600   fmt_str = c_getstr (fmt);
12601   if (fmt_str != NULL)
12602     {
12603       /* If the format doesn't contain % args or %%, we know the size.  */
12604       if (strchr (fmt_str, target_percent) == 0)
12605         {
12606           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
12607             len = build_int_cstu (size_type_node, strlen (fmt_str));
12608         }
12609       /* If the format is "%s" and first ... argument is a string literal,
12610          we know the size too.  */
12611       else if (fcode == BUILT_IN_SPRINTF_CHK
12612                && strcmp (fmt_str, target_percent_s) == 0)
12613         {
12614           tree arg;
12615
12616           if (nargs == 5)
12617             {
12618               arg = CALL_EXPR_ARG (exp, 4);
12619               if (validate_arg (arg, POINTER_TYPE))
12620                 {
12621                   len = c_strlen (arg, 1);
12622                   if (! len || ! host_integerp (len, 1))
12623                     len = NULL_TREE;
12624                 }
12625             }
12626         }
12627     }
12628
12629   if (! integer_all_onesp (size))
12630     {
12631       if (! len || ! tree_int_cst_lt (len, size))
12632         return NULL_TREE;
12633     }
12634
12635   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
12636      or if format doesn't contain % chars or is "%s".  */
12637   if (! integer_zerop (flag))
12638     {
12639       if (fmt_str == NULL)
12640         return NULL_TREE;
12641       if (strchr (fmt_str, target_percent) != NULL
12642           && strcmp (fmt_str, target_percent_s))
12643         return NULL_TREE;
12644     }
12645
12646   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
12647   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
12648                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
12649   if (!fn)
12650     return NULL_TREE;
12651
12652   return rewrite_call_expr (loc, exp, 4, fn, 2, dest, fmt);
12653 }
12654
12655 /* Fold a call EXP to {,v}snprintf.  Return NULL_TREE if
12656    a normal call should be emitted rather than expanding the function
12657    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
12658    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
12659    passed as second argument.  */
12660
12661 tree
12662 fold_builtin_snprintf_chk (location_t loc, tree exp, tree maxlen,
12663                            enum built_in_function fcode)
12664 {
12665   tree dest, size, len, fn, fmt, flag;
12666   const char *fmt_str;
12667
12668   /* Verify the required arguments in the original call.  */
12669   if (call_expr_nargs (exp) < 5)
12670     return NULL_TREE;
12671   dest = CALL_EXPR_ARG (exp, 0);
12672   if (!validate_arg (dest, POINTER_TYPE))
12673     return NULL_TREE;
12674   len = CALL_EXPR_ARG (exp, 1);
12675   if (!validate_arg (len, INTEGER_TYPE))
12676     return NULL_TREE;
12677   flag = CALL_EXPR_ARG (exp, 2);
12678   if (!validate_arg (flag, INTEGER_TYPE))
12679     return NULL_TREE;
12680   size = CALL_EXPR_ARG (exp, 3);
12681   if (!validate_arg (size, INTEGER_TYPE))
12682     return NULL_TREE;
12683   fmt = CALL_EXPR_ARG (exp, 4);
12684   if (!validate_arg (fmt, POINTER_TYPE))
12685     return NULL_TREE;
12686
12687   if (! host_integerp (size, 1))
12688     return NULL_TREE;
12689
12690   if (! integer_all_onesp (size))
12691     {
12692       if (! host_integerp (len, 1))
12693         {
12694           /* If LEN is not constant, try MAXLEN too.
12695              For MAXLEN only allow optimizing into non-_ocs function
12696              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
12697           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
12698             return NULL_TREE;
12699         }
12700       else
12701         maxlen = len;
12702
12703       if (tree_int_cst_lt (size, maxlen))
12704         return NULL_TREE;
12705     }
12706
12707   if (!init_target_chars ())
12708     return NULL_TREE;
12709
12710   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
12711      or if format doesn't contain % chars or is "%s".  */
12712   if (! integer_zerop (flag))
12713     {
12714       fmt_str = c_getstr (fmt);
12715       if (fmt_str == NULL)
12716         return NULL_TREE;
12717       if (strchr (fmt_str, target_percent) != NULL
12718           && strcmp (fmt_str, target_percent_s))
12719         return NULL_TREE;
12720     }
12721
12722   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
12723      available.  */
12724   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
12725                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
12726   if (!fn)
12727     return NULL_TREE;
12728
12729   return rewrite_call_expr (loc, exp, 5, fn, 3, dest, len, fmt);
12730 }
12731
12732 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
12733    FMT and ARG are the arguments to the call; we don't fold cases with
12734    more than 2 arguments, and ARG may be null if this is a 1-argument case.
12735
12736    Return NULL_TREE if no simplification was possible, otherwise return the
12737    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12738    code of the function to be simplified.  */
12739
12740 static tree
12741 fold_builtin_printf (location_t loc, tree fndecl, tree fmt,
12742                      tree arg, bool ignore,
12743                      enum built_in_function fcode)
12744 {
12745   tree fn_putchar, fn_puts, newarg, call = NULL_TREE;
12746   const char *fmt_str = NULL;
12747
12748   /* If the return value is used, don't do the transformation.  */
12749   if (! ignore)
12750     return NULL_TREE;
12751
12752   /* Verify the required arguments in the original call.  */
12753   if (!validate_arg (fmt, POINTER_TYPE))
12754     return NULL_TREE;
12755
12756   /* Check whether the format is a literal string constant.  */
12757   fmt_str = c_getstr (fmt);
12758   if (fmt_str == NULL)
12759     return NULL_TREE;
12760
12761   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
12762     {
12763       /* If we're using an unlocked function, assume the other
12764          unlocked functions exist explicitly.  */
12765       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
12766       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
12767     }
12768   else
12769     {
12770       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
12771       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
12772     }
12773
12774   if (!init_target_chars ())
12775     return NULL_TREE;
12776
12777   if (strcmp (fmt_str, target_percent_s) == 0
12778       || strchr (fmt_str, target_percent) == NULL)
12779     {
12780       const char *str;
12781
12782       if (strcmp (fmt_str, target_percent_s) == 0)
12783         {
12784           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12785             return NULL_TREE;
12786
12787           if (!arg || !validate_arg (arg, POINTER_TYPE))
12788             return NULL_TREE;
12789
12790           str = c_getstr (arg);
12791           if (str == NULL)
12792             return NULL_TREE;
12793         }
12794       else
12795         {
12796           /* The format specifier doesn't contain any '%' characters.  */
12797           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
12798               && arg)
12799             return NULL_TREE;
12800           str = fmt_str;
12801         }
12802
12803       /* If the string was "", printf does nothing.  */
12804       if (str[0] == '\0')
12805         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12806
12807       /* If the string has length of 1, call putchar.  */
12808       if (str[1] == '\0')
12809         {
12810           /* Given printf("c"), (where c is any one character,)
12811              convert "c"[0] to an int and pass that to the replacement
12812              function.  */
12813           newarg = build_int_cst (NULL_TREE, str[0]);
12814           if (fn_putchar)
12815             call = build_call_expr_loc (loc, fn_putchar, 1, newarg);
12816         }
12817       else
12818         {
12819           /* If the string was "string\n", call puts("string").  */
12820           size_t len = strlen (str);
12821           if ((unsigned char)str[len - 1] == target_newline)
12822             {
12823               /* Create a NUL-terminated string that's one char shorter
12824                  than the original, stripping off the trailing '\n'.  */
12825               char *newstr = XALLOCAVEC (char, len);
12826               memcpy (newstr, str, len - 1);
12827               newstr[len - 1] = 0;
12828
12829               newarg = build_string_literal (len, newstr);
12830               if (fn_puts)
12831                 call = build_call_expr_loc (loc, fn_puts, 1, newarg);
12832             }
12833           else
12834             /* We'd like to arrange to call fputs(string,stdout) here,
12835                but we need stdout and don't have a way to get it yet.  */
12836             return NULL_TREE;
12837         }
12838     }
12839
12840   /* The other optimizations can be done only on the non-va_list variants.  */
12841   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
12842     return NULL_TREE;
12843
12844   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
12845   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
12846     {
12847       if (!arg || !validate_arg (arg, POINTER_TYPE))
12848         return NULL_TREE;
12849       if (fn_puts)
12850         call = build_call_expr_loc (loc, fn_puts, 1, arg);
12851     }
12852
12853   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
12854   else if (strcmp (fmt_str, target_percent_c) == 0)
12855     {
12856       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12857         return NULL_TREE;
12858       if (fn_putchar)
12859         call = build_call_expr_loc (loc, fn_putchar, 1, arg);
12860     }
12861
12862   if (!call)
12863     return NULL_TREE;
12864
12865   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
12866 }
12867
12868 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
12869    FP, FMT, and ARG are the arguments to the call.  We don't fold calls with
12870    more than 3 arguments, and ARG may be null in the 2-argument case.
12871
12872    Return NULL_TREE if no simplification was possible, otherwise return the
12873    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
12874    code of the function to be simplified.  */
12875
12876 static tree
12877 fold_builtin_fprintf (location_t loc, tree fndecl, tree fp,
12878                       tree fmt, tree arg, bool ignore,
12879                       enum built_in_function fcode)
12880 {
12881   tree fn_fputc, fn_fputs, call = NULL_TREE;
12882   const char *fmt_str = NULL;
12883
12884   /* If the return value is used, don't do the transformation.  */
12885   if (! ignore)
12886     return NULL_TREE;
12887
12888   /* Verify the required arguments in the original call.  */
12889   if (!validate_arg (fp, POINTER_TYPE))
12890     return NULL_TREE;
12891   if (!validate_arg (fmt, POINTER_TYPE))
12892     return NULL_TREE;
12893
12894   /* Check whether the format is a literal string constant.  */
12895   fmt_str = c_getstr (fmt);
12896   if (fmt_str == NULL)
12897     return NULL_TREE;
12898
12899   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
12900     {
12901       /* If we're using an unlocked function, assume the other
12902          unlocked functions exist explicitly.  */
12903       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
12904       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
12905     }
12906   else
12907     {
12908       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
12909       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
12910     }
12911
12912   if (!init_target_chars ())
12913     return NULL_TREE;
12914
12915   /* If the format doesn't contain % args or %%, use strcpy.  */
12916   if (strchr (fmt_str, target_percent) == NULL)
12917     {
12918       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
12919           && arg)
12920         return NULL_TREE;
12921
12922       /* If the format specifier was "", fprintf does nothing.  */
12923       if (fmt_str[0] == '\0')
12924         {
12925           /* If FP has side-effects, just wait until gimplification is
12926              done.  */
12927           if (TREE_SIDE_EFFECTS (fp))
12928             return NULL_TREE;
12929
12930           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
12931         }
12932
12933       /* When "string" doesn't contain %, replace all cases of
12934          fprintf (fp, string) with fputs (string, fp).  The fputs
12935          builtin will take care of special cases like length == 1.  */
12936       if (fn_fputs)
12937         call = build_call_expr_loc (loc, fn_fputs, 2, fmt, fp);
12938     }
12939
12940   /* The other optimizations can be done only on the non-va_list variants.  */
12941   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
12942     return NULL_TREE;
12943
12944   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
12945   else if (strcmp (fmt_str, target_percent_s) == 0)
12946     {
12947       if (!arg || !validate_arg (arg, POINTER_TYPE))
12948         return NULL_TREE;
12949       if (fn_fputs)
12950         call = build_call_expr_loc (loc, fn_fputs, 2, arg, fp);
12951     }
12952
12953   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
12954   else if (strcmp (fmt_str, target_percent_c) == 0)
12955     {
12956       if (!arg || !validate_arg (arg, INTEGER_TYPE))
12957         return NULL_TREE;
12958       if (fn_fputc)
12959         call = build_call_expr_loc (loc, fn_fputc, 2, arg, fp);
12960     }
12961
12962   if (!call)
12963     return NULL_TREE;
12964   return fold_convert_loc (loc, TREE_TYPE (TREE_TYPE (fndecl)), call);
12965 }
12966
12967 /* Initialize format string characters in the target charset.  */
12968
12969 static bool
12970 init_target_chars (void)
12971 {
12972   static bool init;
12973   if (!init)
12974     {
12975       target_newline = lang_hooks.to_target_charset ('\n');
12976       target_percent = lang_hooks.to_target_charset ('%');
12977       target_c = lang_hooks.to_target_charset ('c');
12978       target_s = lang_hooks.to_target_charset ('s');
12979       if (target_newline == 0 || target_percent == 0 || target_c == 0
12980           || target_s == 0)
12981         return false;
12982
12983       target_percent_c[0] = target_percent;
12984       target_percent_c[1] = target_c;
12985       target_percent_c[2] = '\0';
12986
12987       target_percent_s[0] = target_percent;
12988       target_percent_s[1] = target_s;
12989       target_percent_s[2] = '\0';
12990
12991       target_percent_s_newline[0] = target_percent;
12992       target_percent_s_newline[1] = target_s;
12993       target_percent_s_newline[2] = target_newline;
12994       target_percent_s_newline[3] = '\0';
12995
12996       init = true;
12997     }
12998   return true;
12999 }
13000
13001 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
13002    and no overflow/underflow occurred.  INEXACT is true if M was not
13003    exactly calculated.  TYPE is the tree type for the result.  This
13004    function assumes that you cleared the MPFR flags and then
13005    calculated M to see if anything subsequently set a flag prior to
13006    entering this function.  Return NULL_TREE if any checks fail.  */
13007
13008 static tree
13009 do_mpfr_ckconv (mpfr_srcptr m, tree type, int inexact)
13010 {
13011   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13012      overflow/underflow occurred.  If -frounding-math, proceed iff the
13013      result of calling FUNC was exact.  */
13014   if (mpfr_number_p (m) && !mpfr_overflow_p () && !mpfr_underflow_p ()
13015       && (!flag_rounding_math || !inexact))
13016     {
13017       REAL_VALUE_TYPE rr;
13018
13019       real_from_mpfr (&rr, m, type, GMP_RNDN);
13020       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
13021          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13022          but the mpft_t is not, then we underflowed in the
13023          conversion.  */
13024       if (real_isfinite (&rr)
13025           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
13026         {
13027           REAL_VALUE_TYPE rmode;
13028
13029           real_convert (&rmode, TYPE_MODE (type), &rr);
13030           /* Proceed iff the specified mode can hold the value.  */
13031           if (real_identical (&rmode, &rr))
13032             return build_real (type, rmode);
13033         }
13034     }
13035   return NULL_TREE;
13036 }
13037
13038 #ifdef HAVE_mpc
13039 /* Helper function for do_mpc_arg*().  Ensure M is a normal complex
13040    number and no overflow/underflow occurred.  INEXACT is true if M
13041    was not exactly calculated.  TYPE is the tree type for the result.
13042    This function assumes that you cleared the MPFR flags and then
13043    calculated M to see if anything subsequently set a flag prior to
13044    entering this function.  Return NULL_TREE if any checks fail, if
13045    FORCE_CONVERT is true, then bypass the checks.  */
13046
13047 static tree
13048 do_mpc_ckconv (mpc_srcptr m, tree type, int inexact, int force_convert)
13049 {
13050   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
13051      overflow/underflow occurred.  If -frounding-math, proceed iff the
13052      result of calling FUNC was exact.  */
13053   if (force_convert
13054       || (mpfr_number_p (mpc_realref (m)) && mpfr_number_p (mpc_imagref (m))
13055           && !mpfr_overflow_p () && !mpfr_underflow_p ()
13056           && (!flag_rounding_math || !inexact)))
13057     {
13058       REAL_VALUE_TYPE re, im;
13059
13060       real_from_mpfr (&re, mpc_realref (m), type, GMP_RNDN);
13061       real_from_mpfr (&im, mpc_imagref (m), type, GMP_RNDN);
13062       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR values,
13063          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
13064          but the mpft_t is not, then we underflowed in the
13065          conversion.  */
13066       if (force_convert
13067           || (real_isfinite (&re) && real_isfinite (&im)
13068               && (re.cl == rvc_zero) == (mpfr_zero_p (mpc_realref (m)) != 0)
13069               && (im.cl == rvc_zero) == (mpfr_zero_p (mpc_imagref (m)) != 0)))
13070         {
13071           REAL_VALUE_TYPE re_mode, im_mode;
13072
13073           real_convert (&re_mode, TYPE_MODE (TREE_TYPE (type)), &re);
13074           real_convert (&im_mode, TYPE_MODE (TREE_TYPE (type)), &im);
13075           /* Proceed iff the specified mode can hold the value.  */
13076           if (force_convert
13077               || (real_identical (&re_mode, &re)
13078                   && real_identical (&im_mode, &im)))
13079             return build_complex (type, build_real (TREE_TYPE (type), re_mode),
13080                                   build_real (TREE_TYPE (type), im_mode));
13081         }
13082     }
13083   return NULL_TREE;
13084 }
13085 #endif /* HAVE_mpc */
13086
13087 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
13088    FUNC on it and return the resulting value as a tree with type TYPE.
13089    If MIN and/or MAX are not NULL, then the supplied ARG must be
13090    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
13091    acceptable values, otherwise they are not.  The mpfr precision is
13092    set to the precision of TYPE.  We assume that function FUNC returns
13093    zero if the result could be calculated exactly within the requested
13094    precision.  */
13095
13096 static tree
13097 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
13098               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
13099               bool inclusive)
13100 {
13101   tree result = NULL_TREE;
13102   
13103   STRIP_NOPS (arg);
13104
13105   /* To proceed, MPFR must exactly represent the target floating point
13106      format, which only happens when the target base equals two.  */
13107   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13108       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg))
13109     {
13110       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13111
13112       if (real_isfinite (ra)
13113           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
13114           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
13115         {
13116           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13117           const int prec = fmt->p;
13118           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13119           int inexact;
13120           mpfr_t m;
13121
13122           mpfr_init2 (m, prec);
13123           mpfr_from_real (m, ra, GMP_RNDN);
13124           mpfr_clear_flags ();
13125           inexact = func (m, m, rnd);
13126           result = do_mpfr_ckconv (m, type, inexact);
13127           mpfr_clear (m);
13128         }
13129     }
13130   
13131   return result;
13132 }
13133
13134 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
13135    FUNC on it and return the resulting value as a tree with type TYPE.
13136    The mpfr precision is set to the precision of TYPE.  We assume that
13137    function FUNC returns zero if the result could be calculated
13138    exactly within the requested precision.  */
13139
13140 static tree
13141 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
13142               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13143 {
13144   tree result = NULL_TREE;
13145   
13146   STRIP_NOPS (arg1);
13147   STRIP_NOPS (arg2);
13148
13149   /* To proceed, MPFR must exactly represent the target floating point
13150      format, which only happens when the target base equals two.  */
13151   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13152       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13153       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13154     {
13155       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13156       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13157
13158       if (real_isfinite (ra1) && real_isfinite (ra2))
13159         {
13160           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13161           const int prec = fmt->p;
13162           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13163           int inexact;
13164           mpfr_t m1, m2;
13165
13166           mpfr_inits2 (prec, m1, m2, NULL);
13167           mpfr_from_real (m1, ra1, GMP_RNDN);
13168           mpfr_from_real (m2, ra2, GMP_RNDN);
13169           mpfr_clear_flags ();
13170           inexact = func (m1, m1, m2, rnd);
13171           result = do_mpfr_ckconv (m1, type, inexact);
13172           mpfr_clears (m1, m2, NULL);
13173         }
13174     }
13175   
13176   return result;
13177 }
13178
13179 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
13180    FUNC on it and return the resulting value as a tree with type TYPE.
13181    The mpfr precision is set to the precision of TYPE.  We assume that
13182    function FUNC returns zero if the result could be calculated
13183    exactly within the requested precision.  */
13184
13185 static tree
13186 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
13187               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
13188 {
13189   tree result = NULL_TREE;
13190   
13191   STRIP_NOPS (arg1);
13192   STRIP_NOPS (arg2);
13193   STRIP_NOPS (arg3);
13194
13195   /* To proceed, MPFR must exactly represent the target floating point
13196      format, which only happens when the target base equals two.  */
13197   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13198       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1)
13199       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2)
13200       && TREE_CODE (arg3) == REAL_CST && !TREE_OVERFLOW (arg3))
13201     {
13202       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
13203       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
13204       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
13205
13206       if (real_isfinite (ra1) && real_isfinite (ra2) && real_isfinite (ra3))
13207         {
13208           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13209           const int prec = fmt->p;
13210           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13211           int inexact;
13212           mpfr_t m1, m2, m3;
13213
13214           mpfr_inits2 (prec, m1, m2, m3, NULL);
13215           mpfr_from_real (m1, ra1, GMP_RNDN);
13216           mpfr_from_real (m2, ra2, GMP_RNDN);
13217           mpfr_from_real (m3, ra3, GMP_RNDN);
13218           mpfr_clear_flags ();
13219           inexact = func (m1, m1, m2, m3, rnd);
13220           result = do_mpfr_ckconv (m1, type, inexact);
13221           mpfr_clears (m1, m2, m3, NULL);
13222         }
13223     }
13224   
13225   return result;
13226 }
13227
13228 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
13229    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
13230    If ARG_SINP and ARG_COSP are NULL then the result is returned
13231    as a complex value.
13232    The type is taken from the type of ARG and is used for setting the
13233    precision of the calculation and results.  */
13234
13235 static tree
13236 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
13237 {
13238   tree const type = TREE_TYPE (arg);
13239   tree result = NULL_TREE;
13240   
13241   STRIP_NOPS (arg);
13242   
13243   /* To proceed, MPFR must exactly represent the target floating point
13244      format, which only happens when the target base equals two.  */
13245   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13246       && TREE_CODE (arg) == REAL_CST
13247       && !TREE_OVERFLOW (arg))
13248     {
13249       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
13250
13251       if (real_isfinite (ra))
13252         {
13253           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13254           const int prec = fmt->p;
13255           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13256           tree result_s, result_c;
13257           int inexact;
13258           mpfr_t m, ms, mc;
13259
13260           mpfr_inits2 (prec, m, ms, mc, NULL);
13261           mpfr_from_real (m, ra, GMP_RNDN);
13262           mpfr_clear_flags ();
13263           inexact = mpfr_sin_cos (ms, mc, m, rnd);
13264           result_s = do_mpfr_ckconv (ms, type, inexact);
13265           result_c = do_mpfr_ckconv (mc, type, inexact);
13266           mpfr_clears (m, ms, mc, NULL);
13267           if (result_s && result_c)
13268             {
13269               /* If we are to return in a complex value do so.  */
13270               if (!arg_sinp && !arg_cosp)
13271                 return build_complex (build_complex_type (type),
13272                                       result_c, result_s);
13273
13274               /* Dereference the sin/cos pointer arguments.  */
13275               arg_sinp = build_fold_indirect_ref (arg_sinp);
13276               arg_cosp = build_fold_indirect_ref (arg_cosp);
13277               /* Proceed if valid pointer type were passed in.  */
13278               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
13279                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
13280                 {
13281                   /* Set the values. */
13282                   result_s = fold_build2 (MODIFY_EXPR, type, arg_sinp,
13283                                           result_s);
13284                   TREE_SIDE_EFFECTS (result_s) = 1;
13285                   result_c = fold_build2 (MODIFY_EXPR, type, arg_cosp,
13286                                           result_c);
13287                   TREE_SIDE_EFFECTS (result_c) = 1;
13288                   /* Combine the assignments into a compound expr.  */
13289                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13290                                                     result_s, result_c));
13291                 }
13292             }
13293         }
13294     }
13295   return result;
13296 }
13297
13298 /* If argument ARG1 is an INTEGER_CST and ARG2 is a REAL_CST, call the
13299    two-argument mpfr order N Bessel function FUNC on them and return
13300    the resulting value as a tree with type TYPE.  The mpfr precision
13301    is set to the precision of TYPE.  We assume that function FUNC
13302    returns zero if the result could be calculated exactly within the
13303    requested precision.  */
13304 static tree
13305 do_mpfr_bessel_n (tree arg1, tree arg2, tree type,
13306                   int (*func)(mpfr_ptr, long, mpfr_srcptr, mp_rnd_t),
13307                   const REAL_VALUE_TYPE *min, bool inclusive)
13308 {
13309   tree result = NULL_TREE;
13310
13311   STRIP_NOPS (arg1);
13312   STRIP_NOPS (arg2);
13313
13314   /* To proceed, MPFR must exactly represent the target floating point
13315      format, which only happens when the target base equals two.  */
13316   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13317       && host_integerp (arg1, 0)
13318       && TREE_CODE (arg2) == REAL_CST && !TREE_OVERFLOW (arg2))
13319     {
13320       const HOST_WIDE_INT n = tree_low_cst(arg1, 0);
13321       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg2);
13322
13323       if (n == (long)n
13324           && real_isfinite (ra)
13325           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min)))
13326         {
13327           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13328           const int prec = fmt->p;
13329           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13330           int inexact;
13331           mpfr_t m;
13332
13333           mpfr_init2 (m, prec);
13334           mpfr_from_real (m, ra, GMP_RNDN);
13335           mpfr_clear_flags ();
13336           inexact = func (m, n, m, rnd);
13337           result = do_mpfr_ckconv (m, type, inexact);
13338           mpfr_clear (m);
13339         }
13340     }
13341   
13342   return result;
13343 }
13344
13345 /* If arguments ARG0 and ARG1 are REAL_CSTs, call mpfr_remquo() to set
13346    the pointer *(ARG_QUO) and return the result.  The type is taken
13347    from the type of ARG0 and is used for setting the precision of the
13348    calculation and results.  */
13349
13350 static tree
13351 do_mpfr_remquo (tree arg0, tree arg1, tree arg_quo)
13352 {
13353   tree const type = TREE_TYPE (arg0);
13354   tree result = NULL_TREE;
13355   
13356   STRIP_NOPS (arg0);
13357   STRIP_NOPS (arg1);
13358   
13359   /* To proceed, MPFR must exactly represent the target floating point
13360      format, which only happens when the target base equals two.  */
13361   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13362       && TREE_CODE (arg0) == REAL_CST && !TREE_OVERFLOW (arg0)
13363       && TREE_CODE (arg1) == REAL_CST && !TREE_OVERFLOW (arg1))
13364     {
13365       const REAL_VALUE_TYPE *const ra0 = TREE_REAL_CST_PTR (arg0);
13366       const REAL_VALUE_TYPE *const ra1 = TREE_REAL_CST_PTR (arg1);
13367
13368       if (real_isfinite (ra0) && real_isfinite (ra1))
13369         {
13370           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13371           const int prec = fmt->p;
13372           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13373           tree result_rem;
13374           long integer_quo;
13375           mpfr_t m0, m1;
13376
13377           mpfr_inits2 (prec, m0, m1, NULL);
13378           mpfr_from_real (m0, ra0, GMP_RNDN);
13379           mpfr_from_real (m1, ra1, GMP_RNDN);
13380           mpfr_clear_flags ();
13381           mpfr_remquo (m0, &integer_quo, m0, m1, rnd);
13382           /* Remquo is independent of the rounding mode, so pass
13383              inexact=0 to do_mpfr_ckconv().  */
13384           result_rem = do_mpfr_ckconv (m0, type, /*inexact=*/ 0);
13385           mpfr_clears (m0, m1, NULL);
13386           if (result_rem)
13387             {
13388               /* MPFR calculates quo in the host's long so it may
13389                  return more bits in quo than the target int can hold
13390                  if sizeof(host long) > sizeof(target int).  This can
13391                  happen even for native compilers in LP64 mode.  In
13392                  these cases, modulo the quo value with the largest
13393                  number that the target int can hold while leaving one
13394                  bit for the sign.  */
13395               if (sizeof (integer_quo) * CHAR_BIT > INT_TYPE_SIZE)
13396                 integer_quo %= (long)(1UL << (INT_TYPE_SIZE - 1));
13397
13398               /* Dereference the quo pointer argument.  */
13399               arg_quo = build_fold_indirect_ref (arg_quo);
13400               /* Proceed iff a valid pointer type was passed in.  */
13401               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_quo)) == integer_type_node)
13402                 {
13403                   /* Set the value. */
13404                   tree result_quo = fold_build2 (MODIFY_EXPR,
13405                                                  TREE_TYPE (arg_quo), arg_quo,
13406                                                  build_int_cst (NULL, integer_quo));
13407                   TREE_SIDE_EFFECTS (result_quo) = 1;
13408                   /* Combine the quo assignment with the rem.  */
13409                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13410                                                     result_quo, result_rem));
13411                 }
13412             }
13413         }
13414     }
13415   return result;
13416 }
13417
13418 /* If ARG is a REAL_CST, call mpfr_lgamma() on it and return the
13419    resulting value as a tree with type TYPE.  The mpfr precision is
13420    set to the precision of TYPE.  We assume that this mpfr function
13421    returns zero if the result could be calculated exactly within the
13422    requested precision.  In addition, the integer pointer represented
13423    by ARG_SG will be dereferenced and set to the appropriate signgam
13424    (-1,1) value.  */
13425
13426 static tree
13427 do_mpfr_lgamma_r (tree arg, tree arg_sg, tree type)
13428 {
13429   tree result = NULL_TREE;
13430
13431   STRIP_NOPS (arg);
13432   
13433   /* To proceed, MPFR must exactly represent the target floating point
13434      format, which only happens when the target base equals two.  Also
13435      verify ARG is a constant and that ARG_SG is an int pointer.  */
13436   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
13437       && TREE_CODE (arg) == REAL_CST && !TREE_OVERFLOW (arg)
13438       && TREE_CODE (TREE_TYPE (arg_sg)) == POINTER_TYPE
13439       && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg_sg))) == integer_type_node)
13440     {
13441       const REAL_VALUE_TYPE *const ra = TREE_REAL_CST_PTR (arg);
13442
13443       /* In addition to NaN and Inf, the argument cannot be zero or a
13444          negative integer.  */
13445       if (real_isfinite (ra)
13446           && ra->cl != rvc_zero
13447           && !(real_isneg(ra) && real_isinteger(ra, TYPE_MODE (type))))
13448         {
13449           const struct real_format *fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
13450           const int prec = fmt->p;
13451           const mp_rnd_t rnd = fmt->round_towards_zero? GMP_RNDZ : GMP_RNDN;
13452           int inexact, sg;
13453           mpfr_t m;
13454           tree result_lg;
13455
13456           mpfr_init2 (m, prec);
13457           mpfr_from_real (m, ra, GMP_RNDN);
13458           mpfr_clear_flags ();
13459           inexact = mpfr_lgamma (m, &sg, m, rnd);
13460           result_lg = do_mpfr_ckconv (m, type, inexact);
13461           mpfr_clear (m);
13462           if (result_lg)
13463             {
13464               tree result_sg;
13465
13466               /* Dereference the arg_sg pointer argument.  */
13467               arg_sg = build_fold_indirect_ref (arg_sg);
13468               /* Assign the signgam value into *arg_sg. */
13469               result_sg = fold_build2 (MODIFY_EXPR,
13470                                        TREE_TYPE (arg_sg), arg_sg,
13471                                        build_int_cst (NULL, sg));
13472               TREE_SIDE_EFFECTS (result_sg) = 1;
13473               /* Combine the signgam assignment with the lgamma result.  */
13474               result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
13475                                                 result_sg, result_lg));
13476             }
13477         }
13478     }
13479
13480   return result;
13481 }
13482
13483 #ifdef HAVE_mpc
13484 /* If argument ARG is a COMPLEX_CST, call the one-argument mpc
13485    function FUNC on it and return the resulting value as a tree with
13486    type TYPE.  The mpfr precision is set to the precision of TYPE.  We
13487    assume that function FUNC returns zero if the result could be
13488    calculated exactly within the requested precision.  */
13489
13490 static tree
13491 do_mpc_arg1 (tree arg, tree type, int (*func)(mpc_ptr, mpc_srcptr, mpc_rnd_t))
13492 {
13493   tree result = NULL_TREE;
13494   
13495   STRIP_NOPS (arg);
13496
13497   /* To proceed, MPFR must exactly represent the target floating point
13498      format, which only happens when the target base equals two.  */
13499   if (TREE_CODE (arg) == COMPLEX_CST && !TREE_OVERFLOW (arg)
13500       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == REAL_TYPE
13501       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg))))->b == 2)
13502     {
13503       const REAL_VALUE_TYPE *const re = TREE_REAL_CST_PTR (TREE_REALPART (arg));
13504       const REAL_VALUE_TYPE *const im = TREE_REAL_CST_PTR (TREE_IMAGPART (arg));
13505
13506       if (real_isfinite (re) && real_isfinite (im))
13507         {
13508           const struct real_format *const fmt =
13509             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13510           const int prec = fmt->p;
13511           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13512           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13513           int inexact;
13514           mpc_t m;
13515           
13516           mpc_init2 (m, prec);
13517           mpfr_from_real (mpc_realref(m), re, rnd);
13518           mpfr_from_real (mpc_imagref(m), im, rnd);
13519           mpfr_clear_flags ();
13520           inexact = func (m, m, crnd);
13521           result = do_mpc_ckconv (m, type, inexact, /*force_convert=*/ 0);
13522           mpc_clear (m);
13523         }
13524     }
13525
13526   return result;
13527 }
13528
13529 /* If arguments ARG0 and ARG1 are a COMPLEX_CST, call the two-argument
13530    mpc function FUNC on it and return the resulting value as a tree
13531    with type TYPE.  The mpfr precision is set to the precision of
13532    TYPE.  We assume that function FUNC returns zero if the result
13533    could be calculated exactly within the requested precision.  If
13534    DO_NONFINITE is true, then fold expressions containing Inf or NaN
13535    in the arguments and/or results.  */
13536
13537 #ifdef HAVE_mpc
13538 tree
13539 do_mpc_arg2 (tree arg0, tree arg1, tree type, int do_nonfinite,
13540              int (*func)(mpc_ptr, mpc_srcptr, mpc_srcptr, mpc_rnd_t))
13541 {
13542   tree result = NULL_TREE;
13543   
13544   STRIP_NOPS (arg0);
13545   STRIP_NOPS (arg1);
13546
13547   /* To proceed, MPFR must exactly represent the target floating point
13548      format, which only happens when the target base equals two.  */
13549   if (TREE_CODE (arg0) == COMPLEX_CST && !TREE_OVERFLOW (arg0)
13550       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE
13551       && TREE_CODE (arg1) == COMPLEX_CST && !TREE_OVERFLOW (arg1)
13552       && TREE_CODE (TREE_TYPE (TREE_TYPE (arg1))) == REAL_TYPE
13553       && REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0))))->b == 2)
13554     {
13555       const REAL_VALUE_TYPE *const re0 = TREE_REAL_CST_PTR (TREE_REALPART (arg0));
13556       const REAL_VALUE_TYPE *const im0 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg0));
13557       const REAL_VALUE_TYPE *const re1 = TREE_REAL_CST_PTR (TREE_REALPART (arg1));
13558       const REAL_VALUE_TYPE *const im1 = TREE_REAL_CST_PTR (TREE_IMAGPART (arg1));
13559
13560       if (do_nonfinite
13561           || (real_isfinite (re0) && real_isfinite (im0)
13562               && real_isfinite (re1) && real_isfinite (im1)))
13563         {
13564           const struct real_format *const fmt =
13565             REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (type)));
13566           const int prec = fmt->p;
13567           const mp_rnd_t rnd = fmt->round_towards_zero ? GMP_RNDZ : GMP_RNDN;
13568           const mpc_rnd_t crnd = fmt->round_towards_zero ? MPC_RNDZZ : MPC_RNDNN;
13569           int inexact;
13570           mpc_t m0, m1;
13571           
13572           mpc_init2 (m0, prec);
13573           mpc_init2 (m1, prec);
13574           mpfr_from_real (mpc_realref(m0), re0, rnd);
13575           mpfr_from_real (mpc_imagref(m0), im0, rnd);
13576           mpfr_from_real (mpc_realref(m1), re1, rnd);
13577           mpfr_from_real (mpc_imagref(m1), im1, rnd);
13578           mpfr_clear_flags ();
13579           inexact = func (m0, m0, m1, crnd);
13580           result = do_mpc_ckconv (m0, type, inexact, do_nonfinite);
13581           mpc_clear (m0);
13582           mpc_clear (m1);
13583         }
13584     }
13585
13586   return result;
13587 }
13588 # endif
13589 #endif /* HAVE_mpc */
13590
13591 /* FIXME tuples.
13592    The functions below provide an alternate interface for folding
13593    builtin function calls presented as GIMPLE_CALL statements rather
13594    than as CALL_EXPRs.  The folded result is still expressed as a
13595    tree.  There is too much code duplication in the handling of
13596    varargs functions, and a more intrusive re-factoring would permit
13597    better sharing of code between the tree and statement-based
13598    versions of these functions.  */
13599
13600 /* Construct a new CALL_EXPR using the tail of the argument list of STMT
13601    along with N new arguments specified as the "..." parameters.  SKIP
13602    is the number of arguments in STMT to be omitted.  This function is used
13603    to do varargs-to-varargs transformations.  */
13604
13605 static tree
13606 gimple_rewrite_call_expr (gimple stmt, int skip, tree fndecl, int n, ...)
13607 {
13608   int oldnargs = gimple_call_num_args (stmt);
13609   int nargs = oldnargs - skip + n;
13610   tree fntype = TREE_TYPE (fndecl);
13611   tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
13612   tree *buffer;
13613   int i, j;
13614   va_list ap;
13615   location_t loc = gimple_location (stmt);
13616
13617   buffer = XALLOCAVEC (tree, nargs);
13618   va_start (ap, n);
13619   for (i = 0; i < n; i++)
13620     buffer[i] = va_arg (ap, tree);
13621   va_end (ap);
13622   for (j = skip; j < oldnargs; j++, i++)
13623     buffer[i] = gimple_call_arg (stmt, j);
13624
13625   return fold (build_call_array_loc (loc, TREE_TYPE (fntype), fn, nargs, buffer));
13626 }
13627
13628 /* Fold a call STMT to __{,v}sprintf_chk.  Return NULL_TREE if
13629    a normal call should be emitted rather than expanding the function
13630    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
13631
13632 static tree
13633 gimple_fold_builtin_sprintf_chk (gimple stmt, enum built_in_function fcode)
13634 {
13635   tree dest, size, len, fn, fmt, flag;
13636   const char *fmt_str;
13637   int nargs = gimple_call_num_args (stmt);
13638
13639   /* Verify the required arguments in the original call.  */
13640   if (nargs < 4)
13641     return NULL_TREE;
13642   dest = gimple_call_arg (stmt, 0);
13643   if (!validate_arg (dest, POINTER_TYPE))
13644     return NULL_TREE;
13645   flag = gimple_call_arg (stmt, 1);
13646   if (!validate_arg (flag, INTEGER_TYPE))
13647     return NULL_TREE;
13648   size = gimple_call_arg (stmt, 2);
13649   if (!validate_arg (size, INTEGER_TYPE))
13650     return NULL_TREE;
13651   fmt = gimple_call_arg (stmt, 3);
13652   if (!validate_arg (fmt, POINTER_TYPE))
13653     return NULL_TREE;
13654
13655   if (! host_integerp (size, 1))
13656     return NULL_TREE;
13657
13658   len = NULL_TREE;
13659
13660   if (!init_target_chars ())
13661     return NULL_TREE;
13662
13663   /* Check whether the format is a literal string constant.  */
13664   fmt_str = c_getstr (fmt);
13665   if (fmt_str != NULL)
13666     {
13667       /* If the format doesn't contain % args or %%, we know the size.  */
13668       if (strchr (fmt_str, target_percent) == 0)
13669         {
13670           if (fcode != BUILT_IN_SPRINTF_CHK || nargs == 4)
13671             len = build_int_cstu (size_type_node, strlen (fmt_str));
13672         }
13673       /* If the format is "%s" and first ... argument is a string literal,
13674          we know the size too.  */
13675       else if (fcode == BUILT_IN_SPRINTF_CHK
13676                && strcmp (fmt_str, target_percent_s) == 0)
13677         {
13678           tree arg;
13679
13680           if (nargs == 5)
13681             {
13682               arg = gimple_call_arg (stmt, 4);
13683               if (validate_arg (arg, POINTER_TYPE))
13684                 {
13685                   len = c_strlen (arg, 1);
13686                   if (! len || ! host_integerp (len, 1))
13687                     len = NULL_TREE;
13688                 }
13689             }
13690         }
13691     }
13692
13693   if (! integer_all_onesp (size))
13694     {
13695       if (! len || ! tree_int_cst_lt (len, size))
13696         return NULL_TREE;
13697     }
13698
13699   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
13700      or if format doesn't contain % chars or is "%s".  */
13701   if (! integer_zerop (flag))
13702     {
13703       if (fmt_str == NULL)
13704         return NULL_TREE;
13705       if (strchr (fmt_str, target_percent) != NULL
13706           && strcmp (fmt_str, target_percent_s))
13707         return NULL_TREE;
13708     }
13709
13710   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
13711   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
13712                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
13713   if (!fn)
13714     return NULL_TREE;
13715
13716   return gimple_rewrite_call_expr (stmt, 4, fn, 2, dest, fmt);
13717 }
13718
13719 /* Fold a call STMT to {,v}snprintf.  Return NULL_TREE if
13720    a normal call should be emitted rather than expanding the function
13721    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
13722    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
13723    passed as second argument.  */
13724
13725 tree
13726 gimple_fold_builtin_snprintf_chk (gimple stmt, tree maxlen,
13727                                   enum built_in_function fcode)
13728 {
13729   tree dest, size, len, fn, fmt, flag;
13730   const char *fmt_str;
13731
13732   /* Verify the required arguments in the original call.  */
13733   if (gimple_call_num_args (stmt) < 5)
13734     return NULL_TREE;
13735   dest = gimple_call_arg (stmt, 0);
13736   if (!validate_arg (dest, POINTER_TYPE))
13737     return NULL_TREE;
13738   len = gimple_call_arg (stmt, 1);
13739   if (!validate_arg (len, INTEGER_TYPE))
13740     return NULL_TREE;
13741   flag = gimple_call_arg (stmt, 2);
13742   if (!validate_arg (flag, INTEGER_TYPE))
13743     return NULL_TREE;
13744   size = gimple_call_arg (stmt, 3);
13745   if (!validate_arg (size, INTEGER_TYPE))
13746     return NULL_TREE;
13747   fmt = gimple_call_arg (stmt, 4);
13748   if (!validate_arg (fmt, POINTER_TYPE))
13749     return NULL_TREE;
13750
13751   if (! host_integerp (size, 1))
13752     return NULL_TREE;
13753
13754   if (! integer_all_onesp (size))
13755     {
13756       if (! host_integerp (len, 1))
13757         {
13758           /* If LEN is not constant, try MAXLEN too.
13759              For MAXLEN only allow optimizing into non-_ocs function
13760              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
13761           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
13762             return NULL_TREE;
13763         }
13764       else
13765         maxlen = len;
13766
13767       if (tree_int_cst_lt (size, maxlen))
13768         return NULL_TREE;
13769     }
13770
13771   if (!init_target_chars ())
13772     return NULL_TREE;
13773
13774   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
13775      or if format doesn't contain % chars or is "%s".  */
13776   if (! integer_zerop (flag))
13777     {
13778       fmt_str = c_getstr (fmt);
13779       if (fmt_str == NULL)
13780         return NULL_TREE;
13781       if (strchr (fmt_str, target_percent) != NULL
13782           && strcmp (fmt_str, target_percent_s))
13783         return NULL_TREE;
13784     }
13785
13786   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
13787      available.  */
13788   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
13789                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
13790   if (!fn)
13791     return NULL_TREE;
13792
13793   return gimple_rewrite_call_expr (stmt, 5, fn, 3, dest, len, fmt);
13794 }
13795
13796 /* Builtins with folding operations that operate on "..." arguments
13797    need special handling; we need to store the arguments in a convenient
13798    data structure before attempting any folding.  Fortunately there are
13799    only a few builtins that fall into this category.  FNDECL is the
13800    function, EXP is the CALL_EXPR for the call, and IGNORE is true if the
13801    result of the function call is ignored.  */
13802
13803 static tree
13804 gimple_fold_builtin_varargs (tree fndecl, gimple stmt,
13805                              bool ignore ATTRIBUTE_UNUSED)
13806 {
13807   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
13808   tree ret = NULL_TREE;
13809
13810   switch (fcode)
13811     {
13812     case BUILT_IN_SPRINTF_CHK:
13813     case BUILT_IN_VSPRINTF_CHK:
13814       ret = gimple_fold_builtin_sprintf_chk (stmt, fcode);
13815       break;
13816
13817     case BUILT_IN_SNPRINTF_CHK:
13818     case BUILT_IN_VSNPRINTF_CHK:
13819       ret = gimple_fold_builtin_snprintf_chk (stmt, NULL_TREE, fcode);
13820
13821     default:
13822       break;
13823     }
13824   if (ret)
13825     {
13826       ret = build1 (NOP_EXPR, TREE_TYPE (ret), ret);
13827       TREE_NO_WARNING (ret) = 1;
13828       return ret;
13829     }
13830   return NULL_TREE;
13831 }
13832
13833 /* A wrapper function for builtin folding that prevents warnings for
13834    "statement without effect" and the like, caused by removing the
13835    call node earlier than the warning is generated.  */
13836
13837 tree
13838 fold_call_stmt (gimple stmt, bool ignore)
13839 {
13840   tree ret = NULL_TREE;
13841   tree fndecl = gimple_call_fndecl (stmt);
13842   location_t loc = gimple_location (stmt);
13843   if (fndecl
13844       && TREE_CODE (fndecl) == FUNCTION_DECL
13845       && DECL_BUILT_IN (fndecl)
13846       && !gimple_call_va_arg_pack_p (stmt))
13847     {
13848       int nargs = gimple_call_num_args (stmt);
13849
13850       if (avoid_folding_inline_builtin (fndecl))
13851         return NULL_TREE;
13852       /* FIXME: Don't use a list in this interface.  */
13853       if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
13854         {
13855           tree arglist = NULL_TREE;
13856           int i;
13857           for (i = nargs - 1; i >= 0; i--)
13858             arglist = tree_cons (NULL_TREE, gimple_call_arg (stmt, i), arglist);
13859           return targetm.fold_builtin (fndecl, arglist, ignore);
13860         }
13861       else
13862         {
13863           if (nargs <= MAX_ARGS_TO_FOLD_BUILTIN)
13864             {
13865               tree args[MAX_ARGS_TO_FOLD_BUILTIN];
13866               int i;
13867               for (i = 0; i < nargs; i++)
13868                 args[i] = gimple_call_arg (stmt, i);
13869               ret = fold_builtin_n (loc, fndecl, args, nargs, ignore);
13870             }
13871           if (!ret)
13872             ret = gimple_fold_builtin_varargs (fndecl, stmt, ignore);
13873           if (ret)
13874             {
13875               /* Propagate location information from original call to
13876                  expansion of builtin.  Otherwise things like
13877                  maybe_emit_chk_warning, that operate on the expansion
13878                  of a builtin, will use the wrong location information.  */
13879               if (gimple_has_location (stmt))
13880                 {
13881                   tree realret = ret;
13882                   if (TREE_CODE (ret) == NOP_EXPR)
13883                     realret = TREE_OPERAND (ret, 0);
13884                   if (CAN_HAVE_LOCATION_P (realret)
13885                       && !EXPR_HAS_LOCATION (realret))
13886                     SET_EXPR_LOCATION (realret, loc);
13887                   return realret;
13888                 }
13889               return ret;
13890             }
13891         }
13892     }
13893   return NULL_TREE;
13894 }
13895
13896 /* Look up the function in built_in_decls that corresponds to DECL
13897    and set ASMSPEC as its user assembler name.  DECL must be a
13898    function decl that declares a builtin.  */
13899
13900 void
13901 set_builtin_user_assembler_name (tree decl, const char *asmspec)
13902 {
13903   tree builtin;
13904   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
13905               && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
13906               && asmspec != 0);
13907
13908   builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
13909   set_user_assembler_name (builtin, asmspec);
13910   switch (DECL_FUNCTION_CODE (decl))
13911     {
13912     case BUILT_IN_MEMCPY:
13913       init_block_move_fn (asmspec);
13914       memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
13915       break;
13916     case BUILT_IN_MEMSET:
13917       init_block_clear_fn (asmspec);
13918       memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
13919       break;
13920     case BUILT_IN_MEMMOVE:
13921       memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
13922       break;
13923     case BUILT_IN_MEMCMP:
13924       memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
13925       break;
13926     case BUILT_IN_ABORT:
13927       abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
13928       break;
13929     default:
13930       break;
13931     }
13932 }