OSDN Git Service

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