OSDN Git Service

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