OSDN Git Service

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