OSDN Git Service

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