OSDN Git Service

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