OSDN Git Service

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