OSDN Git Service

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