OSDN Git Service

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