OSDN Git Service

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