OSDN Git Service

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