OSDN Git Service

PR middle-end/29335
[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 cexp, cexpf, or cexpl.  Return
7371    NULL_TREE if no simplification can be made.  */
7372
7373 static tree
7374 fold_builtin_cexp (tree arglist, tree type)
7375 {
7376   tree arg0, rtype;
7377   tree realp, imagp, ifn;
7378
7379   if (!validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7380     return NULL_TREE;
7381
7382   arg0 = TREE_VALUE (arglist);
7383   rtype = TREE_TYPE (TREE_TYPE (arg0));
7384
7385   /* In case we can figure out the real part of arg0 and it is constant zero
7386      fold to cexpi.  */
7387   ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
7388   if (!ifn)
7389     return NULL_TREE;
7390
7391   if ((realp = fold_unary (REALPART_EXPR, rtype, arg0))
7392       && real_zerop (realp))
7393     {
7394       tree narg = fold_build1 (IMAGPART_EXPR, rtype, arg0);
7395       return build_function_call_expr (ifn, build_tree_list (NULL_TREE, narg));
7396     }
7397
7398   /* In case we can easily decompose real and imaginary parts split cexp
7399      to exp (r) * cexpi (i).  */
7400   if (flag_unsafe_math_optimizations
7401       && realp)
7402     {
7403       tree rfn, rcall, icall;
7404
7405       rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
7406       if (!rfn)
7407         return NULL_TREE;
7408
7409       imagp = fold_unary (IMAGPART_EXPR, rtype, arg0);
7410       if (!imagp)
7411         return NULL_TREE;
7412
7413       icall = build_function_call_expr (ifn,
7414                                         build_tree_list (NULL_TREE, imagp));
7415       icall = builtin_save_expr (icall);
7416       rcall = build_function_call_expr (rfn,
7417                                         build_tree_list (NULL_TREE, realp));
7418       rcall = builtin_save_expr (rcall);
7419       return build2 (COMPLEX_EXPR, type,
7420                      build2 (MULT_EXPR, rtype,
7421                              rcall,
7422                              build1 (REALPART_EXPR, rtype, icall)),
7423                      build2 (MULT_EXPR, rtype,
7424                              rcall,
7425                              build1 (IMAGPART_EXPR, rtype, icall)));
7426     }
7427
7428   return NULL_TREE;
7429 }
7430
7431 /* Fold function call to builtin trunc, truncf or truncl.  Return
7432    NULL_TREE if no simplification can be made.  */
7433
7434 static tree
7435 fold_builtin_trunc (tree fndecl, tree arglist)
7436 {
7437   tree arg;
7438
7439   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7440     return 0;
7441
7442   /* Optimize trunc of constant value.  */
7443   arg = TREE_VALUE (arglist);
7444   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7445     {
7446       REAL_VALUE_TYPE r, x;
7447       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7448
7449       x = TREE_REAL_CST (arg);
7450       real_trunc (&r, TYPE_MODE (type), &x);
7451       return build_real (type, r);
7452     }
7453
7454   return fold_trunc_transparent_mathfn (fndecl, arglist);
7455 }
7456
7457 /* Fold function call to builtin floor, floorf or floorl.  Return
7458    NULL_TREE if no simplification can be made.  */
7459
7460 static tree
7461 fold_builtin_floor (tree fndecl, tree arglist)
7462 {
7463   tree arg;
7464
7465   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7466     return 0;
7467
7468   /* Optimize floor of constant value.  */
7469   arg = TREE_VALUE (arglist);
7470   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7471     {
7472       REAL_VALUE_TYPE x;
7473
7474       x = TREE_REAL_CST (arg);
7475       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7476         {
7477           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7478           REAL_VALUE_TYPE r;
7479
7480           real_floor (&r, TYPE_MODE (type), &x);
7481           return build_real (type, r);
7482         }
7483     }
7484
7485   /* Fold floor (x) where x is nonnegative to trunc (x).  */
7486   if (tree_expr_nonnegative_p (arg))
7487     {
7488       tree truncfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_TRUNC);
7489       if (truncfn)
7490         return build_function_call_expr (truncfn, arglist);
7491     }
7492
7493   return fold_trunc_transparent_mathfn (fndecl, arglist);
7494 }
7495
7496 /* Fold function call to builtin ceil, ceilf or ceill.  Return
7497    NULL_TREE if no simplification can be made.  */
7498
7499 static tree
7500 fold_builtin_ceil (tree fndecl, tree arglist)
7501 {
7502   tree arg;
7503
7504   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7505     return 0;
7506
7507   /* Optimize ceil of constant value.  */
7508   arg = TREE_VALUE (arglist);
7509   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7510     {
7511       REAL_VALUE_TYPE x;
7512
7513       x = TREE_REAL_CST (arg);
7514       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7515         {
7516           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7517           REAL_VALUE_TYPE r;
7518
7519           real_ceil (&r, TYPE_MODE (type), &x);
7520           return build_real (type, r);
7521         }
7522     }
7523
7524   return fold_trunc_transparent_mathfn (fndecl, arglist);
7525 }
7526
7527 /* Fold function call to builtin round, roundf or roundl.  Return
7528    NULL_TREE if no simplification can be made.  */
7529
7530 static tree
7531 fold_builtin_round (tree fndecl, tree arglist)
7532 {
7533   tree arg;
7534
7535   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7536     return 0;
7537
7538   /* Optimize round of constant value.  */
7539   arg = TREE_VALUE (arglist);
7540   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7541     {
7542       REAL_VALUE_TYPE x;
7543
7544       x = TREE_REAL_CST (arg);
7545       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7546         {
7547           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7548           REAL_VALUE_TYPE r;
7549
7550           real_round (&r, TYPE_MODE (type), &x);
7551           return build_real (type, r);
7552         }
7553     }
7554
7555   return fold_trunc_transparent_mathfn (fndecl, arglist);
7556 }
7557
7558 /* Fold function call to builtin lround, lroundf or lroundl (or the
7559    corresponding long long versions) and other rounding functions.
7560    Return NULL_TREE if no simplification can be made.  */
7561
7562 static tree
7563 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7564 {
7565   tree arg;
7566
7567   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7568     return 0;
7569
7570   /* Optimize lround of constant value.  */
7571   arg = TREE_VALUE (arglist);
7572   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7573     {
7574       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7575
7576       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7577         {
7578           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7579           tree ftype = TREE_TYPE (arg), result;
7580           HOST_WIDE_INT hi, lo;
7581           REAL_VALUE_TYPE r;
7582
7583           switch (DECL_FUNCTION_CODE (fndecl))
7584             {
7585             CASE_FLT_FN (BUILT_IN_LFLOOR):
7586             CASE_FLT_FN (BUILT_IN_LLFLOOR):
7587               real_floor (&r, TYPE_MODE (ftype), &x);
7588               break;
7589
7590             CASE_FLT_FN (BUILT_IN_LCEIL):
7591             CASE_FLT_FN (BUILT_IN_LLCEIL):
7592               real_ceil (&r, TYPE_MODE (ftype), &x);
7593               break;
7594
7595             CASE_FLT_FN (BUILT_IN_LROUND):
7596             CASE_FLT_FN (BUILT_IN_LLROUND):
7597               real_round (&r, TYPE_MODE (ftype), &x);
7598               break;
7599
7600             default:
7601               gcc_unreachable ();
7602             }
7603
7604           REAL_VALUE_TO_INT (&lo, &hi, r);
7605           result = build_int_cst_wide (NULL_TREE, lo, hi);
7606           if (int_fits_type_p (result, itype))
7607             return fold_convert (itype, result);
7608         }
7609     }
7610
7611   switch (DECL_FUNCTION_CODE (fndecl))
7612     {
7613     CASE_FLT_FN (BUILT_IN_LFLOOR):
7614     CASE_FLT_FN (BUILT_IN_LLFLOOR):
7615       /* Fold lfloor (x) where x is nonnegative to FIX_TRUNC (x).  */
7616       if (tree_expr_nonnegative_p (arg))
7617         return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)),
7618                             arg);
7619       break;
7620     default:;
7621     }
7622
7623   return fold_fixed_mathfn (fndecl, arglist);
7624 }
7625
7626 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7627    and their long and long long variants (i.e. ffsl and ffsll).
7628    Return NULL_TREE if no simplification can be made.  */
7629
7630 static tree
7631 fold_builtin_bitop (tree fndecl, tree arglist)
7632 {
7633   tree arg;
7634
7635   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7636     return NULL_TREE;
7637
7638   /* Optimize for constant argument.  */
7639   arg = TREE_VALUE (arglist);
7640   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7641     {
7642       HOST_WIDE_INT hi, width, result;
7643       unsigned HOST_WIDE_INT lo;
7644       tree type;
7645
7646       type = TREE_TYPE (arg);
7647       width = TYPE_PRECISION (type);
7648       lo = TREE_INT_CST_LOW (arg);
7649
7650       /* Clear all the bits that are beyond the type's precision.  */
7651       if (width > HOST_BITS_PER_WIDE_INT)
7652         {
7653           hi = TREE_INT_CST_HIGH (arg);
7654           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7655             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7656         }
7657       else
7658         {
7659           hi = 0;
7660           if (width < HOST_BITS_PER_WIDE_INT)
7661             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7662         }
7663
7664       switch (DECL_FUNCTION_CODE (fndecl))
7665         {
7666         CASE_INT_FN (BUILT_IN_FFS):
7667           if (lo != 0)
7668             result = exact_log2 (lo & -lo) + 1;
7669           else if (hi != 0)
7670             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7671           else
7672             result = 0;
7673           break;
7674
7675         CASE_INT_FN (BUILT_IN_CLZ):
7676           if (hi != 0)
7677             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7678           else if (lo != 0)
7679             result = width - floor_log2 (lo) - 1;
7680           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7681             result = width;
7682           break;
7683
7684         CASE_INT_FN (BUILT_IN_CTZ):
7685           if (lo != 0)
7686             result = exact_log2 (lo & -lo);
7687           else if (hi != 0)
7688             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7689           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7690             result = width;
7691           break;
7692
7693         CASE_INT_FN (BUILT_IN_POPCOUNT):
7694           result = 0;
7695           while (lo)
7696             result++, lo &= lo - 1;
7697           while (hi)
7698             result++, hi &= hi - 1;
7699           break;
7700
7701         CASE_INT_FN (BUILT_IN_PARITY):
7702           result = 0;
7703           while (lo)
7704             result++, lo &= lo - 1;
7705           while (hi)
7706             result++, hi &= hi - 1;
7707           result &= 1;
7708           break;
7709
7710         default:
7711           gcc_unreachable ();
7712         }
7713
7714       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7715     }
7716
7717   return NULL_TREE;
7718 }
7719
7720 /* Fold function call to builtin_bswap and the long and long long
7721    variants.  Return NULL_TREE if no simplification can be made.  */
7722 static tree
7723 fold_builtin_bswap (tree fndecl, tree arglist)
7724 {
7725   tree arg;
7726
7727   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7728     return 0;
7729
7730   /* Optimize constant value.  */
7731   arg = TREE_VALUE (arglist);
7732   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7733     {
7734       HOST_WIDE_INT hi, width, r_hi = 0;
7735       unsigned HOST_WIDE_INT lo, r_lo = 0;
7736       tree type;
7737
7738       type = TREE_TYPE (arg);
7739       width = TYPE_PRECISION (type);
7740       lo = TREE_INT_CST_LOW (arg);
7741       hi = TREE_INT_CST_HIGH (arg);
7742
7743       switch (DECL_FUNCTION_CODE (fndecl))
7744         {
7745           case BUILT_IN_BSWAP32:
7746           case BUILT_IN_BSWAP64:
7747             {
7748               int s;
7749
7750               for (s = 0; s < width; s += 8)
7751                 {
7752                   int d = width - s - 8;
7753                   unsigned HOST_WIDE_INT byte;
7754
7755                   if (s < HOST_BITS_PER_WIDE_INT)
7756                     byte = (lo >> s) & 0xff;
7757                   else
7758                     byte = (hi >> (s - HOST_BITS_PER_WIDE_INT)) & 0xff;
7759
7760                   if (d < HOST_BITS_PER_WIDE_INT)
7761                     r_lo |= byte << d;
7762                   else
7763                     r_hi |= byte << (d - HOST_BITS_PER_WIDE_INT);
7764                 }
7765             }
7766
7767             break;
7768
7769         default:
7770           gcc_unreachable ();
7771         }
7772
7773       if (width < HOST_BITS_PER_WIDE_INT)
7774         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
7775       else
7776         return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
7777     }
7778
7779   return NULL_TREE;
7780 }
7781 /* Return true if EXPR is the real constant contained in VALUE.  */
7782
7783 static bool
7784 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7785 {
7786   STRIP_NOPS (expr);
7787
7788   return ((TREE_CODE (expr) == REAL_CST
7789            && ! TREE_CONSTANT_OVERFLOW (expr)
7790            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7791           || (TREE_CODE (expr) == COMPLEX_CST
7792               && real_dconstp (TREE_REALPART (expr), value)
7793               && real_zerop (TREE_IMAGPART (expr))));
7794 }
7795
7796 /* A subroutine of fold_builtin to fold the various logarithmic
7797    functions.  Return NULL_TREE if no simplification can me made.
7798    FUNC is the corresponding MPFR logarithm function.  */
7799
7800 static tree
7801 fold_builtin_logarithm (tree fndecl, tree arglist,
7802                         int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
7803 {
7804   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7805     {
7806       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7807       tree arg = TREE_VALUE (arglist);
7808       tree res;
7809       const enum built_in_function fcode = builtin_mathfn_code (arg);
7810
7811       /* Optimize log(e) = 1.0.  We're never passed an exact 'e',
7812          instead we'll look for 'e' truncated to MODE.  So only do
7813          this if flag_unsafe_math_optimizations is set.  */
7814       if (flag_unsafe_math_optimizations && func == mpfr_log)
7815         {
7816           const REAL_VALUE_TYPE e_truncated =
7817             real_value_truncate (TYPE_MODE (type), dconste);
7818           if (real_dconstp (arg, &e_truncated))
7819             return build_real (type, dconst1);
7820         }
7821
7822       /* Calculate the result when the argument is a constant.  */
7823       if ((res = do_mpfr_arg1 (arg, type, func, &dconst0, NULL, false)))
7824         return res;
7825
7826       /* Special case, optimize logN(expN(x)) = x.  */
7827       if (flag_unsafe_math_optimizations
7828           && ((func == mpfr_log
7829                && (fcode == BUILT_IN_EXP
7830                    || fcode == BUILT_IN_EXPF
7831                    || fcode == BUILT_IN_EXPL))
7832               || (func == mpfr_log2
7833                   && (fcode == BUILT_IN_EXP2
7834                       || fcode == BUILT_IN_EXP2F
7835                       || fcode == BUILT_IN_EXP2L))
7836               || (func == mpfr_log10 && (BUILTIN_EXP10_P (fcode)))))
7837         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7838
7839       /* Optimize logN(func()) for various exponential functions.  We
7840          want to determine the value "x" and the power "exponent" in
7841          order to transform logN(x**exponent) into exponent*logN(x).  */
7842       if (flag_unsafe_math_optimizations)
7843         {
7844           tree exponent = 0, x = 0;
7845
7846           switch (fcode)
7847           {
7848           CASE_FLT_FN (BUILT_IN_EXP):
7849             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7850             x = build_real (type,
7851                             real_value_truncate (TYPE_MODE (type), dconste));
7852             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7853             break;
7854           CASE_FLT_FN (BUILT_IN_EXP2):
7855             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7856             x = build_real (type, dconst2);
7857             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7858             break;
7859           CASE_FLT_FN (BUILT_IN_EXP10):
7860           CASE_FLT_FN (BUILT_IN_POW10):
7861             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7862             x = build_real (type, dconst10);
7863             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7864             break;
7865           CASE_FLT_FN (BUILT_IN_SQRT):
7866             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7867             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7868             exponent = build_real (type, dconsthalf);
7869             break;
7870           CASE_FLT_FN (BUILT_IN_CBRT):
7871             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7872             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7873             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7874                                                               dconstthird));
7875             break;
7876           CASE_FLT_FN (BUILT_IN_POW):
7877             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7878             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7879             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7880             break;
7881           default:
7882             break;
7883           }
7884
7885           /* Now perform the optimization.  */
7886           if (x && exponent)
7887             {
7888               tree logfn;
7889               arglist = build_tree_list (NULL_TREE, x);
7890               logfn = build_function_call_expr (fndecl, arglist);
7891               return fold_build2 (MULT_EXPR, type, exponent, logfn);
7892             }
7893         }
7894     }
7895
7896   return 0;
7897 }
7898
7899 /* Fold a builtin function call to hypot, hypotf, or hypotl.  Return
7900    NULL_TREE if no simplification can be made.  */
7901
7902 static tree
7903 fold_builtin_hypot (tree fndecl, tree arglist, tree type)
7904 {
7905   tree arg0 = TREE_VALUE (arglist);
7906   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7907   tree res, narg0, narg1;
7908
7909   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7910     return NULL_TREE;
7911
7912   /* Calculate the result when the argument is a constant.  */
7913   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_hypot)))
7914     return res;
7915   
7916   /* If either argument to hypot has a negate or abs, strip that off.
7917      E.g. hypot(-x,fabs(y)) -> hypot(x,y).  */
7918   narg0 = fold_strip_sign_ops (arg0);
7919   narg1 = fold_strip_sign_ops (arg1);
7920   if (narg0 || narg1)
7921     {
7922       tree narglist = tree_cons (NULL_TREE, narg0 ? narg0 : arg0,
7923                                  build_tree_list (NULL_TREE,
7924                                                   narg1 ? narg1 : arg1));
7925       return build_function_call_expr (fndecl, narglist);
7926     }
7927   
7928   /* If either argument is zero, hypot is fabs of the other.  */
7929   if (real_zerop (arg0))
7930     return fold_build1 (ABS_EXPR, type, arg1);
7931   else if (real_zerop (arg1))
7932     return fold_build1 (ABS_EXPR, type, arg0);
7933       
7934   /* hypot(x,x) -> fabs(x)*sqrt(2).  */
7935   if (flag_unsafe_math_optimizations
7936       && operand_equal_p (arg0, arg1, OEP_PURE_SAME))
7937     {
7938       REAL_VALUE_TYPE sqrt2;
7939
7940       real_sqrt (&sqrt2, TYPE_MODE (type), &dconst2);
7941       return fold_build2 (MULT_EXPR, type,
7942                           fold_build1 (ABS_EXPR, type, arg0),
7943                           build_real (type, sqrt2));
7944     }
7945
7946   return NULL_TREE;
7947 }
7948
7949
7950 /* Fold a builtin function call to pow, powf, or powl.  Return
7951    NULL_TREE if no simplification can be made.  */
7952 static tree
7953 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7954 {
7955   tree arg0 = TREE_VALUE (arglist);
7956   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7957   tree res;
7958
7959   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7960     return NULL_TREE;
7961
7962   /* Calculate the result when the argument is a constant.  */
7963   if ((res = do_mpfr_arg2 (arg0, arg1, type, mpfr_pow)))
7964     return res;
7965
7966   /* Optimize pow(1.0,y) = 1.0.  */
7967   if (real_onep (arg0))
7968     return omit_one_operand (type, build_real (type, dconst1), arg1);
7969
7970   if (TREE_CODE (arg1) == REAL_CST
7971       && ! TREE_CONSTANT_OVERFLOW (arg1))
7972     {
7973       REAL_VALUE_TYPE cint;
7974       REAL_VALUE_TYPE c;
7975       HOST_WIDE_INT n;
7976
7977       c = TREE_REAL_CST (arg1);
7978
7979       /* Optimize pow(x,0.0) = 1.0.  */
7980       if (REAL_VALUES_EQUAL (c, dconst0))
7981         return omit_one_operand (type, build_real (type, dconst1),
7982                                  arg0);
7983
7984       /* Optimize pow(x,1.0) = x.  */
7985       if (REAL_VALUES_EQUAL (c, dconst1))
7986         return arg0;
7987
7988       /* Optimize pow(x,-1.0) = 1.0/x.  */
7989       if (REAL_VALUES_EQUAL (c, dconstm1))
7990         return fold_build2 (RDIV_EXPR, type,
7991                             build_real (type, dconst1), arg0);
7992
7993       /* Optimize pow(x,0.5) = sqrt(x).  */
7994       if (flag_unsafe_math_optimizations
7995           && REAL_VALUES_EQUAL (c, dconsthalf))
7996         {
7997           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7998
7999           if (sqrtfn != NULL_TREE)
8000             {
8001               tree arglist = build_tree_list (NULL_TREE, arg0);
8002               return build_function_call_expr (sqrtfn, arglist);
8003             }
8004         }
8005
8006       /* Optimize pow(x,1.0/3.0) = cbrt(x).  */
8007       if (flag_unsafe_math_optimizations)
8008         {
8009           const REAL_VALUE_TYPE dconstroot
8010             = real_value_truncate (TYPE_MODE (type), dconstthird);
8011
8012           if (REAL_VALUES_EQUAL (c, dconstroot))
8013             {
8014               tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
8015               if (cbrtfn != NULL_TREE)
8016                 {
8017                   tree arglist = build_tree_list (NULL_TREE, arg0);
8018                   return build_function_call_expr (cbrtfn, arglist);
8019                 }
8020             }
8021         }
8022
8023       /* Check for an integer exponent.  */
8024       n = real_to_integer (&c);
8025       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
8026       if (real_identical (&c, &cint))
8027         {
8028           /* Attempt to evaluate pow at compile-time.  */
8029           if (TREE_CODE (arg0) == REAL_CST
8030               && ! TREE_CONSTANT_OVERFLOW (arg0))
8031             {
8032               REAL_VALUE_TYPE x;
8033               bool inexact;
8034
8035               x = TREE_REAL_CST (arg0);
8036               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8037               if (flag_unsafe_math_optimizations || !inexact)
8038                 return build_real (type, x);
8039             }
8040
8041           /* Strip sign ops from even integer powers.  */
8042           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
8043             {
8044               tree narg0 = fold_strip_sign_ops (arg0);
8045               if (narg0)
8046                 {
8047                   arglist = build_tree_list (NULL_TREE, arg1);
8048                   arglist = tree_cons (NULL_TREE, narg0, arglist);
8049                   return build_function_call_expr (fndecl, arglist);
8050                 }
8051             }
8052         }
8053     }
8054
8055   if (flag_unsafe_math_optimizations)
8056     {
8057       const enum built_in_function fcode = builtin_mathfn_code (arg0);
8058
8059       /* Optimize pow(expN(x),y) = expN(x*y).  */
8060       if (BUILTIN_EXPONENT_P (fcode))
8061         {
8062           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8063           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8064           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
8065           arglist = build_tree_list (NULL_TREE, arg);
8066           return build_function_call_expr (expfn, arglist);
8067         }
8068
8069       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8070       if (BUILTIN_SQRT_P (fcode))
8071         {
8072           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8073           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8074                                     build_real (type, dconsthalf));
8075
8076           arglist = tree_cons (NULL_TREE, narg0,
8077                                build_tree_list (NULL_TREE, narg1));
8078           return build_function_call_expr (fndecl, arglist);
8079         }
8080
8081       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
8082       if (BUILTIN_CBRT_P (fcode))
8083         {
8084           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8085           if (tree_expr_nonnegative_p (arg))
8086             {
8087               const REAL_VALUE_TYPE dconstroot
8088                 = real_value_truncate (TYPE_MODE (type), dconstthird);
8089               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
8090                                         build_real (type, dconstroot));
8091               arglist = tree_cons (NULL_TREE, arg,
8092                                    build_tree_list (NULL_TREE, narg1));
8093               return build_function_call_expr (fndecl, arglist);
8094             }
8095         }
8096
8097       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8098       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
8099            || fcode == BUILT_IN_POWL)
8100         {
8101           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8102           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8103           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
8104           arglist = tree_cons (NULL_TREE, arg00,
8105                                build_tree_list (NULL_TREE, narg1));
8106           return build_function_call_expr (fndecl, arglist);
8107         }
8108     }
8109
8110   return NULL_TREE;
8111 }
8112
8113 /* Fold a builtin function call to powi, powif, or powil.  Return
8114    NULL_TREE if no simplification can be made.  */
8115 static tree
8116 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
8117 {
8118   tree arg0 = TREE_VALUE (arglist);
8119   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8120
8121   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
8122     return NULL_TREE;
8123
8124   /* Optimize pow(1.0,y) = 1.0.  */
8125   if (real_onep (arg0))
8126     return omit_one_operand (type, build_real (type, dconst1), arg1);
8127
8128   if (host_integerp (arg1, 0))
8129     {
8130       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
8131
8132       /* Evaluate powi at compile-time.  */
8133       if (TREE_CODE (arg0) == REAL_CST
8134           && ! TREE_CONSTANT_OVERFLOW (arg0))
8135         {
8136           REAL_VALUE_TYPE x;
8137           x = TREE_REAL_CST (arg0);
8138           real_powi (&x, TYPE_MODE (type), &x, c);
8139           return build_real (type, x);
8140         }
8141
8142       /* Optimize pow(x,0) = 1.0.  */
8143       if (c == 0)
8144         return omit_one_operand (type, build_real (type, dconst1),
8145                                  arg0);
8146
8147       /* Optimize pow(x,1) = x.  */
8148       if (c == 1)
8149         return arg0;
8150
8151       /* Optimize pow(x,-1) = 1.0/x.  */
8152       if (c == -1)
8153         return fold_build2 (RDIV_EXPR, type,
8154                            build_real (type, dconst1), arg0);
8155     }
8156
8157   return NULL_TREE;
8158 }
8159
8160 /* A subroutine of fold_builtin to fold the various exponent
8161    functions.  Return NULL_TREE if no simplification can me made.
8162    FUNC is the corresponding MPFR exponent function.  */
8163
8164 static tree
8165 fold_builtin_exponent (tree fndecl, tree arglist,
8166                        int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t))
8167 {
8168   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8169     {
8170       tree type = TREE_TYPE (TREE_TYPE (fndecl));
8171       tree arg = TREE_VALUE (arglist);
8172       tree res;
8173       
8174       /* Calculate the result when the argument is a constant.  */
8175       if ((res = do_mpfr_arg1 (arg, type, func, NULL, NULL, 0)))
8176         return res;
8177
8178       /* Optimize expN(logN(x)) = x.  */
8179       if (flag_unsafe_math_optimizations)
8180         {
8181           const enum built_in_function fcode = builtin_mathfn_code (arg);
8182
8183           if ((func == mpfr_exp
8184                && (fcode == BUILT_IN_LOG
8185                    || fcode == BUILT_IN_LOGF
8186                    || fcode == BUILT_IN_LOGL))
8187               || (func == mpfr_exp2
8188                   && (fcode == BUILT_IN_LOG2
8189                       || fcode == BUILT_IN_LOG2F
8190                       || fcode == BUILT_IN_LOG2L))
8191               || (func == mpfr_exp10
8192                   && (fcode == BUILT_IN_LOG10
8193                       || fcode == BUILT_IN_LOG10F
8194                       || fcode == BUILT_IN_LOG10L)))
8195             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
8196         }
8197     }
8198
8199   return 0;
8200 }
8201
8202 /* Return true if VAR is a VAR_DECL or a component thereof.  */
8203
8204 static bool
8205 var_decl_component_p (tree var)
8206 {
8207   tree inner = var;
8208   while (handled_component_p (inner))
8209     inner = TREE_OPERAND (inner, 0);
8210   return SSA_VAR_P (inner);
8211 }
8212
8213 /* Fold function call to builtin memset.  Return
8214    NULL_TREE if no simplification can be made.  */
8215
8216 static tree
8217 fold_builtin_memset (tree arglist, tree type, bool ignore)
8218 {
8219   tree dest, c, len, var, ret;
8220   unsigned HOST_WIDE_INT length, cval;
8221
8222   if (!validate_arglist (arglist,
8223                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
8224     return 0;
8225
8226   dest = TREE_VALUE (arglist);
8227   c = TREE_VALUE (TREE_CHAIN (arglist));
8228   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8229
8230   if (! host_integerp (len, 1))
8231     return 0;
8232
8233   /* If the LEN parameter is zero, return DEST.  */
8234   if (integer_zerop (len))
8235     return omit_one_operand (type, dest, c);
8236
8237   if (! host_integerp (c, 1) || TREE_SIDE_EFFECTS (dest))
8238     return 0;
8239
8240   var = dest;
8241   STRIP_NOPS (var);
8242   if (TREE_CODE (var) != ADDR_EXPR)
8243     return 0;
8244
8245   var = TREE_OPERAND (var, 0);
8246   if (TREE_THIS_VOLATILE (var))
8247     return 0;
8248
8249   if (!INTEGRAL_TYPE_P (TREE_TYPE (var))
8250       && !POINTER_TYPE_P (TREE_TYPE (var)))
8251     return 0;
8252
8253   if (! var_decl_component_p (var))
8254     return 0;
8255
8256   length = tree_low_cst (len, 1);
8257   if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (var))) != length
8258       || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
8259          < (int) length)
8260     return 0;
8261
8262   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
8263     return 0;
8264
8265   if (integer_zerop (c))
8266     cval = 0;
8267   else
8268     {
8269       if (CHAR_BIT != 8 || BITS_PER_UNIT != 8 || HOST_BITS_PER_WIDE_INT > 64)
8270         return 0;
8271
8272       cval = tree_low_cst (c, 1);
8273       cval &= 0xff;
8274       cval |= cval << 8;
8275       cval |= cval << 16;
8276       cval |= (cval << 31) << 1;
8277     }
8278
8279   ret = build_int_cst_type (TREE_TYPE (var), cval);
8280   ret = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (var), var, ret);
8281   if (ignore)
8282     return ret;
8283
8284   return omit_one_operand (type, dest, ret);
8285 }
8286
8287 /* Fold function call to builtin memset.  Return
8288    NULL_TREE if no simplification can be made.  */
8289
8290 static tree
8291 fold_builtin_bzero (tree arglist, bool ignore)
8292 {
8293   tree dest, size, newarglist;
8294
8295   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8296     return 0;
8297
8298   if (!ignore)
8299     return 0;
8300
8301   dest = TREE_VALUE (arglist);
8302   size = TREE_VALUE (TREE_CHAIN (arglist));
8303
8304   /* New argument list transforming bzero(ptr x, int y) to
8305      memset(ptr x, int 0, size_t y).   This is done this way
8306      so that if it isn't expanded inline, we fallback to
8307      calling bzero instead of memset.  */
8308
8309   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8310   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
8311   newarglist = tree_cons (NULL_TREE, dest, newarglist);
8312   return fold_builtin_memset (newarglist, void_type_node, ignore);
8313 }
8314
8315 /* Fold function call to builtin mem{{,p}cpy,move}.  Return
8316    NULL_TREE if no simplification can be made.
8317    If ENDP is 0, return DEST (like memcpy).
8318    If ENDP is 1, return DEST+LEN (like mempcpy).
8319    If ENDP is 2, return DEST+LEN-1 (like stpcpy).
8320    If ENDP is 3, return DEST, additionally *SRC and *DEST may overlap
8321    (memmove).   */
8322
8323 static tree
8324 fold_builtin_memory_op (tree arglist, tree type, bool ignore, int endp)
8325 {
8326   tree dest, src, len, destvar, srcvar, expr;
8327
8328   if (! validate_arglist (arglist,
8329                           POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8330     return 0;
8331
8332   dest = TREE_VALUE (arglist);
8333   src = TREE_VALUE (TREE_CHAIN (arglist));
8334   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8335
8336   /* If the LEN parameter is zero, return DEST.  */
8337   if (integer_zerop (len))
8338     return omit_one_operand (type, dest, src);
8339
8340   /* If SRC and DEST are the same (and not volatile), return
8341      DEST{,+LEN,+LEN-1}.  */
8342   if (operand_equal_p (src, dest, 0))
8343     expr = len;
8344   else
8345     {
8346       tree srctype, desttype;
8347       if (endp == 3)
8348         {
8349           int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
8350           int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
8351
8352           /* Both DEST and SRC must be pointer types. 
8353              ??? This is what old code did.  Is the testing for pointer types
8354              really mandatory?
8355
8356              If either SRC is readonly or length is 1, we can use memcpy.  */
8357           if (dest_align && src_align
8358               && (readonly_data_expr (src)
8359                   || (host_integerp (len, 1)
8360                       && (MIN (src_align, dest_align) / BITS_PER_UNIT >=
8361                           tree_low_cst (len, 1)))))
8362             {
8363               tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8364               if (!fn)
8365                 return 0;
8366               return build_function_call_expr (fn, arglist);
8367             }
8368           return 0;
8369         }
8370
8371       if (!host_integerp (len, 0))
8372         return 0;
8373       /* FIXME:
8374          This logic lose for arguments like (type *)malloc (sizeof (type)),
8375          since we strip the casts of up to VOID return value from malloc.
8376          Perhaps we ought to inherit type from non-VOID argument here?  */
8377       STRIP_NOPS (src);
8378       STRIP_NOPS (dest);
8379       srctype = TREE_TYPE (TREE_TYPE (src));
8380       desttype = TREE_TYPE (TREE_TYPE (dest));
8381       if (!srctype || !desttype
8382           || !TYPE_SIZE_UNIT (srctype)
8383           || !TYPE_SIZE_UNIT (desttype)
8384           || TREE_CODE (TYPE_SIZE_UNIT (srctype)) != INTEGER_CST
8385           || TREE_CODE (TYPE_SIZE_UNIT (desttype)) != INTEGER_CST
8386           || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8387           || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
8388         return 0;
8389
8390       if (get_pointer_alignment (dest, BIGGEST_ALIGNMENT) 
8391           < (int) TYPE_ALIGN (desttype)
8392           || (get_pointer_alignment (src, BIGGEST_ALIGNMENT) 
8393               < (int) TYPE_ALIGN (srctype)))
8394         return 0;
8395
8396       if (!ignore)
8397         dest = builtin_save_expr (dest);
8398
8399       srcvar = build_fold_indirect_ref (src);
8400       if (TREE_THIS_VOLATILE (srcvar))
8401         return 0;
8402       if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8403         return 0;
8404       /* With memcpy, it is possible to bypass aliasing rules, so without
8405          this check i. e. execute/20060930-2.c would be misoptimized, because
8406          it use conflicting alias set to hold argument for the memcpy call.
8407          This check is probably unnecesary with -fno-strict-aliasing. 
8408          Similarly for destvar.  See also PR29286.  */
8409       if (!var_decl_component_p (srcvar)
8410           /* Accept: memcpy (*char_var, "test", 1); that simplify
8411              to char_var='t';  */
8412           || is_gimple_min_invariant (srcvar)
8413           || readonly_data_expr (src))
8414         return 0;
8415
8416       destvar = build_fold_indirect_ref (dest);
8417       if (TREE_THIS_VOLATILE (destvar))
8418         return 0;
8419       if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8420         return 0;
8421       if (!var_decl_component_p (destvar))
8422         return 0;
8423
8424       if (srctype == desttype
8425           || (gimple_in_ssa_p (cfun)
8426               && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8427         expr = srcvar;
8428       else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8429            || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8430           && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8431               || POINTER_TYPE_P (TREE_TYPE (destvar))))
8432         expr = fold_convert (TREE_TYPE (destvar), srcvar);
8433       else
8434         expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8435       expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8436     }
8437
8438   if (ignore)
8439     return expr;
8440
8441   if (endp == 0 || endp == 3)
8442     return omit_one_operand (type, dest, expr);
8443
8444   if (expr == len)
8445     expr = 0;
8446
8447   if (endp == 2)
8448     len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8449                        ssize_int (1));
8450
8451   len = fold_convert (TREE_TYPE (dest), len);
8452   dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8453   dest = fold_convert (type, dest);
8454   if (expr)
8455     dest = omit_one_operand (type, dest, expr);
8456   return dest;
8457 }
8458
8459 /* Fold function call to builtin bcopy.  Return NULL_TREE if no
8460    simplification can be made.  */
8461
8462 static tree
8463 fold_builtin_bcopy (tree arglist, bool ignore)
8464 {
8465   tree src, dest, size, newarglist;
8466
8467   if (!validate_arglist (arglist,
8468                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8469     return 0;
8470
8471   if (! ignore)
8472     return 0;
8473
8474   src = TREE_VALUE (arglist);
8475   dest = TREE_VALUE (TREE_CHAIN (arglist));
8476   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8477
8478   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8479      memmove(ptr y, ptr x, size_t z).   This is done this way
8480      so that if it isn't expanded inline, we fallback to
8481      calling bcopy instead of memmove.  */
8482
8483   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8484   newarglist = tree_cons (NULL_TREE, src, newarglist);
8485   newarglist = tree_cons (NULL_TREE, dest, newarglist);
8486
8487   return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8488 }
8489
8490 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
8491    the length of the string to be copied.  Return NULL_TREE if no
8492    simplification can be made.  */
8493
8494 tree
8495 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8496 {
8497   tree dest, src, fn;
8498
8499   if (!validate_arglist (arglist,
8500                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8501     return 0;
8502
8503   dest = TREE_VALUE (arglist);
8504   src = TREE_VALUE (TREE_CHAIN (arglist));
8505
8506   /* If SRC and DEST are the same (and not volatile), return DEST.  */
8507   if (operand_equal_p (src, dest, 0))
8508     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8509
8510   if (optimize_size)
8511     return 0;
8512
8513   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8514   if (!fn)
8515     return 0;
8516
8517   if (!len)
8518     {
8519       len = c_strlen (src, 1);
8520       if (! len || TREE_SIDE_EFFECTS (len))
8521         return 0;
8522     }
8523
8524   len = size_binop (PLUS_EXPR, len, ssize_int (1));
8525   arglist = build_tree_list (NULL_TREE, len);
8526   arglist = tree_cons (NULL_TREE, src, arglist);
8527   arglist = tree_cons (NULL_TREE, dest, arglist);
8528   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8529                        build_function_call_expr (fn, arglist));
8530 }
8531
8532 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8533    the length of the source string.  Return NULL_TREE if no simplification
8534    can be made.  */
8535
8536 tree
8537 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8538 {
8539   tree dest, src, len, fn;
8540
8541   if (!validate_arglist (arglist,
8542                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8543     return 0;
8544
8545   dest = TREE_VALUE (arglist);
8546   src = TREE_VALUE (TREE_CHAIN (arglist));
8547   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8548
8549   /* If the LEN parameter is zero, return DEST.  */
8550   if (integer_zerop (len))
8551     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8552
8553   /* We can't compare slen with len as constants below if len is not a
8554      constant.  */
8555   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8556     return 0;
8557
8558   if (!slen)
8559     slen = c_strlen (src, 1);
8560
8561   /* Now, we must be passed a constant src ptr parameter.  */
8562   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8563     return 0;
8564
8565   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8566
8567   /* We do not support simplification of this case, though we do
8568      support it when expanding trees into RTL.  */
8569   /* FIXME: generate a call to __builtin_memset.  */
8570   if (tree_int_cst_lt (slen, len))
8571     return 0;
8572
8573   /* OK transform into builtin memcpy.  */
8574   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8575   if (!fn)
8576     return 0;
8577   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8578                        build_function_call_expr (fn, arglist));
8579 }
8580
8581 /* Fold function call to builtin memcmp.  Return
8582    NULL_TREE if no simplification can be made.  */
8583
8584 static tree
8585 fold_builtin_memcmp (tree arglist)
8586 {
8587   tree arg1, arg2, len;
8588   const char *p1, *p2;
8589
8590   if (!validate_arglist (arglist,
8591                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8592     return 0;
8593
8594   arg1 = TREE_VALUE (arglist);
8595   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8596   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8597
8598   /* If the LEN parameter is zero, return zero.  */
8599   if (integer_zerop (len))
8600     return omit_two_operands (integer_type_node, integer_zero_node,
8601                               arg1, arg2);
8602
8603   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8604   if (operand_equal_p (arg1, arg2, 0))
8605     return omit_one_operand (integer_type_node, integer_zero_node, len);
8606
8607   p1 = c_getstr (arg1);
8608   p2 = c_getstr (arg2);
8609
8610   /* If all arguments are constant, and the value of len is not greater
8611      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8612   if (host_integerp (len, 1) && p1 && p2
8613       && compare_tree_int (len, strlen (p1) + 1) <= 0
8614       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8615     {
8616       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8617
8618       if (r > 0)
8619         return integer_one_node;
8620       else if (r < 0)
8621         return integer_minus_one_node;
8622       else
8623         return integer_zero_node;
8624     }
8625
8626   /* If len parameter is one, return an expression corresponding to
8627      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8628   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8629     {
8630       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8631       tree cst_uchar_ptr_node
8632         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8633
8634       tree ind1 = fold_convert (integer_type_node,
8635                                 build1 (INDIRECT_REF, cst_uchar_node,
8636                                         fold_convert (cst_uchar_ptr_node,
8637                                                       arg1)));
8638       tree ind2 = fold_convert (integer_type_node,
8639                                 build1 (INDIRECT_REF, cst_uchar_node,
8640                                         fold_convert (cst_uchar_ptr_node,
8641                                                       arg2)));
8642       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8643     }
8644
8645   return 0;
8646 }
8647
8648 /* Fold function call to builtin strcmp.  Return
8649    NULL_TREE if no simplification can be made.  */
8650
8651 static tree
8652 fold_builtin_strcmp (tree arglist)
8653 {
8654   tree arg1, arg2;
8655   const char *p1, *p2;
8656
8657   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8658     return 0;
8659
8660   arg1 = TREE_VALUE (arglist);
8661   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8662
8663   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8664   if (operand_equal_p (arg1, arg2, 0))
8665     return integer_zero_node;
8666
8667   p1 = c_getstr (arg1);
8668   p2 = c_getstr (arg2);
8669
8670   if (p1 && p2)
8671     {
8672       const int i = strcmp (p1, p2);
8673       if (i < 0)
8674         return integer_minus_one_node;
8675       else if (i > 0)
8676         return integer_one_node;
8677       else
8678         return integer_zero_node;
8679     }
8680
8681   /* If the second arg is "", return *(const unsigned char*)arg1.  */
8682   if (p2 && *p2 == '\0')
8683     {
8684       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8685       tree cst_uchar_ptr_node
8686         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8687
8688       return fold_convert (integer_type_node,
8689                            build1 (INDIRECT_REF, cst_uchar_node,
8690                                    fold_convert (cst_uchar_ptr_node,
8691                                                  arg1)));
8692     }
8693
8694   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8695   if (p1 && *p1 == '\0')
8696     {
8697       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8698       tree cst_uchar_ptr_node
8699         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8700
8701       tree temp = fold_convert (integer_type_node,
8702                                 build1 (INDIRECT_REF, cst_uchar_node,
8703                                         fold_convert (cst_uchar_ptr_node,
8704                                                       arg2)));
8705       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8706     }
8707
8708   return 0;
8709 }
8710
8711 /* Fold function call to builtin strncmp.  Return
8712    NULL_TREE if no simplification can be made.  */
8713
8714 static tree
8715 fold_builtin_strncmp (tree arglist)
8716 {
8717   tree arg1, arg2, len;
8718   const char *p1, *p2;
8719
8720   if (!validate_arglist (arglist,
8721                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8722     return 0;
8723
8724   arg1 = TREE_VALUE (arglist);
8725   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8726   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8727
8728   /* If the LEN parameter is zero, return zero.  */
8729   if (integer_zerop (len))
8730     return omit_two_operands (integer_type_node, integer_zero_node,
8731                               arg1, arg2);
8732
8733   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8734   if (operand_equal_p (arg1, arg2, 0))
8735     return omit_one_operand (integer_type_node, integer_zero_node, len);
8736
8737   p1 = c_getstr (arg1);
8738   p2 = c_getstr (arg2);
8739
8740   if (host_integerp (len, 1) && p1 && p2)
8741     {
8742       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8743       if (i > 0)
8744         return integer_one_node;
8745       else if (i < 0)
8746         return integer_minus_one_node;
8747       else
8748         return integer_zero_node;
8749     }
8750
8751   /* If the second arg is "", and the length is greater than zero,
8752      return *(const unsigned char*)arg1.  */
8753   if (p2 && *p2 == '\0'
8754       && TREE_CODE (len) == INTEGER_CST
8755       && tree_int_cst_sgn (len) == 1)
8756     {
8757       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8758       tree cst_uchar_ptr_node
8759         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8760
8761       return fold_convert (integer_type_node,
8762                            build1 (INDIRECT_REF, cst_uchar_node,
8763                                    fold_convert (cst_uchar_ptr_node,
8764                                                  arg1)));
8765     }
8766
8767   /* If the first arg is "", and the length is greater than zero,
8768      return -*(const unsigned char*)arg2.  */
8769   if (p1 && *p1 == '\0'
8770       && TREE_CODE (len) == INTEGER_CST
8771       && tree_int_cst_sgn (len) == 1)
8772     {
8773       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8774       tree cst_uchar_ptr_node
8775         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8776
8777       tree temp = fold_convert (integer_type_node,
8778                                 build1 (INDIRECT_REF, cst_uchar_node,
8779                                         fold_convert (cst_uchar_ptr_node,
8780                                                       arg2)));
8781       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8782     }
8783
8784   /* If len parameter is one, return an expression corresponding to
8785      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8786   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8787     {
8788       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8789       tree cst_uchar_ptr_node
8790         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8791
8792       tree ind1 = fold_convert (integer_type_node,
8793                                 build1 (INDIRECT_REF, cst_uchar_node,
8794                                         fold_convert (cst_uchar_ptr_node,
8795                                                       arg1)));
8796       tree ind2 = fold_convert (integer_type_node,
8797                                 build1 (INDIRECT_REF, cst_uchar_node,
8798                                         fold_convert (cst_uchar_ptr_node,
8799                                                       arg2)));
8800       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8801     }
8802
8803   return 0;
8804 }
8805
8806 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8807    NULL_TREE if no simplification can be made.  */
8808
8809 static tree
8810 fold_builtin_signbit (tree fndecl, tree arglist)
8811 {
8812   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8813   tree arg, temp;
8814
8815   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8816     return NULL_TREE;
8817
8818   arg = TREE_VALUE (arglist);
8819
8820   /* If ARG is a compile-time constant, determine the result.  */
8821   if (TREE_CODE (arg) == REAL_CST
8822       && !TREE_CONSTANT_OVERFLOW (arg))
8823     {
8824       REAL_VALUE_TYPE c;
8825
8826       c = TREE_REAL_CST (arg);
8827       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8828       return fold_convert (type, temp);
8829     }
8830
8831   /* If ARG is non-negative, the result is always zero.  */
8832   if (tree_expr_nonnegative_p (arg))
8833     return omit_one_operand (type, integer_zero_node, arg);
8834
8835   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8836   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8837     return fold_build2 (LT_EXPR, type, arg,
8838                         build_real (TREE_TYPE (arg), dconst0));
8839
8840   return NULL_TREE;
8841 }
8842
8843 /* Fold function call to builtin copysign, copysignf or copysignl.
8844    Return NULL_TREE if no simplification can be made.  */
8845
8846 static tree
8847 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8848 {
8849   tree arg1, arg2, tem;
8850
8851   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8852     return NULL_TREE;
8853
8854   arg1 = TREE_VALUE (arglist);
8855   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8856
8857   /* copysign(X,X) is X.  */
8858   if (operand_equal_p (arg1, arg2, 0))
8859     return fold_convert (type, arg1);
8860
8861   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8862   if (TREE_CODE (arg1) == REAL_CST
8863       && TREE_CODE (arg2) == REAL_CST
8864       && !TREE_CONSTANT_OVERFLOW (arg1)
8865       && !TREE_CONSTANT_OVERFLOW (arg2))
8866     {
8867       REAL_VALUE_TYPE c1, c2;
8868
8869       c1 = TREE_REAL_CST (arg1);
8870       c2 = TREE_REAL_CST (arg2);
8871       /* c1.sign := c2.sign.  */
8872       real_copysign (&c1, &c2);
8873       return build_real (type, c1);
8874     }
8875
8876   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8877      Remember to evaluate Y for side-effects.  */
8878   if (tree_expr_nonnegative_p (arg2))
8879     return omit_one_operand (type,
8880                              fold_build1 (ABS_EXPR, type, arg1),
8881                              arg2);
8882
8883   /* Strip sign changing operations for the first argument.  */
8884   tem = fold_strip_sign_ops (arg1);
8885   if (tem)
8886     {
8887       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8888       return build_function_call_expr (fndecl, arglist);
8889     }
8890
8891   return NULL_TREE;
8892 }
8893
8894 /* Fold a call to builtin isascii.  */
8895
8896 static tree
8897 fold_builtin_isascii (tree arglist)
8898 {
8899   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8900     return 0;
8901   else
8902     {
8903       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8904       tree arg = TREE_VALUE (arglist);
8905
8906       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8907                     build_int_cst (NULL_TREE,
8908                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8909       return fold_build2 (EQ_EXPR, integer_type_node,
8910                           arg, integer_zero_node);
8911     }
8912 }
8913
8914 /* Fold a call to builtin toascii.  */
8915
8916 static tree
8917 fold_builtin_toascii (tree arglist)
8918 {
8919   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8920     return 0;
8921   else
8922     {
8923       /* Transform toascii(c) -> (c & 0x7f).  */
8924       tree arg = TREE_VALUE (arglist);
8925
8926       return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8927                           build_int_cst (NULL_TREE, 0x7f));
8928     }
8929 }
8930
8931 /* Fold a call to builtin isdigit.  */
8932
8933 static tree
8934 fold_builtin_isdigit (tree arglist)
8935 {
8936   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8937     return 0;
8938   else
8939     {
8940       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8941       /* According to the C standard, isdigit is unaffected by locale.
8942          However, it definitely is affected by the target character set.  */
8943       tree arg;
8944       unsigned HOST_WIDE_INT target_digit0
8945         = lang_hooks.to_target_charset ('0');
8946
8947       if (target_digit0 == 0)
8948         return NULL_TREE;
8949
8950       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8951       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8952                     build_int_cst (unsigned_type_node, target_digit0));
8953       return fold_build2 (LE_EXPR, integer_type_node, arg,
8954                           build_int_cst (unsigned_type_node, 9));
8955     }
8956 }
8957
8958 /* Fold a call to fabs, fabsf or fabsl.  */
8959
8960 static tree
8961 fold_builtin_fabs (tree arglist, tree type)
8962 {
8963   tree arg;
8964
8965   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8966     return 0;
8967
8968   arg = TREE_VALUE (arglist);
8969   arg = fold_convert (type, arg);
8970   if (TREE_CODE (arg) == REAL_CST)
8971     return fold_abs_const (arg, type);
8972   return fold_build1 (ABS_EXPR, type, arg);
8973 }
8974
8975 /* Fold a call to abs, labs, llabs or imaxabs.  */
8976
8977 static tree
8978 fold_builtin_abs (tree arglist, tree type)
8979 {
8980   tree arg;
8981
8982   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8983     return 0;
8984
8985   arg = TREE_VALUE (arglist);
8986   arg = fold_convert (type, arg);
8987   if (TREE_CODE (arg) == INTEGER_CST)
8988     return fold_abs_const (arg, type);
8989   return fold_build1 (ABS_EXPR, type, arg);
8990 }
8991
8992 /* Fold a call to builtin fmin or fmax.  */
8993
8994 static tree
8995 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
8996 {
8997   if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8998     {
8999       tree arg0 = TREE_VALUE (arglist);
9000       tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9001       /* Calculate the result when the argument is a constant.  */
9002       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
9003
9004       if (res)
9005         return res;
9006
9007       /* If either argument is NaN, return the other one.  Avoid the
9008          transformation if we get (and honor) a signalling NaN.  Using
9009          omit_one_operand() ensures we create a non-lvalue.  */
9010       if (TREE_CODE (arg0) == REAL_CST
9011           && real_isnan (&TREE_REAL_CST (arg0))
9012           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
9013               || ! TREE_REAL_CST (arg0).signalling))
9014         return omit_one_operand (type, arg1, arg0);
9015       if (TREE_CODE (arg1) == REAL_CST
9016           && real_isnan (&TREE_REAL_CST (arg1))
9017           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
9018               || ! TREE_REAL_CST (arg1).signalling))
9019         return omit_one_operand (type, arg0, arg1);
9020
9021       /* Transform fmin/fmax(x,x) -> x.  */
9022       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
9023         return omit_one_operand (type, arg0, arg1);
9024       
9025       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
9026          functions to return the numeric arg if the other one is NaN.
9027          These tree codes don't honor that, so only transform if
9028          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
9029          handled, so we don't have to worry about it either.  */
9030       if (flag_finite_math_only)
9031         return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
9032                             fold_convert (type, arg0),
9033                             fold_convert (type, arg1));
9034     }
9035   return NULL_TREE;
9036 }
9037
9038 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
9039    EXP is the CALL_EXPR for the call.  */
9040
9041 static tree
9042 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
9043 {
9044   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9045   tree arg;
9046   REAL_VALUE_TYPE r;
9047
9048   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9049     {
9050       /* Check that we have exactly one argument.  */
9051       if (arglist == 0)
9052         {
9053           error ("too few arguments to function %qs",
9054                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9055           return error_mark_node;
9056         }
9057       else if (TREE_CHAIN (arglist) != 0)
9058         {
9059           error ("too many arguments to function %qs",
9060                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9061           return error_mark_node;
9062         }
9063       else
9064         {
9065           error ("non-floating-point argument to function %qs",
9066                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9067           return error_mark_node;
9068         }
9069     }
9070
9071   arg = TREE_VALUE (arglist);
9072   switch (builtin_index)
9073     {
9074     case BUILT_IN_ISINF:
9075       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9076         return omit_one_operand (type, integer_zero_node, arg);
9077
9078       if (TREE_CODE (arg) == REAL_CST)
9079         {
9080           r = TREE_REAL_CST (arg);
9081           if (real_isinf (&r))
9082             return real_compare (GT_EXPR, &r, &dconst0)
9083                    ? integer_one_node : integer_minus_one_node;
9084           else
9085             return integer_zero_node;
9086         }
9087
9088       return NULL_TREE;
9089
9090     case BUILT_IN_FINITE:
9091       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
9092           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
9093         return omit_one_operand (type, integer_one_node, arg);
9094
9095       if (TREE_CODE (arg) == REAL_CST)
9096         {
9097           r = TREE_REAL_CST (arg);
9098           return real_isinf (&r) || real_isnan (&r)
9099                  ? integer_zero_node : integer_one_node;
9100         }
9101
9102       return NULL_TREE;
9103
9104     case BUILT_IN_ISNAN:
9105       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
9106         return omit_one_operand (type, integer_zero_node, arg);
9107
9108       if (TREE_CODE (arg) == REAL_CST)
9109         {
9110           r = TREE_REAL_CST (arg);
9111           return real_isnan (&r) ? integer_one_node : integer_zero_node;
9112         }
9113
9114       arg = builtin_save_expr (arg);
9115       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
9116
9117     default:
9118       gcc_unreachable ();
9119     }
9120 }
9121
9122 /* Fold a call to an unordered comparison function such as
9123    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
9124    being called and ARGLIST is the argument list for the call.
9125    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
9126    the opposite of the desired result.  UNORDERED_CODE is used
9127    for modes that can hold NaNs and ORDERED_CODE is used for
9128    the rest.  */
9129
9130 static tree
9131 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
9132                             enum tree_code unordered_code,
9133                             enum tree_code ordered_code)
9134 {
9135   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9136   enum tree_code code;
9137   tree arg0, arg1;
9138   tree type0, type1;
9139   enum tree_code code0, code1;
9140   tree cmp_type = NULL_TREE;
9141
9142   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9143     {
9144       /* Check that we have exactly two arguments.  */
9145       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
9146         {
9147           error ("too few arguments to function %qs",
9148                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9149           return error_mark_node;
9150         }
9151       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
9152         {
9153           error ("too many arguments to function %qs",
9154                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9155           return error_mark_node;
9156         }
9157     }
9158
9159   arg0 = TREE_VALUE (arglist);
9160   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
9161
9162   type0 = TREE_TYPE (arg0);
9163   type1 = TREE_TYPE (arg1);
9164
9165   code0 = TREE_CODE (type0);
9166   code1 = TREE_CODE (type1);
9167
9168   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
9169     /* Choose the wider of two real types.  */
9170     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
9171       ? type0 : type1;
9172   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
9173     cmp_type = type0;
9174   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
9175     cmp_type = type1;
9176   else
9177     {
9178       error ("non-floating-point argument to function %qs",
9179                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
9180       return error_mark_node;
9181     }
9182
9183   arg0 = fold_convert (cmp_type, arg0);
9184   arg1 = fold_convert (cmp_type, arg1);
9185
9186   if (unordered_code == UNORDERED_EXPR)
9187     {
9188       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9189         return omit_two_operands (type, integer_zero_node, arg0, arg1);
9190       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9191     }
9192
9193   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9194                                                    : ordered_code;
9195   return fold_build1 (TRUTH_NOT_EXPR, type,
9196                       fold_build2 (code, type, arg0, arg1));
9197 }
9198
9199 /* Used by constant folding to simplify calls to builtin functions.  EXP is
9200    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
9201    result of the function call is ignored.  This function returns NULL_TREE
9202    if no simplification was possible.  */
9203
9204 static tree
9205 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9206 {
9207   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9208   enum built_in_function fcode;
9209
9210   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9211     return targetm.fold_builtin (fndecl, arglist, ignore);
9212
9213   fcode = DECL_FUNCTION_CODE (fndecl);
9214   switch (fcode)
9215     {
9216     case BUILT_IN_FPUTS:
9217       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9218
9219     case BUILT_IN_FPUTS_UNLOCKED:
9220       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9221
9222     case BUILT_IN_STRSTR:
9223       return fold_builtin_strstr (arglist, type);
9224
9225     case BUILT_IN_STRCAT:
9226       return fold_builtin_strcat (arglist);
9227
9228     case BUILT_IN_STRNCAT:
9229       return fold_builtin_strncat (arglist);
9230
9231     case BUILT_IN_STRSPN:
9232       return fold_builtin_strspn (arglist);
9233
9234     case BUILT_IN_STRCSPN:
9235       return fold_builtin_strcspn (arglist);
9236
9237     case BUILT_IN_STRCHR:
9238     case BUILT_IN_INDEX:
9239       return fold_builtin_strchr (arglist, type);
9240
9241     case BUILT_IN_STRRCHR:
9242     case BUILT_IN_RINDEX:
9243       return fold_builtin_strrchr (arglist, type);
9244
9245     case BUILT_IN_STRCPY:
9246       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9247
9248     case BUILT_IN_STRNCPY:
9249       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9250
9251     case BUILT_IN_STRCMP:
9252       return fold_builtin_strcmp (arglist);
9253
9254     case BUILT_IN_STRNCMP:
9255       return fold_builtin_strncmp (arglist);
9256
9257     case BUILT_IN_STRPBRK:
9258       return fold_builtin_strpbrk (arglist, type);
9259
9260     case BUILT_IN_BCMP:
9261     case BUILT_IN_MEMCMP:
9262       return fold_builtin_memcmp (arglist);
9263
9264     case BUILT_IN_SPRINTF:
9265       return fold_builtin_sprintf (arglist, ignore);
9266
9267     case BUILT_IN_CONSTANT_P:
9268       {
9269         tree val;
9270
9271         val = fold_builtin_constant_p (arglist);
9272         /* Gimplification will pull the CALL_EXPR for the builtin out of
9273            an if condition.  When not optimizing, we'll not CSE it back.
9274            To avoid link error types of regressions, return false now.  */
9275         if (!val && !optimize)
9276           val = integer_zero_node;
9277
9278         return val;
9279       }
9280
9281     case BUILT_IN_EXPECT:
9282       return fold_builtin_expect (arglist);
9283
9284     case BUILT_IN_CLASSIFY_TYPE:
9285       return fold_builtin_classify_type (arglist);
9286
9287     case BUILT_IN_STRLEN:
9288       return fold_builtin_strlen (arglist);
9289
9290     CASE_FLT_FN (BUILT_IN_FABS):
9291       return fold_builtin_fabs (arglist, type);
9292
9293     case BUILT_IN_ABS:
9294     case BUILT_IN_LABS:
9295     case BUILT_IN_LLABS:
9296     case BUILT_IN_IMAXABS:
9297       return fold_builtin_abs (arglist, type);
9298
9299     CASE_FLT_FN (BUILT_IN_CONJ):
9300       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9301         return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9302       break;
9303
9304     CASE_FLT_FN (BUILT_IN_CREAL):
9305       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9306         return non_lvalue (fold_build1 (REALPART_EXPR, type,
9307                                         TREE_VALUE (arglist)));
9308       break;
9309
9310     CASE_FLT_FN (BUILT_IN_CIMAG):
9311       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9312         return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9313                                         TREE_VALUE (arglist)));
9314       break;
9315
9316     CASE_FLT_FN (BUILT_IN_CABS):
9317       return fold_builtin_cabs (arglist, type, fndecl);
9318
9319     CASE_FLT_FN (BUILT_IN_SQRT):
9320       return fold_builtin_sqrt (arglist, type);
9321
9322     CASE_FLT_FN (BUILT_IN_CBRT):
9323       return fold_builtin_cbrt (arglist, type);
9324
9325     CASE_FLT_FN (BUILT_IN_ASIN):
9326       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9327         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9328                              &dconstm1, &dconst1, true);
9329     break;
9330
9331     CASE_FLT_FN (BUILT_IN_ACOS):
9332       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9333         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9334                              &dconstm1, &dconst1, true);
9335     break;
9336
9337     CASE_FLT_FN (BUILT_IN_ATAN):
9338       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9339         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9340                              NULL, NULL, 0);
9341     break;
9342
9343     CASE_FLT_FN (BUILT_IN_ASINH):
9344       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9345         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9346                              NULL, NULL, 0);
9347     break;
9348
9349     CASE_FLT_FN (BUILT_IN_ACOSH):
9350       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9351         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9352                              &dconst1, NULL, true);
9353     break;
9354
9355     CASE_FLT_FN (BUILT_IN_ATANH):
9356       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9357         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9358                              &dconstm1, &dconst1, false);
9359     break;
9360
9361     CASE_FLT_FN (BUILT_IN_SIN):
9362       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9363         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9364                              NULL, NULL, 0);
9365     break;
9366
9367     CASE_FLT_FN (BUILT_IN_COS):
9368       return fold_builtin_cos (arglist, type, fndecl);
9369
9370     CASE_FLT_FN (BUILT_IN_TAN):
9371       return fold_builtin_tan (arglist, type);
9372
9373     CASE_FLT_FN (BUILT_IN_SINCOS):
9374       return fold_builtin_sincos (arglist);
9375
9376     CASE_FLT_FN (BUILT_IN_CEXP):
9377       return fold_builtin_cexp (arglist, type);
9378
9379     CASE_FLT_FN (BUILT_IN_CEXPI):
9380       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9381         return do_mpfr_sincos (TREE_VALUE (arglist), NULL_TREE, NULL_TREE);
9382
9383     CASE_FLT_FN (BUILT_IN_SINH):
9384       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9385         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9386                              NULL, NULL, 0);
9387     break;
9388
9389     CASE_FLT_FN (BUILT_IN_COSH):
9390       return fold_builtin_cosh (arglist, type, fndecl);
9391
9392     CASE_FLT_FN (BUILT_IN_TANH):
9393       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9394         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9395                              NULL, NULL, 0);
9396     break;
9397
9398     CASE_FLT_FN (BUILT_IN_ERF):
9399       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9400         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9401                              NULL, NULL, 0);
9402     break;
9403
9404     CASE_FLT_FN (BUILT_IN_ERFC):
9405       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9406         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9407                              NULL, NULL, 0);
9408     break;
9409
9410     CASE_FLT_FN (BUILT_IN_TGAMMA):
9411       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9412         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9413                              NULL, NULL, 0);
9414     break;
9415  
9416     CASE_FLT_FN (BUILT_IN_EXP):
9417       return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9418
9419     CASE_FLT_FN (BUILT_IN_EXP2):
9420       return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9421
9422     CASE_FLT_FN (BUILT_IN_EXP10):
9423     CASE_FLT_FN (BUILT_IN_POW10):
9424       return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9425
9426     CASE_FLT_FN (BUILT_IN_EXPM1):
9427       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9428         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9429                              NULL, NULL, 0);
9430     break;
9431  
9432     CASE_FLT_FN (BUILT_IN_LOG):
9433       return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9434
9435     CASE_FLT_FN (BUILT_IN_LOG2):
9436       return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9437
9438     CASE_FLT_FN (BUILT_IN_LOG10):
9439       return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9440
9441     CASE_FLT_FN (BUILT_IN_LOG1P):
9442       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9443         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9444                              &dconstm1, NULL, false);
9445     break;
9446
9447     CASE_FLT_FN (BUILT_IN_ATAN2):
9448       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9449         return do_mpfr_arg2 (TREE_VALUE (arglist),
9450                              TREE_VALUE (TREE_CHAIN (arglist)),
9451                              type, mpfr_atan2);
9452     break;
9453
9454     CASE_FLT_FN (BUILT_IN_FMA):
9455       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9456         return do_mpfr_arg3 (TREE_VALUE (arglist),
9457                              TREE_VALUE (TREE_CHAIN (arglist)),
9458                              TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9459                              type, mpfr_fma);
9460     break;
9461
9462     CASE_FLT_FN (BUILT_IN_FMIN):
9463       return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9464
9465     CASE_FLT_FN (BUILT_IN_FMAX):
9466       return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9467
9468     CASE_FLT_FN (BUILT_IN_HYPOT):
9469       return fold_builtin_hypot (fndecl, arglist, type);
9470     
9471     CASE_FLT_FN (BUILT_IN_POW):
9472       return fold_builtin_pow (fndecl, arglist, type);
9473
9474     CASE_FLT_FN (BUILT_IN_POWI):
9475       return fold_builtin_powi (fndecl, arglist, type);
9476
9477     CASE_FLT_FN (BUILT_IN_INF):
9478     case BUILT_IN_INFD32:
9479     case BUILT_IN_INFD64:
9480     case BUILT_IN_INFD128:
9481       return fold_builtin_inf (type, true);
9482
9483     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9484       return fold_builtin_inf (type, false);
9485
9486     CASE_FLT_FN (BUILT_IN_NAN):
9487     case BUILT_IN_NAND32:
9488     case BUILT_IN_NAND64:
9489     case BUILT_IN_NAND128:
9490       return fold_builtin_nan (arglist, type, true);
9491
9492     CASE_FLT_FN (BUILT_IN_NANS):
9493       return fold_builtin_nan (arglist, type, false);
9494
9495     CASE_FLT_FN (BUILT_IN_FLOOR):
9496       return fold_builtin_floor (fndecl, arglist);
9497
9498     CASE_FLT_FN (BUILT_IN_CEIL):
9499       return fold_builtin_ceil (fndecl, arglist);
9500
9501     CASE_FLT_FN (BUILT_IN_TRUNC):
9502       return fold_builtin_trunc (fndecl, arglist);
9503
9504     CASE_FLT_FN (BUILT_IN_ROUND):
9505       return fold_builtin_round (fndecl, arglist);
9506
9507     CASE_FLT_FN (BUILT_IN_NEARBYINT):
9508     CASE_FLT_FN (BUILT_IN_RINT):
9509       return fold_trunc_transparent_mathfn (fndecl, arglist);
9510
9511     CASE_FLT_FN (BUILT_IN_LCEIL):
9512     CASE_FLT_FN (BUILT_IN_LLCEIL):
9513     CASE_FLT_FN (BUILT_IN_LFLOOR):
9514     CASE_FLT_FN (BUILT_IN_LLFLOOR):
9515     CASE_FLT_FN (BUILT_IN_LROUND):
9516     CASE_FLT_FN (BUILT_IN_LLROUND):
9517       return fold_builtin_int_roundingfn (fndecl, arglist);
9518
9519     CASE_FLT_FN (BUILT_IN_LRINT):
9520     CASE_FLT_FN (BUILT_IN_LLRINT):
9521       return fold_fixed_mathfn (fndecl, arglist);
9522
9523     case BUILT_IN_BSWAP32:
9524     case BUILT_IN_BSWAP64:
9525       return fold_builtin_bswap (fndecl, arglist);
9526
9527     CASE_INT_FN (BUILT_IN_FFS):
9528     CASE_INT_FN (BUILT_IN_CLZ):
9529     CASE_INT_FN (BUILT_IN_CTZ):
9530     CASE_INT_FN (BUILT_IN_POPCOUNT):
9531     CASE_INT_FN (BUILT_IN_PARITY):
9532       return fold_builtin_bitop (fndecl, arglist);
9533
9534     case BUILT_IN_MEMSET:
9535       return fold_builtin_memset (arglist, type, ignore);
9536
9537     case BUILT_IN_MEMCPY:
9538       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9539
9540     case BUILT_IN_MEMPCPY:
9541       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9542
9543     case BUILT_IN_MEMMOVE:
9544       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9545
9546     case BUILT_IN_BZERO:
9547       return fold_builtin_bzero (arglist, ignore);
9548
9549     case BUILT_IN_BCOPY:
9550       return fold_builtin_bcopy (arglist, ignore);
9551
9552     CASE_FLT_FN (BUILT_IN_SIGNBIT):
9553       return fold_builtin_signbit (fndecl, arglist);
9554
9555     case BUILT_IN_ISASCII:
9556       return fold_builtin_isascii (arglist);
9557
9558     case BUILT_IN_TOASCII:
9559       return fold_builtin_toascii (arglist);
9560
9561     case BUILT_IN_ISDIGIT:
9562       return fold_builtin_isdigit (arglist);
9563
9564     CASE_FLT_FN (BUILT_IN_COPYSIGN):
9565       return fold_builtin_copysign (fndecl, arglist, type);
9566
9567     CASE_FLT_FN (BUILT_IN_FINITE):
9568     case BUILT_IN_FINITED32:
9569     case BUILT_IN_FINITED64:
9570     case BUILT_IN_FINITED128:
9571       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9572
9573     CASE_FLT_FN (BUILT_IN_ISINF):
9574     case BUILT_IN_ISINFD32:
9575     case BUILT_IN_ISINFD64:
9576     case BUILT_IN_ISINFD128:
9577       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9578
9579     CASE_FLT_FN (BUILT_IN_ISNAN):
9580     case BUILT_IN_ISNAND32:
9581     case BUILT_IN_ISNAND64:
9582     case BUILT_IN_ISNAND128:
9583       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9584
9585     case BUILT_IN_ISGREATER:
9586       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9587     case BUILT_IN_ISGREATEREQUAL:
9588       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9589     case BUILT_IN_ISLESS:
9590       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9591     case BUILT_IN_ISLESSEQUAL:
9592       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9593     case BUILT_IN_ISLESSGREATER:
9594       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9595     case BUILT_IN_ISUNORDERED:
9596       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9597                                          NOP_EXPR);
9598
9599       /* We do the folding for va_start in the expander.  */
9600     case BUILT_IN_VA_START:
9601       break;
9602
9603     case BUILT_IN_OBJECT_SIZE:
9604       return fold_builtin_object_size (arglist);
9605     case BUILT_IN_MEMCPY_CHK:
9606     case BUILT_IN_MEMPCPY_CHK:
9607     case BUILT_IN_MEMMOVE_CHK:
9608     case BUILT_IN_MEMSET_CHK:
9609       return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9610                                       DECL_FUNCTION_CODE (fndecl));
9611     case BUILT_IN_STRCPY_CHK:
9612     case BUILT_IN_STPCPY_CHK:
9613       return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9614                                       DECL_FUNCTION_CODE (fndecl));
9615     case BUILT_IN_STRNCPY_CHK:
9616       return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9617     case BUILT_IN_STRCAT_CHK:
9618       return fold_builtin_strcat_chk (fndecl, arglist);
9619     case BUILT_IN_STRNCAT_CHK:
9620       return fold_builtin_strncat_chk (fndecl, arglist);
9621     case BUILT_IN_SPRINTF_CHK:
9622     case BUILT_IN_VSPRINTF_CHK:
9623       return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9624     case BUILT_IN_SNPRINTF_CHK:
9625     case BUILT_IN_VSNPRINTF_CHK:
9626       return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9627                                         DECL_FUNCTION_CODE (fndecl));
9628
9629     case BUILT_IN_PRINTF:
9630     case BUILT_IN_PRINTF_UNLOCKED:
9631     case BUILT_IN_VPRINTF:
9632     case BUILT_IN_PRINTF_CHK:
9633     case BUILT_IN_VPRINTF_CHK:
9634       return fold_builtin_printf (fndecl, arglist, ignore,
9635                                   DECL_FUNCTION_CODE (fndecl));
9636
9637     case BUILT_IN_FPRINTF:
9638     case BUILT_IN_FPRINTF_UNLOCKED:
9639     case BUILT_IN_VFPRINTF:
9640     case BUILT_IN_FPRINTF_CHK:
9641     case BUILT_IN_VFPRINTF_CHK:
9642       return fold_builtin_fprintf (fndecl, arglist, ignore,
9643                                    DECL_FUNCTION_CODE (fndecl));
9644
9645     default:
9646       break;
9647     }
9648
9649   return 0;
9650 }
9651
9652 /* A wrapper function for builtin folding that prevents warnings for
9653    "statement without effect" and the like, caused by removing the
9654    call node earlier than the warning is generated.  */
9655
9656 tree
9657 fold_builtin (tree fndecl, tree arglist, bool ignore)
9658 {
9659   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9660   if (exp && !ignore)
9661     {
9662       exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9663       TREE_NO_WARNING (exp) = 1;
9664     }
9665
9666   return exp;
9667 }
9668
9669 /* Conveniently construct a function call expression.  */
9670
9671 tree
9672 build_function_call_expr (tree fn, tree arglist)
9673 {
9674   tree call_expr;
9675
9676   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9677   return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9678                       call_expr, arglist, NULL_TREE);
9679 }
9680
9681 /* This function validates the types of a function call argument list
9682    represented as a tree chain of parameters against a specified list
9683    of tree_codes.  If the last specifier is a 0, that represents an
9684    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9685
9686 int
9687 validate_arglist (tree arglist, ...)
9688 {
9689   enum tree_code code;
9690   int res = 0;
9691   va_list ap;
9692
9693   va_start (ap, arglist);
9694
9695   do
9696     {
9697       code = va_arg (ap, enum tree_code);
9698       switch (code)
9699         {
9700         case 0:
9701           /* This signifies an ellipses, any further arguments are all ok.  */
9702           res = 1;
9703           goto end;
9704         case VOID_TYPE:
9705           /* This signifies an endlink, if no arguments remain, return
9706              true, otherwise return false.  */
9707           res = arglist == 0;
9708           goto end;
9709         default:
9710           /* If no parameters remain or the parameter's code does not
9711              match the specified code, return false.  Otherwise continue
9712              checking any remaining arguments.  */
9713           if (arglist == 0)
9714             goto end;
9715           if (code == POINTER_TYPE)
9716             {
9717               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9718                 goto end;
9719             }
9720           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9721             goto end;
9722           break;
9723         }
9724       arglist = TREE_CHAIN (arglist);
9725     }
9726   while (1);
9727
9728   /* We need gotos here since we can only have one VA_CLOSE in a
9729      function.  */
9730  end: ;
9731   va_end (ap);
9732
9733   return res;
9734 }
9735
9736 /* Default target-specific builtin expander that does nothing.  */
9737
9738 rtx
9739 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9740                         rtx target ATTRIBUTE_UNUSED,
9741                         rtx subtarget ATTRIBUTE_UNUSED,
9742                         enum machine_mode mode ATTRIBUTE_UNUSED,
9743                         int ignore ATTRIBUTE_UNUSED)
9744 {
9745   return NULL_RTX;
9746 }
9747
9748 /* Returns true is EXP represents data that would potentially reside
9749    in a readonly section.  */
9750
9751 static bool
9752 readonly_data_expr (tree exp)
9753 {
9754   STRIP_NOPS (exp);
9755
9756   if (TREE_CODE (exp) != ADDR_EXPR)
9757     return false;
9758
9759   exp = get_base_address (TREE_OPERAND (exp, 0));
9760   if (!exp)
9761     return false;
9762
9763   /* Make sure we call decl_readonly_section only for trees it
9764      can handle (since it returns true for everything it doesn't
9765      understand).  */
9766   if (TREE_CODE (exp) == STRING_CST
9767       || TREE_CODE (exp) == CONSTRUCTOR
9768       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9769     return decl_readonly_section (exp, 0);
9770   else
9771     return false;
9772 }
9773
9774 /* Simplify a call to the strstr builtin.
9775
9776    Return 0 if no simplification was possible, otherwise return the
9777    simplified form of the call as a tree.
9778
9779    The simplified form may be a constant or other expression which
9780    computes the same value, but in a more efficient manner (including
9781    calls to other builtin functions).
9782
9783    The call may contain arguments which need to be evaluated, but
9784    which are not useful to determine the result of the call.  In
9785    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9786    COMPOUND_EXPR will be an argument which must be evaluated.
9787    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9788    COMPOUND_EXPR in the chain will contain the tree for the simplified
9789    form of the builtin function call.  */
9790
9791 static tree
9792 fold_builtin_strstr (tree arglist, tree type)
9793 {
9794   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9795     return 0;
9796   else
9797     {
9798       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9799       tree fn;
9800       const char *p1, *p2;
9801
9802       p2 = c_getstr (s2);
9803       if (p2 == NULL)
9804         return 0;
9805
9806       p1 = c_getstr (s1);
9807       if (p1 != NULL)
9808         {
9809           const char *r = strstr (p1, p2);
9810           tree tem;
9811
9812           if (r == NULL)
9813             return build_int_cst (TREE_TYPE (s1), 0);
9814
9815           /* Return an offset into the constant string argument.  */
9816           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9817                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9818           return fold_convert (type, tem);
9819         }
9820
9821       /* The argument is const char *, and the result is char *, so we need
9822          a type conversion here to avoid a warning.  */
9823       if (p2[0] == '\0')
9824         return fold_convert (type, s1);
9825
9826       if (p2[1] != '\0')
9827         return 0;
9828
9829       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9830       if (!fn)
9831         return 0;
9832
9833       /* New argument list transforming strstr(s1, s2) to
9834          strchr(s1, s2[0]).  */
9835       arglist = build_tree_list (NULL_TREE,
9836                                  build_int_cst (NULL_TREE, p2[0]));
9837       arglist = tree_cons (NULL_TREE, s1, arglist);
9838       return build_function_call_expr (fn, arglist);
9839     }
9840 }
9841
9842 /* Simplify a call to the strchr builtin.
9843
9844    Return 0 if no simplification was possible, otherwise return the
9845    simplified form of the call as a tree.
9846
9847    The simplified form may be a constant or other expression which
9848    computes the same value, but in a more efficient manner (including
9849    calls to other builtin functions).
9850
9851    The call may contain arguments which need to be evaluated, but
9852    which are not useful to determine the result of the call.  In
9853    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9854    COMPOUND_EXPR will be an argument which must be evaluated.
9855    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9856    COMPOUND_EXPR in the chain will contain the tree for the simplified
9857    form of the builtin function call.  */
9858
9859 static tree
9860 fold_builtin_strchr (tree arglist, tree type)
9861 {
9862   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9863     return 0;
9864   else
9865     {
9866       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9867       const char *p1;
9868
9869       if (TREE_CODE (s2) != INTEGER_CST)
9870         return 0;
9871
9872       p1 = c_getstr (s1);
9873       if (p1 != NULL)
9874         {
9875           char c;
9876           const char *r;
9877           tree tem;
9878
9879           if (target_char_cast (s2, &c))
9880             return 0;
9881
9882           r = strchr (p1, c);
9883
9884           if (r == NULL)
9885             return build_int_cst (TREE_TYPE (s1), 0);
9886
9887           /* Return an offset into the constant string argument.  */
9888           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9889                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9890           return fold_convert (type, tem);
9891         }
9892       return 0;
9893     }
9894 }
9895
9896 /* Simplify a call to the strrchr 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_strrchr (tree arglist, tree type)
9915 {
9916   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_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;
9923
9924       if (TREE_CODE (s2) != INTEGER_CST)
9925         return 0;
9926
9927       p1 = c_getstr (s1);
9928       if (p1 != NULL)
9929         {
9930           char c;
9931           const char *r;
9932           tree tem;
9933
9934           if (target_char_cast (s2, &c))
9935             return 0;
9936
9937           r = strrchr (p1, c);
9938
9939           if (r == NULL)
9940             return build_int_cst (TREE_TYPE (s1), 0);
9941
9942           /* Return an offset into the constant string argument.  */
9943           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9944                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9945           return fold_convert (type, tem);
9946         }
9947
9948       if (! integer_zerop (s2))
9949         return 0;
9950
9951       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9952       if (!fn)
9953         return 0;
9954
9955       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9956       return build_function_call_expr (fn, arglist);
9957     }
9958 }
9959
9960 /* Simplify a call to the strpbrk builtin.
9961
9962    Return 0 if no simplification was possible, otherwise return the
9963    simplified form of the call as a tree.
9964
9965    The simplified form may be a constant or other expression which
9966    computes the same value, but in a more efficient manner (including
9967    calls to other builtin functions).
9968
9969    The call may contain arguments which need to be evaluated, but
9970    which are not useful to determine the result of the call.  In
9971    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9972    COMPOUND_EXPR will be an argument which must be evaluated.
9973    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9974    COMPOUND_EXPR in the chain will contain the tree for the simplified
9975    form of the builtin function call.  */
9976
9977 static tree
9978 fold_builtin_strpbrk (tree arglist, tree type)
9979 {
9980   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9981     return 0;
9982   else
9983     {
9984       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9985       tree fn;
9986       const char *p1, *p2;
9987
9988       p2 = c_getstr (s2);
9989       if (p2 == NULL)
9990         return 0;
9991
9992       p1 = c_getstr (s1);
9993       if (p1 != NULL)
9994         {
9995           const char *r = strpbrk (p1, p2);
9996           tree tem;
9997
9998           if (r == NULL)
9999             return build_int_cst (TREE_TYPE (s1), 0);
10000
10001           /* Return an offset into the constant string argument.  */
10002           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
10003                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
10004           return fold_convert (type, tem);
10005         }
10006
10007       if (p2[0] == '\0')
10008         /* strpbrk(x, "") == NULL.
10009            Evaluate and ignore s1 in case it had side-effects.  */
10010         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
10011
10012       if (p2[1] != '\0')
10013         return 0;  /* Really call strpbrk.  */
10014
10015       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
10016       if (!fn)
10017         return 0;
10018
10019       /* New argument list transforming strpbrk(s1, s2) to
10020          strchr(s1, s2[0]).  */
10021       arglist = build_tree_list (NULL_TREE,
10022                                  build_int_cst (NULL_TREE, p2[0]));
10023       arglist = tree_cons (NULL_TREE, s1, arglist);
10024       return build_function_call_expr (fn, arglist);
10025     }
10026 }
10027
10028 /* Simplify a call to the strcat builtin.
10029
10030    Return 0 if no simplification was possible, otherwise return the
10031    simplified form of the call as a tree.
10032
10033    The simplified form may be a constant or other expression which
10034    computes the same value, but in a more efficient manner (including
10035    calls to other builtin functions).
10036
10037    The call may contain arguments which need to be evaluated, but
10038    which are not useful to determine the result of the call.  In
10039    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10040    COMPOUND_EXPR will be an argument which must be evaluated.
10041    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10042    COMPOUND_EXPR in the chain will contain the tree for the simplified
10043    form of the builtin function call.  */
10044
10045 static tree
10046 fold_builtin_strcat (tree arglist)
10047 {
10048   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10049     return 0;
10050   else
10051     {
10052       tree dst = TREE_VALUE (arglist),
10053         src = TREE_VALUE (TREE_CHAIN (arglist));
10054       const char *p = c_getstr (src);
10055
10056       /* If the string length is zero, return the dst parameter.  */
10057       if (p && *p == '\0')
10058         return dst;
10059
10060       return 0;
10061     }
10062 }
10063
10064 /* Simplify a call to the strncat builtin.
10065
10066    Return 0 if no simplification was possible, otherwise return the
10067    simplified form of the call as a tree.
10068
10069    The simplified form may be a constant or other expression which
10070    computes the same value, but in a more efficient manner (including
10071    calls to other builtin functions).
10072
10073    The call may contain arguments which need to be evaluated, but
10074    which are not useful to determine the result of the call.  In
10075    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10076    COMPOUND_EXPR will be an argument which must be evaluated.
10077    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10078    COMPOUND_EXPR in the chain will contain the tree for the simplified
10079    form of the builtin function call.  */
10080
10081 static tree
10082 fold_builtin_strncat (tree arglist)
10083 {
10084   if (!validate_arglist (arglist,
10085                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10086     return 0;
10087   else
10088     {
10089       tree dst = TREE_VALUE (arglist);
10090       tree src = TREE_VALUE (TREE_CHAIN (arglist));
10091       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10092       const char *p = c_getstr (src);
10093
10094       /* If the requested length is zero, or the src parameter string
10095          length is zero, return the dst parameter.  */
10096       if (integer_zerop (len) || (p && *p == '\0'))
10097         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
10098
10099       /* If the requested len is greater than or equal to the string
10100          length, call strcat.  */
10101       if (TREE_CODE (len) == INTEGER_CST && p
10102           && compare_tree_int (len, strlen (p)) >= 0)
10103         {
10104           tree newarglist
10105             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
10106           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
10107
10108           /* If the replacement _DECL isn't initialized, don't do the
10109              transformation.  */
10110           if (!fn)
10111             return 0;
10112
10113           return build_function_call_expr (fn, newarglist);
10114         }
10115       return 0;
10116     }
10117 }
10118
10119 /* Simplify a call to the strspn builtin.
10120
10121    Return 0 if no simplification was possible, otherwise return the
10122    simplified form of the call as a tree.
10123
10124    The simplified form may be a constant or other expression which
10125    computes the same value, but in a more efficient manner (including
10126    calls to other builtin functions).
10127
10128    The call may contain arguments which need to be evaluated, but
10129    which are not useful to determine the result of the call.  In
10130    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10131    COMPOUND_EXPR will be an argument which must be evaluated.
10132    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10133    COMPOUND_EXPR in the chain will contain the tree for the simplified
10134    form of the builtin function call.  */
10135
10136 static tree
10137 fold_builtin_strspn (tree arglist)
10138 {
10139   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10140     return 0;
10141   else
10142     {
10143       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10144       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10145
10146       /* If both arguments are constants, evaluate at compile-time.  */
10147       if (p1 && p2)
10148         {
10149           const size_t r = strspn (p1, p2);
10150           return size_int (r);
10151         }
10152
10153       /* If either argument is "", return 0.  */
10154       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
10155         /* Evaluate and ignore both arguments in case either one has
10156            side-effects.  */
10157         return omit_two_operands (integer_type_node, integer_zero_node,
10158                                   s1, s2);
10159       return 0;
10160     }
10161 }
10162
10163 /* Simplify a call to the strcspn builtin.
10164
10165    Return 0 if no simplification was possible, otherwise return the
10166    simplified form of the call as a tree.
10167
10168    The simplified form may be a constant or other expression which
10169    computes the same value, but in a more efficient manner (including
10170    calls to other builtin functions).
10171
10172    The call may contain arguments which need to be evaluated, but
10173    which are not useful to determine the result of the call.  In
10174    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
10175    COMPOUND_EXPR will be an argument which must be evaluated.
10176    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
10177    COMPOUND_EXPR in the chain will contain the tree for the simplified
10178    form of the builtin function call.  */
10179
10180 static tree
10181 fold_builtin_strcspn (tree arglist)
10182 {
10183   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10184     return 0;
10185   else
10186     {
10187       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10188       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10189
10190       /* If both arguments are constants, evaluate at compile-time.  */
10191       if (p1 && p2)
10192         {
10193           const size_t r = strcspn (p1, p2);
10194           return size_int (r);
10195         }
10196
10197       /* If the first argument is "", return 0.  */
10198       if (p1 && *p1 == '\0')
10199         {
10200           /* Evaluate and ignore argument s2 in case it has
10201              side-effects.  */
10202           return omit_one_operand (integer_type_node,
10203                                    integer_zero_node, s2);
10204         }
10205
10206       /* If the second argument is "", return __builtin_strlen(s1).  */
10207       if (p2 && *p2 == '\0')
10208         {
10209           tree newarglist = build_tree_list (NULL_TREE, s1),
10210             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10211
10212           /* If the replacement _DECL isn't initialized, don't do the
10213              transformation.  */
10214           if (!fn)
10215             return 0;
10216
10217           return build_function_call_expr (fn, newarglist);
10218         }
10219       return 0;
10220     }
10221 }
10222
10223 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
10224    by the builtin will be ignored.  UNLOCKED is true is true if this
10225    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
10226    the known length of the string.  Return NULL_TREE if no simplification
10227    was possible.  */
10228
10229 tree
10230 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10231 {
10232   tree fn;
10233   /* If we're using an unlocked function, assume the other unlocked
10234      functions exist explicitly.  */
10235   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10236     : implicit_built_in_decls[BUILT_IN_FPUTC];
10237   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10238     : implicit_built_in_decls[BUILT_IN_FWRITE];
10239
10240   /* If the return value is used, don't do the transformation.  */
10241   if (!ignore)
10242     return 0;
10243
10244   /* Verify the arguments in the original call.  */
10245   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10246     return 0;
10247
10248   if (! len)
10249     len = c_strlen (TREE_VALUE (arglist), 0);
10250
10251   /* Get the length of the string passed to fputs.  If the length
10252      can't be determined, punt.  */
10253   if (!len
10254       || TREE_CODE (len) != INTEGER_CST)
10255     return 0;
10256
10257   switch (compare_tree_int (len, 1))
10258     {
10259     case -1: /* length is 0, delete the call entirely .  */
10260       return omit_one_operand (integer_type_node, integer_zero_node,
10261                                TREE_VALUE (TREE_CHAIN (arglist)));
10262
10263     case 0: /* length is 1, call fputc.  */
10264       {
10265         const char *p = c_getstr (TREE_VALUE (arglist));
10266
10267         if (p != NULL)
10268           {
10269             /* New argument list transforming fputs(string, stream) to
10270                fputc(string[0], stream).  */
10271             arglist = build_tree_list (NULL_TREE,
10272                                        TREE_VALUE (TREE_CHAIN (arglist)));
10273             arglist = tree_cons (NULL_TREE,
10274                                  build_int_cst (NULL_TREE, p[0]),
10275                                  arglist);
10276             fn = fn_fputc;
10277             break;
10278           }
10279       }
10280       /* FALLTHROUGH */
10281     case 1: /* length is greater than 1, call fwrite.  */
10282       {
10283         tree string_arg;
10284
10285         /* If optimizing for size keep fputs.  */
10286         if (optimize_size)
10287           return 0;
10288         string_arg = TREE_VALUE (arglist);
10289         /* New argument list transforming fputs(string, stream) to
10290            fwrite(string, 1, len, stream).  */
10291         arglist = build_tree_list (NULL_TREE,
10292                                    TREE_VALUE (TREE_CHAIN (arglist)));
10293         arglist = tree_cons (NULL_TREE, len, arglist);
10294         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10295         arglist = tree_cons (NULL_TREE, string_arg, arglist);
10296         fn = fn_fwrite;
10297         break;
10298       }
10299     default:
10300       gcc_unreachable ();
10301     }
10302
10303   /* If the replacement _DECL isn't initialized, don't do the
10304      transformation.  */
10305   if (!fn)
10306     return 0;
10307
10308   /* These optimizations are only performed when the result is ignored,
10309      hence there's no need to cast the result to integer_type_node.  */
10310   return build_function_call_expr (fn, arglist);
10311 }
10312
10313 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10314    produced.  False otherwise.  This is done so that we don't output the error
10315    or warning twice or three times.  */
10316 bool
10317 fold_builtin_next_arg (tree arglist)
10318 {
10319   tree fntype = TREE_TYPE (current_function_decl);
10320
10321   if (TYPE_ARG_TYPES (fntype) == 0
10322       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10323           == void_type_node))
10324     {
10325       error ("%<va_start%> used in function with fixed args");
10326       return true;
10327     }
10328   else if (!arglist)
10329     {
10330       /* Evidently an out of date version of <stdarg.h>; can't validate
10331          va_start's second argument, but can still work as intended.  */
10332       warning (0, "%<__builtin_next_arg%> called without an argument");
10333       return true;
10334     }
10335   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10336      when we checked the arguments and if needed issued a warning.  */
10337   else if (!TREE_CHAIN (arglist)
10338            || !integer_zerop (TREE_VALUE (arglist))
10339            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10340            || TREE_CHAIN (TREE_CHAIN (arglist)))
10341     {
10342       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10343       tree arg = TREE_VALUE (arglist);
10344
10345       if (TREE_CHAIN (arglist))
10346         {
10347           error ("%<va_start%> used with too many arguments");
10348           return true;
10349         }
10350
10351       /* Strip off all nops for the sake of the comparison.  This
10352          is not quite the same as STRIP_NOPS.  It does more.
10353          We must also strip off INDIRECT_EXPR for C++ reference
10354          parameters.  */
10355       while (TREE_CODE (arg) == NOP_EXPR
10356              || TREE_CODE (arg) == CONVERT_EXPR
10357              || TREE_CODE (arg) == NON_LVALUE_EXPR
10358              || TREE_CODE (arg) == INDIRECT_REF)
10359         arg = TREE_OPERAND (arg, 0);
10360       if (arg != last_parm)
10361         {
10362           /* FIXME: Sometimes with the tree optimizers we can get the
10363              not the last argument even though the user used the last
10364              argument.  We just warn and set the arg to be the last
10365              argument so that we will get wrong-code because of
10366              it.  */
10367           warning (0, "second parameter of %<va_start%> not last named argument");
10368         }
10369       /* We want to verify the second parameter just once before the tree
10370          optimizers are run and then avoid keeping it in the tree,
10371          as otherwise we could warn even for correct code like:
10372          void foo (int i, ...)
10373          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
10374       TREE_VALUE (arglist) = integer_zero_node;
10375       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10376     }
10377   return false;
10378 }
10379
10380
10381 /* Simplify a call to the sprintf builtin.
10382
10383    Return 0 if no simplification was possible, otherwise return the
10384    simplified form of the call as a tree.  If IGNORED is true, it means that
10385    the caller does not use the returned value of the function.  */
10386
10387 static tree
10388 fold_builtin_sprintf (tree arglist, int ignored)
10389 {
10390   tree call, retval, dest, fmt;
10391   const char *fmt_str = NULL;
10392
10393   /* Verify the required arguments in the original call.  We deal with two
10394      types of sprintf() calls: 'sprintf (str, fmt)' and
10395      'sprintf (dest, "%s", orig)'.  */
10396   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10397       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10398                             VOID_TYPE))
10399     return NULL_TREE;
10400
10401   /* Get the destination string and the format specifier.  */
10402   dest = TREE_VALUE (arglist);
10403   fmt = TREE_VALUE (TREE_CHAIN (arglist));
10404
10405   /* Check whether the format is a literal string constant.  */
10406   fmt_str = c_getstr (fmt);
10407   if (fmt_str == NULL)
10408     return NULL_TREE;
10409
10410   call = NULL_TREE;
10411   retval = NULL_TREE;
10412
10413   if (!init_target_chars())
10414     return 0;
10415
10416   /* If the format doesn't contain % args or %%, use strcpy.  */
10417   if (strchr (fmt_str, target_percent) == NULL)
10418     {
10419       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10420
10421       if (!fn)
10422         return NULL_TREE;
10423
10424       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10425          'format' is known to contain no % formats.  */
10426       arglist = build_tree_list (NULL_TREE, fmt);
10427       arglist = tree_cons (NULL_TREE, dest, arglist);
10428       call = build_function_call_expr (fn, arglist);
10429       if (!ignored)
10430         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10431     }
10432
10433   /* If the format is "%s", use strcpy if the result isn't used.  */
10434   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10435     {
10436       tree fn, orig;
10437       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10438
10439       if (!fn)
10440         return NULL_TREE;
10441
10442       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
10443       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10444       arglist = build_tree_list (NULL_TREE, orig);
10445       arglist = tree_cons (NULL_TREE, dest, arglist);
10446       if (!ignored)
10447         {
10448           retval = c_strlen (orig, 1);
10449           if (!retval || TREE_CODE (retval) != INTEGER_CST)
10450             return NULL_TREE;
10451         }
10452       call = build_function_call_expr (fn, arglist);
10453     }
10454
10455   if (call && retval)
10456     {
10457       retval = fold_convert
10458         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10459          retval);
10460       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10461     }
10462   else
10463     return call;
10464 }
10465
10466 /* Expand a call to __builtin_object_size.  */
10467
10468 rtx
10469 expand_builtin_object_size (tree exp)
10470 {
10471   tree ost;
10472   int object_size_type;
10473   tree fndecl = get_callee_fndecl (exp);
10474   tree arglist = TREE_OPERAND (exp, 1);
10475   location_t locus = EXPR_LOCATION (exp);
10476
10477   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10478     {
10479       error ("%Hfirst argument of %D must be a pointer, second integer constant",
10480              &locus, fndecl);
10481       expand_builtin_trap ();
10482       return const0_rtx;
10483     }
10484
10485   ost = TREE_VALUE (TREE_CHAIN (arglist));
10486   STRIP_NOPS (ost);
10487
10488   if (TREE_CODE (ost) != INTEGER_CST
10489       || tree_int_cst_sgn (ost) < 0
10490       || compare_tree_int (ost, 3) > 0)
10491     {
10492       error ("%Hlast argument of %D is not integer constant between 0 and 3",
10493              &locus, fndecl);
10494       expand_builtin_trap ();
10495       return const0_rtx;
10496     }
10497
10498   object_size_type = tree_low_cst (ost, 0);
10499
10500   return object_size_type < 2 ? constm1_rtx : const0_rtx;
10501 }
10502
10503 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10504    FCODE is the BUILT_IN_* to use.
10505    Return 0 if we failed; the caller should emit a normal call,
10506    otherwise try to get the result in TARGET, if convenient (and in
10507    mode MODE if that's convenient).  */
10508
10509 static rtx
10510 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10511                            enum built_in_function fcode)
10512 {
10513   tree arglist = TREE_OPERAND (exp, 1);
10514   tree dest, src, len, size;
10515
10516   if (!validate_arglist (arglist,
10517                          POINTER_TYPE,
10518                          fcode == BUILT_IN_MEMSET_CHK
10519                          ? INTEGER_TYPE : POINTER_TYPE,
10520                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10521     return 0;
10522
10523   dest = TREE_VALUE (arglist);
10524   src = TREE_VALUE (TREE_CHAIN (arglist));
10525   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10526   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10527
10528   if (! host_integerp (size, 1))
10529     return 0;
10530
10531   if (host_integerp (len, 1) || integer_all_onesp (size))
10532     {
10533       tree fn;
10534
10535       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10536         {
10537           location_t locus = EXPR_LOCATION (exp);
10538           warning (0, "%Hcall to %D will always overflow destination buffer",
10539                    &locus, get_callee_fndecl (exp));
10540           return 0;
10541         }
10542
10543       arglist = build_tree_list (NULL_TREE, len);
10544       arglist = tree_cons (NULL_TREE, src, arglist);
10545       arglist = tree_cons (NULL_TREE, dest, arglist);
10546
10547       fn = NULL_TREE;
10548       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10549          mem{cpy,pcpy,move,set} is available.  */
10550       switch (fcode)
10551         {
10552         case BUILT_IN_MEMCPY_CHK:
10553           fn = built_in_decls[BUILT_IN_MEMCPY];
10554           break;
10555         case BUILT_IN_MEMPCPY_CHK:
10556           fn = built_in_decls[BUILT_IN_MEMPCPY];
10557           break;
10558         case BUILT_IN_MEMMOVE_CHK:
10559           fn = built_in_decls[BUILT_IN_MEMMOVE];
10560           break;
10561         case BUILT_IN_MEMSET_CHK:
10562           fn = built_in_decls[BUILT_IN_MEMSET];
10563           break;
10564         default:
10565           break;
10566         }
10567
10568       if (! fn)
10569         return 0;
10570
10571       fn = build_function_call_expr (fn, arglist);
10572       if (TREE_CODE (fn) == CALL_EXPR)
10573         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10574       return expand_expr (fn, target, mode, EXPAND_NORMAL);
10575     }
10576   else if (fcode == BUILT_IN_MEMSET_CHK)
10577     return 0;
10578   else
10579     {
10580       unsigned int dest_align
10581         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10582
10583       /* If DEST is not a pointer type, call the normal function.  */
10584       if (dest_align == 0)
10585         return 0;
10586
10587       /* If SRC and DEST are the same (and not volatile), do nothing.  */
10588       if (operand_equal_p (src, dest, 0))
10589         {
10590           tree expr;
10591
10592           if (fcode != BUILT_IN_MEMPCPY_CHK)
10593             {
10594               /* Evaluate and ignore LEN in case it has side-effects.  */
10595               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10596               return expand_expr (dest, target, mode, EXPAND_NORMAL);
10597             }
10598
10599           len = fold_convert (TREE_TYPE (dest), len);
10600           expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10601           return expand_expr (expr, target, mode, EXPAND_NORMAL);
10602         }
10603
10604       /* __memmove_chk special case.  */
10605       if (fcode == BUILT_IN_MEMMOVE_CHK)
10606         {
10607           unsigned int src_align
10608             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10609
10610           if (src_align == 0)
10611             return 0;
10612
10613           /* If src is categorized for a readonly section we can use
10614              normal __memcpy_chk.  */
10615           if (readonly_data_expr (src))
10616             {
10617               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10618               if (!fn)
10619                 return 0;
10620               fn = build_function_call_expr (fn, arglist);
10621               if (TREE_CODE (fn) == CALL_EXPR)
10622                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10623               return expand_expr (fn, target, mode, EXPAND_NORMAL);
10624             }
10625         }
10626       return 0;
10627     }
10628 }
10629
10630 /* Emit warning if a buffer overflow is detected at compile time.  */
10631
10632 static void
10633 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10634 {
10635   int arg_mask, is_strlen = 0;
10636   tree arglist = TREE_OPERAND (exp, 1), a;
10637   tree len, size;
10638   location_t locus;
10639
10640   switch (fcode)
10641     {
10642     case BUILT_IN_STRCPY_CHK:
10643     case BUILT_IN_STPCPY_CHK:
10644     /* For __strcat_chk the warning will be emitted only if overflowing
10645        by at least strlen (dest) + 1 bytes.  */
10646     case BUILT_IN_STRCAT_CHK:
10647       arg_mask = 6;
10648       is_strlen = 1;
10649       break;
10650     case BUILT_IN_STRNCAT_CHK:
10651     /* For __strncat_chk the warning will be emitted only if overflowing
10652        by at least strlen (dest) + 1 bytes.  */
10653       arg_mask = 12;
10654       break;
10655     case BUILT_IN_STRNCPY_CHK:
10656       arg_mask = 12;
10657       break;
10658     case BUILT_IN_SNPRINTF_CHK:
10659     case BUILT_IN_VSNPRINTF_CHK:
10660       arg_mask = 10;
10661       break;
10662     default:
10663       gcc_unreachable ();
10664     }
10665
10666   len = NULL_TREE;
10667   size = NULL_TREE;
10668   for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10669     if (arg_mask & 1)
10670       {
10671         if (len)
10672           size = a;
10673         else
10674           len = a;
10675       }
10676
10677   if (!len || !size)
10678     return;
10679
10680   len = TREE_VALUE (len);
10681   size = TREE_VALUE (size);
10682
10683   if (! host_integerp (size, 1) || integer_all_onesp (size))
10684     return;
10685
10686   if (is_strlen)
10687     {
10688       len = c_strlen (len, 1);
10689       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10690         return;
10691     }
10692   else if (fcode == BUILT_IN_STRNCAT_CHK)
10693     {
10694       tree src = TREE_VALUE (TREE_CHAIN (arglist));
10695       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10696         return;
10697       src = c_strlen (src, 1);
10698       if (! src || ! host_integerp (src, 1))
10699         {
10700           locus = EXPR_LOCATION (exp);
10701           warning (0, "%Hcall to %D might overflow destination buffer",
10702                    &locus, get_callee_fndecl (exp));
10703           return;
10704         }
10705       else if (tree_int_cst_lt (src, size))
10706         return;
10707     }
10708   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10709     return;
10710
10711   locus = EXPR_LOCATION (exp);
10712   warning (0, "%Hcall to %D will always overflow destination buffer",
10713            &locus, get_callee_fndecl (exp));
10714 }
10715
10716 /* Emit warning if a buffer overflow is detected at compile time
10717    in __sprintf_chk/__vsprintf_chk calls.  */
10718
10719 static void
10720 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10721 {
10722   tree arglist = TREE_OPERAND (exp, 1);
10723   tree dest, size, len, fmt, flag;
10724   const char *fmt_str;
10725
10726   /* Verify the required arguments in the original call.  */
10727   if (! arglist)
10728     return;
10729   dest = TREE_VALUE (arglist);
10730   arglist = TREE_CHAIN (arglist);
10731   if (! arglist)
10732     return;
10733   flag = TREE_VALUE (arglist);
10734   arglist = TREE_CHAIN (arglist);
10735   if (! arglist)
10736     return;
10737   size = TREE_VALUE (arglist);
10738   arglist = TREE_CHAIN (arglist);
10739   if (! arglist)
10740     return;
10741   fmt = TREE_VALUE (arglist);
10742   arglist = TREE_CHAIN (arglist);
10743
10744   if (! host_integerp (size, 1) || integer_all_onesp (size))
10745     return;
10746
10747   /* Check whether the format is a literal string constant.  */
10748   fmt_str = c_getstr (fmt);
10749   if (fmt_str == NULL)
10750     return;
10751
10752   if (!init_target_chars())
10753     return;
10754
10755   /* If the format doesn't contain % args or %%, we know its size.  */
10756   if (strchr (fmt_str, target_percent) == 0)
10757     len = build_int_cstu (size_type_node, strlen (fmt_str));
10758   /* If the format is "%s" and first ... argument is a string literal,
10759      we know it too.  */
10760   else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10761     {
10762       tree arg;
10763
10764       if (! arglist)
10765         return;
10766       arg = TREE_VALUE (arglist);
10767       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10768         return;
10769
10770       len = c_strlen (arg, 1);
10771       if (!len || ! host_integerp (len, 1))
10772         return;
10773     }
10774   else
10775     return;
10776
10777   if (! tree_int_cst_lt (len, size))
10778     {
10779       location_t locus = EXPR_LOCATION (exp);
10780       warning (0, "%Hcall to %D will always overflow destination buffer",
10781                &locus, get_callee_fndecl (exp));
10782     }
10783 }
10784
10785 /* Fold a call to __builtin_object_size, if possible.  */
10786
10787 tree
10788 fold_builtin_object_size (tree arglist)
10789 {
10790   tree ptr, ost, ret = 0;
10791   int object_size_type;
10792
10793   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10794     return 0;
10795
10796   ptr = TREE_VALUE (arglist);
10797   ost = TREE_VALUE (TREE_CHAIN (arglist));
10798   STRIP_NOPS (ost);
10799
10800   if (TREE_CODE (ost) != INTEGER_CST
10801       || tree_int_cst_sgn (ost) < 0
10802       || compare_tree_int (ost, 3) > 0)
10803     return 0;
10804
10805   object_size_type = tree_low_cst (ost, 0);
10806
10807   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10808      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10809      and (size_t) 0 for types 2 and 3.  */
10810   if (TREE_SIDE_EFFECTS (ptr))
10811     return fold_convert (size_type_node,
10812                          object_size_type < 2
10813                          ? integer_minus_one_node : integer_zero_node);
10814
10815   if (TREE_CODE (ptr) == ADDR_EXPR)
10816     ret = build_int_cstu (size_type_node,
10817                         compute_builtin_object_size (ptr, object_size_type));
10818
10819   else if (TREE_CODE (ptr) == SSA_NAME)
10820     {
10821       unsigned HOST_WIDE_INT bytes;
10822
10823       /* If object size is not known yet, delay folding until
10824        later.  Maybe subsequent passes will help determining
10825        it.  */
10826       bytes = compute_builtin_object_size (ptr, object_size_type);
10827       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10828                                              ? -1 : 0))
10829         ret = build_int_cstu (size_type_node, bytes);
10830     }
10831
10832   if (ret)
10833     {
10834       ret = force_fit_type (ret, -1, false, false);
10835       if (TREE_CONSTANT_OVERFLOW (ret))
10836         ret = 0;
10837     }
10838
10839   return ret;
10840 }
10841
10842 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10843    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10844    code of the builtin.  If MAXLEN is not NULL, it is maximum length
10845    passed as third argument.  */
10846
10847 tree
10848 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10849                          enum built_in_function fcode)
10850 {
10851   tree dest, src, len, size, fn;
10852
10853   if (!validate_arglist (arglist,
10854                          POINTER_TYPE,
10855                          fcode == BUILT_IN_MEMSET_CHK
10856                          ? INTEGER_TYPE : POINTER_TYPE,
10857                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10858     return 0;
10859
10860   dest = TREE_VALUE (arglist);
10861   /* Actually val for __memset_chk, but it doesn't matter.  */
10862   src = TREE_VALUE (TREE_CHAIN (arglist));
10863   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10864   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10865
10866   /* If SRC and DEST are the same (and not volatile), return DEST
10867      (resp. DEST+LEN for __mempcpy_chk).  */
10868   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10869     {
10870       if (fcode != BUILT_IN_MEMPCPY_CHK)
10871         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10872       else
10873         {
10874           tree temp = fold_convert (TREE_TYPE (dest), len);
10875           temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10876           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10877         }
10878     }
10879
10880   if (! host_integerp (size, 1))
10881     return 0;
10882
10883   if (! integer_all_onesp (size))
10884     {
10885       if (! host_integerp (len, 1))
10886         {
10887           /* If LEN is not constant, try MAXLEN too.
10888              For MAXLEN only allow optimizing into non-_ocs function
10889              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10890           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10891             {
10892               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10893                 {
10894                   /* (void) __mempcpy_chk () can be optimized into
10895                      (void) __memcpy_chk ().  */
10896                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10897                   if (!fn)
10898                     return 0;
10899
10900                   return build_function_call_expr (fn, arglist);
10901                 }
10902               return 0;
10903             }
10904         }
10905       else
10906         maxlen = len;
10907
10908       if (tree_int_cst_lt (size, maxlen))
10909         return 0;
10910     }
10911
10912   arglist = build_tree_list (NULL_TREE, len);
10913   arglist = tree_cons (NULL_TREE, src, arglist);
10914   arglist = tree_cons (NULL_TREE, dest, arglist);
10915
10916   fn = NULL_TREE;
10917   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10918      mem{cpy,pcpy,move,set} is available.  */
10919   switch (fcode)
10920     {
10921     case BUILT_IN_MEMCPY_CHK:
10922       fn = built_in_decls[BUILT_IN_MEMCPY];
10923       break;
10924     case BUILT_IN_MEMPCPY_CHK:
10925       fn = built_in_decls[BUILT_IN_MEMPCPY];
10926       break;
10927     case BUILT_IN_MEMMOVE_CHK:
10928       fn = built_in_decls[BUILT_IN_MEMMOVE];
10929       break;
10930     case BUILT_IN_MEMSET_CHK:
10931       fn = built_in_decls[BUILT_IN_MEMSET];
10932       break;
10933     default:
10934       break;
10935     }
10936
10937   if (!fn)
10938     return 0;
10939
10940   return build_function_call_expr (fn, arglist);
10941 }
10942
10943 /* Fold a call to the __st[rp]cpy_chk builtin.
10944    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10945    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10946    strings passed as second argument.  */
10947
10948 tree
10949 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10950                          enum built_in_function fcode)
10951 {
10952   tree dest, src, size, len, fn;
10953
10954   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10955                          VOID_TYPE))
10956     return 0;
10957
10958   dest = TREE_VALUE (arglist);
10959   src = TREE_VALUE (TREE_CHAIN (arglist));
10960   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10961
10962   /* If SRC and DEST are the same (and not volatile), return DEST.  */
10963   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10964     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10965
10966   if (! host_integerp (size, 1))
10967     return 0;
10968
10969   if (! integer_all_onesp (size))
10970     {
10971       len = c_strlen (src, 1);
10972       if (! len || ! host_integerp (len, 1))
10973         {
10974           /* If LEN is not constant, try MAXLEN too.
10975              For MAXLEN only allow optimizing into non-_ocs function
10976              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10977           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10978             {
10979               if (fcode == BUILT_IN_STPCPY_CHK)
10980                 {
10981                   if (! ignore)
10982                     return 0;
10983
10984                   /* If return value of __stpcpy_chk is ignored,
10985                      optimize into __strcpy_chk.  */
10986                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10987                   if (!fn)
10988                     return 0;
10989
10990                   return build_function_call_expr (fn, arglist);
10991                 }
10992
10993               if (! len || TREE_SIDE_EFFECTS (len))
10994                 return 0;
10995
10996               /* If c_strlen returned something, but not a constant,
10997                  transform __strcpy_chk into __memcpy_chk.  */
10998               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10999               if (!fn)
11000                 return 0;
11001
11002               len = size_binop (PLUS_EXPR, len, ssize_int (1));
11003               arglist = build_tree_list (NULL_TREE, size);
11004               arglist = tree_cons (NULL_TREE, len, arglist);
11005               arglist = tree_cons (NULL_TREE, src, arglist);
11006               arglist = tree_cons (NULL_TREE, dest, arglist);
11007               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
11008                                    build_function_call_expr (fn, arglist));
11009             }
11010         }
11011       else
11012         maxlen = len;
11013
11014       if (! tree_int_cst_lt (maxlen, size))
11015         return 0;
11016     }
11017
11018   arglist = build_tree_list (NULL_TREE, src);
11019   arglist = tree_cons (NULL_TREE, dest, arglist);
11020
11021   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
11022   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
11023                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
11024   if (!fn)
11025     return 0;
11026
11027   return build_function_call_expr (fn, arglist);
11028 }
11029
11030 /* Fold a call to the __strncpy_chk builtin.
11031    If MAXLEN is not NULL, it is maximum length passed as third argument.  */
11032
11033 tree
11034 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
11035 {
11036   tree dest, src, size, len, fn;
11037
11038   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11039                          INTEGER_TYPE, VOID_TYPE))
11040     return 0;
11041
11042   dest = TREE_VALUE (arglist);
11043   src = TREE_VALUE (TREE_CHAIN (arglist));
11044   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11045   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11046
11047   if (! host_integerp (size, 1))
11048     return 0;
11049
11050   if (! integer_all_onesp (size))
11051     {
11052       if (! host_integerp (len, 1))
11053         {
11054           /* If LEN is not constant, try MAXLEN too.
11055              For MAXLEN only allow optimizing into non-_ocs function
11056              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
11057           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11058             return 0;
11059         }
11060       else
11061         maxlen = len;
11062
11063       if (tree_int_cst_lt (size, maxlen))
11064         return 0;
11065     }
11066
11067   arglist = build_tree_list (NULL_TREE, len);
11068   arglist = tree_cons (NULL_TREE, src, arglist);
11069   arglist = tree_cons (NULL_TREE, dest, arglist);
11070
11071   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
11072   fn = built_in_decls[BUILT_IN_STRNCPY];
11073   if (!fn)
11074     return 0;
11075
11076   return build_function_call_expr (fn, arglist);
11077 }
11078
11079 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
11080
11081 static tree
11082 fold_builtin_strcat_chk (tree fndecl, tree arglist)
11083 {
11084   tree dest, src, size, fn;
11085   const char *p;
11086
11087   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11088                          VOID_TYPE))
11089     return 0;
11090
11091   dest = TREE_VALUE (arglist);
11092   src = TREE_VALUE (TREE_CHAIN (arglist));
11093   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11094
11095   p = c_getstr (src);
11096   /* If the SRC parameter is "", return DEST.  */
11097   if (p && *p == '\0')
11098     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11099
11100   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
11101     return 0;
11102
11103   arglist = build_tree_list (NULL_TREE, src);
11104   arglist = tree_cons (NULL_TREE, dest, arglist);
11105
11106   /* If __builtin_strcat_chk is used, assume strcat is available.  */
11107   fn = built_in_decls[BUILT_IN_STRCAT];
11108   if (!fn)
11109     return 0;
11110
11111   return build_function_call_expr (fn, arglist);
11112 }
11113
11114 /* Fold a call to the __strncat_chk builtin EXP.  */
11115
11116 static tree
11117 fold_builtin_strncat_chk (tree fndecl, tree arglist)
11118 {
11119   tree dest, src, size, len, fn;
11120   const char *p;
11121
11122   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
11123                          INTEGER_TYPE, VOID_TYPE))
11124     return 0;
11125
11126   dest = TREE_VALUE (arglist);
11127   src = TREE_VALUE (TREE_CHAIN (arglist));
11128   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11129   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
11130
11131   p = c_getstr (src);
11132   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
11133   if (p && *p == '\0')
11134     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
11135   else if (integer_zerop (len))
11136     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
11137
11138   if (! host_integerp (size, 1))
11139     return 0;
11140
11141   if (! integer_all_onesp (size))
11142     {
11143       tree src_len = c_strlen (src, 1);
11144       if (src_len
11145           && host_integerp (src_len, 1)
11146           && host_integerp (len, 1)
11147           && ! tree_int_cst_lt (len, src_len))
11148         {
11149           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
11150           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
11151           if (!fn)
11152             return 0;
11153
11154           arglist = build_tree_list (NULL_TREE, size);
11155           arglist = tree_cons (NULL_TREE, src, arglist);
11156           arglist = tree_cons (NULL_TREE, dest, arglist);
11157           return build_function_call_expr (fn, arglist);
11158         }
11159       return 0;
11160     }
11161
11162   arglist = build_tree_list (NULL_TREE, len);
11163   arglist = tree_cons (NULL_TREE, src, arglist);
11164   arglist = tree_cons (NULL_TREE, dest, arglist);
11165
11166   /* If __builtin_strncat_chk is used, assume strncat is available.  */
11167   fn = built_in_decls[BUILT_IN_STRNCAT];
11168   if (!fn)
11169     return 0;
11170
11171   return build_function_call_expr (fn, arglist);
11172 }
11173
11174 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
11175    a normal call should be emitted rather than expanding the function
11176    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
11177
11178 static tree
11179 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
11180 {
11181   tree dest, size, len, fn, fmt, flag;
11182   const char *fmt_str;
11183
11184   /* Verify the required arguments in the original call.  */
11185   if (! arglist)
11186     return 0;
11187   dest = TREE_VALUE (arglist);
11188   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11189     return 0;
11190   arglist = TREE_CHAIN (arglist);
11191   if (! arglist)
11192     return 0;
11193   flag = TREE_VALUE (arglist);
11194   if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11195     return 0;
11196   arglist = TREE_CHAIN (arglist);
11197   if (! arglist)
11198     return 0;
11199   size = TREE_VALUE (arglist);
11200   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11201     return 0;
11202   arglist = TREE_CHAIN (arglist);
11203   if (! arglist)
11204     return 0;
11205   fmt = TREE_VALUE (arglist);
11206   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11207     return 0;
11208   arglist = TREE_CHAIN (arglist);
11209
11210   if (! host_integerp (size, 1))
11211     return 0;
11212
11213   len = NULL_TREE;
11214
11215   if (!init_target_chars())
11216     return 0;
11217
11218   /* Check whether the format is a literal string constant.  */
11219   fmt_str = c_getstr (fmt);
11220   if (fmt_str != NULL)
11221     {
11222       /* If the format doesn't contain % args or %%, we know the size.  */
11223       if (strchr (fmt_str, target_percent) == 0)
11224         {
11225           if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11226             len = build_int_cstu (size_type_node, strlen (fmt_str));
11227         }
11228       /* If the format is "%s" and first ... argument is a string literal,
11229          we know the size too.  */
11230       else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11231         {
11232           tree arg;
11233
11234           if (arglist && !TREE_CHAIN (arglist))
11235             {
11236               arg = TREE_VALUE (arglist);
11237               if (POINTER_TYPE_P (TREE_TYPE (arg)))
11238                 {
11239                   len = c_strlen (arg, 1);
11240                   if (! len || ! host_integerp (len, 1))
11241                     len = NULL_TREE;
11242                 }
11243             }
11244         }
11245     }
11246
11247   if (! integer_all_onesp (size))
11248     {
11249       if (! len || ! tree_int_cst_lt (len, size))
11250         return 0;
11251     }
11252
11253   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11254      or if format doesn't contain % chars or is "%s".  */
11255   if (! integer_zerop (flag))
11256     {
11257       if (fmt_str == NULL)
11258         return 0;
11259       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11260         return 0;
11261     }
11262
11263   arglist = tree_cons (NULL_TREE, fmt, arglist);
11264   arglist = tree_cons (NULL_TREE, dest, arglist);
11265
11266   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
11267   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11268                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11269   if (!fn)
11270     return 0;
11271
11272   return build_function_call_expr (fn, arglist);
11273 }
11274
11275 /* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
11276    a normal call should be emitted rather than expanding the function
11277    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
11278    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
11279    passed as second argument.  */
11280
11281 tree
11282 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11283                            enum built_in_function fcode)
11284 {
11285   tree dest, size, len, fn, fmt, flag;
11286   const char *fmt_str;
11287
11288   /* Verify the required arguments in the original call.  */
11289   if (! arglist)
11290     return 0;
11291   dest = TREE_VALUE (arglist);
11292   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11293     return 0;
11294   arglist = TREE_CHAIN (arglist);
11295   if (! arglist)
11296     return 0;
11297   len = TREE_VALUE (arglist);
11298   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11299     return 0;
11300   arglist = TREE_CHAIN (arglist);
11301   if (! arglist)
11302     return 0;
11303   flag = TREE_VALUE (arglist);
11304   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11305     return 0;
11306   arglist = TREE_CHAIN (arglist);
11307   if (! arglist)
11308     return 0;
11309   size = TREE_VALUE (arglist);
11310   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11311     return 0;
11312   arglist = TREE_CHAIN (arglist);
11313   if (! arglist)
11314     return 0;
11315   fmt = TREE_VALUE (arglist);
11316   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11317     return 0;
11318   arglist = TREE_CHAIN (arglist);
11319
11320   if (! host_integerp (size, 1))
11321     return 0;
11322
11323   if (! integer_all_onesp (size))
11324     {
11325       if (! host_integerp (len, 1))
11326         {
11327           /* If LEN is not constant, try MAXLEN too.
11328              For MAXLEN only allow optimizing into non-_ocs function
11329              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
11330           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11331             return 0;
11332         }
11333       else
11334         maxlen = len;
11335
11336       if (tree_int_cst_lt (size, maxlen))
11337         return 0;
11338     }
11339
11340   if (!init_target_chars())
11341     return 0;
11342
11343   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11344      or if format doesn't contain % chars or is "%s".  */
11345   if (! integer_zerop (flag))
11346     {
11347       fmt_str = c_getstr (fmt);
11348       if (fmt_str == NULL)
11349         return 0;
11350       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11351         return 0;
11352     }
11353
11354   arglist = tree_cons (NULL_TREE, fmt, arglist);
11355   arglist = tree_cons (NULL_TREE, len, arglist);
11356   arglist = tree_cons (NULL_TREE, dest, arglist);
11357
11358   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11359      available.  */
11360   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11361                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11362   if (!fn)
11363     return 0;
11364
11365   return build_function_call_expr (fn, arglist);
11366 }
11367
11368 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11369
11370    Return 0 if no simplification was possible, otherwise return the
11371    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11372    code of the function to be simplified.  */
11373
11374 static tree
11375 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11376                      enum built_in_function fcode)
11377 {
11378   tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11379   const char *fmt_str = NULL;
11380
11381   /* If the return value is used, don't do the transformation.  */
11382   if (! ignore)
11383     return 0;
11384
11385   /* Verify the required arguments in the original call.  */
11386   if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11387     {
11388       tree flag;
11389
11390       if (! arglist)
11391         return 0;
11392       flag = TREE_VALUE (arglist);
11393       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11394           || TREE_SIDE_EFFECTS (flag))
11395         return 0;
11396       arglist = TREE_CHAIN (arglist);
11397     }
11398
11399   if (! arglist)
11400     return 0;
11401   fmt = TREE_VALUE (arglist);
11402   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11403     return 0;
11404   arglist = TREE_CHAIN (arglist);
11405
11406   /* Check whether the format is a literal string constant.  */
11407   fmt_str = c_getstr (fmt);
11408   if (fmt_str == NULL)
11409     return NULL_TREE;
11410
11411   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11412     {
11413       /* If we're using an unlocked function, assume the other
11414          unlocked functions exist explicitly.  */
11415       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11416       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11417     }
11418   else
11419     {
11420       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11421       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11422     }
11423
11424   if (!init_target_chars())
11425     return 0;
11426
11427   if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11428     {
11429       const char *str;
11430
11431       if (strcmp (fmt_str, target_percent_s) == 0)
11432         {
11433           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11434             return 0;
11435
11436           if (! arglist
11437               || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11438               || TREE_CHAIN (arglist))
11439             return 0;
11440
11441           str = c_getstr (TREE_VALUE (arglist));
11442           if (str == NULL)
11443             return 0;
11444         }
11445       else
11446         {
11447           /* The format specifier doesn't contain any '%' characters.  */
11448           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11449               && arglist)
11450             return 0;
11451           str = fmt_str;
11452         }
11453
11454       /* If the string was "", printf does nothing.  */
11455       if (str[0] == '\0')
11456         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11457
11458       /* If the string has length of 1, call putchar.  */
11459       if (str[1] == '\0')
11460         {
11461           /* Given printf("c"), (where c is any one character,)
11462              convert "c"[0] to an int and pass that to the replacement
11463              function.  */
11464           arg = build_int_cst (NULL_TREE, str[0]);
11465           arglist = build_tree_list (NULL_TREE, arg);
11466           fn = fn_putchar;
11467         }
11468       else
11469         {
11470           /* If the string was "string\n", call puts("string").  */
11471           size_t len = strlen (str);
11472           if ((unsigned char)str[len - 1] == target_newline)
11473             {
11474               /* Create a NUL-terminated string that's one char shorter
11475                  than the original, stripping off the trailing '\n'.  */
11476               char *newstr = alloca (len);
11477               memcpy (newstr, str, len - 1);
11478               newstr[len - 1] = 0;
11479
11480               arg = build_string_literal (len, newstr);
11481               arglist = build_tree_list (NULL_TREE, arg);
11482               fn = fn_puts;
11483             }
11484           else
11485             /* We'd like to arrange to call fputs(string,stdout) here,
11486                but we need stdout and don't have a way to get it yet.  */
11487             return 0;
11488         }
11489     }
11490
11491   /* The other optimizations can be done only on the non-va_list variants.  */
11492   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11493     return 0;
11494
11495   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
11496   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11497     {
11498       if (! arglist
11499           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11500           || TREE_CHAIN (arglist))
11501         return 0;
11502       fn = fn_puts;
11503     }
11504
11505   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
11506   else if (strcmp (fmt_str, target_percent_c) == 0)
11507     {
11508       if (! arglist
11509           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11510           || TREE_CHAIN (arglist))
11511         return 0;
11512       fn = fn_putchar;
11513     }
11514
11515   if (!fn)
11516     return 0;
11517
11518   call = build_function_call_expr (fn, arglist);
11519   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11520 }
11521
11522 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11523
11524    Return 0 if no simplification was possible, otherwise return the
11525    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11526    code of the function to be simplified.  */
11527
11528 static tree
11529 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11530                       enum built_in_function fcode)
11531 {
11532   tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11533   const char *fmt_str = NULL;
11534
11535   /* If the return value is used, don't do the transformation.  */
11536   if (! ignore)
11537     return 0;
11538
11539   /* Verify the required arguments in the original call.  */
11540   if (! arglist)
11541     return 0;
11542   fp = TREE_VALUE (arglist);
11543   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11544     return 0;
11545   arglist = TREE_CHAIN (arglist);
11546
11547   if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11548     {
11549       tree flag;
11550
11551       if (! arglist)
11552         return 0;
11553       flag = TREE_VALUE (arglist);
11554       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11555           || TREE_SIDE_EFFECTS (flag))
11556         return 0;
11557       arglist = TREE_CHAIN (arglist);
11558     }
11559
11560   if (! arglist)
11561     return 0;
11562   fmt = TREE_VALUE (arglist);
11563   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11564     return 0;
11565   arglist = TREE_CHAIN (arglist);
11566
11567   /* Check whether the format is a literal string constant.  */
11568   fmt_str = c_getstr (fmt);
11569   if (fmt_str == NULL)
11570     return NULL_TREE;
11571
11572   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11573     {
11574       /* If we're using an unlocked function, assume the other
11575          unlocked functions exist explicitly.  */
11576       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11577       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11578     }
11579   else
11580     {
11581       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11582       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11583     }
11584
11585   if (!init_target_chars())
11586     return 0;
11587
11588   /* If the format doesn't contain % args or %%, use strcpy.  */
11589   if (strchr (fmt_str, target_percent) == NULL)
11590     {
11591       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11592           && arglist)
11593         return 0;
11594
11595       /* If the format specifier was "", fprintf does nothing.  */
11596       if (fmt_str[0] == '\0')
11597         {
11598           /* If FP has side-effects, just wait until gimplification is
11599              done.  */
11600           if (TREE_SIDE_EFFECTS (fp))
11601             return 0;
11602
11603           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11604         }
11605
11606       /* When "string" doesn't contain %, replace all cases of
11607          fprintf (fp, string) with fputs (string, fp).  The fputs
11608          builtin will take care of special cases like length == 1.  */
11609       arglist = build_tree_list (NULL_TREE, fp);
11610       arglist = tree_cons (NULL_TREE, fmt, arglist);
11611       fn = fn_fputs;
11612     }
11613
11614   /* The other optimizations can be done only on the non-va_list variants.  */
11615   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11616     return 0;
11617
11618   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
11619   else if (strcmp (fmt_str, target_percent_s) == 0)
11620     {
11621       if (! arglist
11622           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11623           || TREE_CHAIN (arglist))
11624         return 0;
11625       arg = TREE_VALUE (arglist);
11626       arglist = build_tree_list (NULL_TREE, fp);
11627       arglist = tree_cons (NULL_TREE, arg, arglist);
11628       fn = fn_fputs;
11629     }
11630
11631   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
11632   else if (strcmp (fmt_str, target_percent_c) == 0)
11633     {
11634       if (! arglist
11635           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11636           || TREE_CHAIN (arglist))
11637         return 0;
11638       arg = TREE_VALUE (arglist);
11639       arglist = build_tree_list (NULL_TREE, fp);
11640       arglist = tree_cons (NULL_TREE, arg, arglist);
11641       fn = fn_fputc;
11642     }
11643
11644   if (!fn)
11645     return 0;
11646
11647   call = build_function_call_expr (fn, arglist);
11648   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11649 }
11650
11651 /* Initialize format string characters in the target charset.  */
11652
11653 static bool
11654 init_target_chars (void)
11655 {
11656   static bool init;
11657   if (!init)
11658     {
11659       target_newline = lang_hooks.to_target_charset ('\n');
11660       target_percent = lang_hooks.to_target_charset ('%');
11661       target_c = lang_hooks.to_target_charset ('c');
11662       target_s = lang_hooks.to_target_charset ('s');
11663       if (target_newline == 0 || target_percent == 0 || target_c == 0
11664           || target_s == 0)
11665         return false;
11666
11667       target_percent_c[0] = target_percent;
11668       target_percent_c[1] = target_c;
11669       target_percent_c[2] = '\0';
11670
11671       target_percent_s[0] = target_percent;
11672       target_percent_s[1] = target_s;
11673       target_percent_s[2] = '\0';
11674
11675       target_percent_s_newline[0] = target_percent;
11676       target_percent_s_newline[1] = target_s;
11677       target_percent_s_newline[2] = target_newline;
11678       target_percent_s_newline[3] = '\0';
11679
11680       init = true;
11681     }
11682   return true;
11683 }
11684
11685 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
11686    and no overflow/underflow occurred.  INEXACT is true if M was not
11687    exactly calculated.  TYPE is the tree type for the result.  This
11688    function assumes that you cleared the MPFR flags and then
11689    calculated M to see if anything subsequently set a flag prior to
11690    entering this function.  Return NULL_TREE if any checks fail.  */
11691
11692 static tree
11693 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11694 {
11695   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11696      overflow/underflow occurred.  If -frounding-math, proceed iff the
11697      result of calling FUNC was exact.  */
11698   if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11699       && (!flag_rounding_math || !inexact))
11700     {
11701       REAL_VALUE_TYPE rr;
11702
11703       real_from_mpfr (&rr, m);
11704       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11705          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
11706          but the mpft_t is not, then we underflowed in the
11707          conversion.  */
11708       if (!real_isnan (&rr) && !real_isinf (&rr)
11709           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11710         {
11711           REAL_VALUE_TYPE rmode;
11712
11713           real_convert (&rmode, TYPE_MODE (type), &rr);
11714           /* Proceed iff the specified mode can hold the value.  */
11715           if (real_identical (&rmode, &rr))
11716             return build_real (type, rmode);
11717         }
11718     }
11719   return NULL_TREE;
11720 }
11721
11722 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11723    FUNC on it and return the resulting value as a tree with type TYPE.
11724    If MIN and/or MAX are not NULL, then the supplied ARG must be
11725    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
11726    acceptable values, otherwise they are not.  The mpfr precision is
11727    set to the precision of TYPE.  We assume that function FUNC returns
11728    zero if the result could be calculated exactly within the requested
11729    precision.  */
11730
11731 static tree
11732 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11733               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11734               bool inclusive)
11735 {
11736   tree result = NULL_TREE;
11737   
11738   STRIP_NOPS (arg);
11739
11740   /* To proceed, MPFR must exactly represent the target floating point
11741      format, which only happens when the target base equals two.  */
11742   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11743       && TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11744     {
11745       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11746
11747       if (!real_isnan (ra) && !real_isinf (ra)
11748           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11749           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11750         {
11751           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11752           int inexact;
11753           mpfr_t m;
11754
11755           mpfr_init2 (m, prec);
11756           mpfr_from_real (m, ra);
11757           mpfr_clear_flags();
11758           inexact = func (m, m, GMP_RNDN);
11759           result = do_mpfr_ckconv (m, type, inexact);
11760           mpfr_clear (m);
11761         }
11762     }
11763   
11764   return result;
11765 }
11766
11767 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11768    FUNC on it and return the resulting value as a tree with type TYPE.
11769    The mpfr precision is set to the precision of TYPE.  We assume that
11770    function FUNC returns zero if the result could be calculated
11771    exactly within the requested precision.  */
11772
11773 static tree
11774 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11775               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11776 {
11777   tree result = NULL_TREE;
11778   
11779   STRIP_NOPS (arg1);
11780   STRIP_NOPS (arg2);
11781
11782   /* To proceed, MPFR must exactly represent the target floating point
11783      format, which only happens when the target base equals two.  */
11784   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11785       && TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11786       && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
11787     {
11788       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11789       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11790
11791       if (!real_isnan (ra1) && !real_isinf (ra1)
11792           && !real_isnan (ra2) && !real_isinf (ra2))
11793         {
11794           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11795           int inexact;
11796           mpfr_t m1, m2;
11797
11798           mpfr_inits2 (prec, m1, m2, NULL);
11799           mpfr_from_real (m1, ra1);
11800           mpfr_from_real (m2, ra2);
11801           mpfr_clear_flags();
11802           inexact = func (m1, m1, m2, GMP_RNDN);
11803           result = do_mpfr_ckconv (m1, type, inexact);
11804           mpfr_clears (m1, m2, NULL);
11805         }
11806     }
11807   
11808   return result;
11809 }
11810
11811 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11812    FUNC on it and return the resulting value as a tree with type TYPE.
11813    The mpfr precision is set to the precision of TYPE.  We assume that
11814    function FUNC returns zero if the result could be calculated
11815    exactly within the requested precision.  */
11816
11817 static tree
11818 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11819               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11820 {
11821   tree result = NULL_TREE;
11822   
11823   STRIP_NOPS (arg1);
11824   STRIP_NOPS (arg2);
11825   STRIP_NOPS (arg3);
11826
11827   /* To proceed, MPFR must exactly represent the target floating point
11828      format, which only happens when the target base equals two.  */
11829   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11830       && TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11831       && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2)
11832       && TREE_CODE (arg3) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg3))
11833     {
11834       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11835       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11836       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11837
11838       if (!real_isnan (ra1) && !real_isinf (ra1)
11839           && !real_isnan (ra2) && !real_isinf (ra2)
11840           && !real_isnan (ra3) && !real_isinf (ra3))
11841         {
11842           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11843           int inexact;
11844           mpfr_t m1, m2, m3;
11845
11846           mpfr_inits2 (prec, m1, m2, m3, NULL);
11847           mpfr_from_real (m1, ra1);
11848           mpfr_from_real (m2, ra2);
11849           mpfr_from_real (m3, ra3);
11850           mpfr_clear_flags();
11851           inexact = func (m1, m1, m2, m3, GMP_RNDN);
11852           result = do_mpfr_ckconv (m1, type, inexact);
11853           mpfr_clears (m1, m2, m3, NULL);
11854         }
11855     }
11856   
11857   return result;
11858 }
11859
11860 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11861    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11862    If ARG_SINP and ARG_COSP are NULL then the result is returned
11863    as a complex value.
11864    The type is taken from the type of ARG and is used for setting the
11865    precision of the calculation and results.  */
11866
11867 static tree
11868 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11869 {
11870   tree const type = TREE_TYPE (arg);
11871   tree result = NULL_TREE;
11872   
11873   STRIP_NOPS (arg);
11874   
11875   /* To proceed, MPFR must exactly represent the target floating point
11876      format, which only happens when the target base equals two.  */
11877   if (REAL_MODE_FORMAT (TYPE_MODE (type))->b == 2
11878       && TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11879     {
11880       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11881
11882       if (!real_isnan (ra) && !real_isinf (ra))
11883         {
11884           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11885           tree result_s, result_c;
11886           int inexact;
11887           mpfr_t m, ms, mc;
11888
11889           mpfr_inits2 (prec, m, ms, mc, NULL);
11890           mpfr_from_real (m, ra);
11891           mpfr_clear_flags();
11892           inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11893           result_s = do_mpfr_ckconv (ms, type, inexact);
11894           result_c = do_mpfr_ckconv (mc, type, inexact);
11895           mpfr_clears (m, ms, mc, NULL);
11896           if (result_s && result_c)
11897             {
11898               /* If we are to return in a complex value do so.  */
11899               if (!arg_sinp && !arg_cosp)
11900                 return build_complex (build_complex_type (type),
11901                                       result_c, result_s);
11902
11903               /* Dereference the sin/cos pointer arguments.  */
11904               arg_sinp = build_fold_indirect_ref (arg_sinp);
11905               arg_cosp = build_fold_indirect_ref (arg_cosp);
11906               /* Proceed if valid pointer type were passed in.  */
11907               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11908                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11909                 {
11910                   /* Set the values. */
11911                   result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11912                                           result_s);
11913                   TREE_SIDE_EFFECTS (result_s) = 1;
11914                   result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11915                                           result_c);
11916                   TREE_SIDE_EFFECTS (result_c) = 1;
11917                   /* Combine the assignments into a compound expr.  */
11918                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11919                                                     result_s, result_c));
11920                 }
11921             }
11922         }
11923     }
11924   return result;
11925 }