OSDN Git Service

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