OSDN Git Service

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