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