OSDN Git Service

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