OSDN Git Service

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