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