OSDN Git Service

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