OSDN Git Service

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