OSDN Git Service

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