OSDN Git Service

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