OSDN Git Service

* gdbinit.in: Set complaints to 0.
[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 (GIMPLE_MODIFY_STMT, 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 (GIMPLE_MODIFY_STMT, 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 (GIMPLE_MODIFY_STMT, 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 (GIMPLE_MODIFY_STMT, 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 (GIMPLE_MODIFY_STMT, 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 GIMPLE_MODIFY_STMT:
6742     case BIND_EXPR:
6743       return integer_valued_real_p (GENERIC_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 (GIMPLE_MODIFY_STMT, 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           || !tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
8206           || !tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len))
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       if (!tree_int_cst_equal (lang_hooks.expr_size (srcvar), len))
8222         return 0;
8223       /* With memcpy, it is possible to bypass aliasing rules, so without
8224          this check i. e. execute/20060930-2.c would be misoptimized, because
8225          it use conflicting alias set to hold argument for the memcpy call.
8226          This check is probably unnecesary with -fno-strict-aliasing. 
8227          Similarly for destvar.  See also PR29286.  */
8228       if (!var_decl_component_p (srcvar)
8229           /* Accept: memcpy (*char_var, "test", 1); that simplify
8230              to char_var='t';  */
8231           || is_gimple_min_invariant (srcvar)
8232           || readonly_data_expr (src))
8233         return 0;
8234
8235       destvar = build_fold_indirect_ref (dest);
8236       if (TREE_THIS_VOLATILE (destvar))
8237         return 0;
8238       if (!tree_int_cst_equal (lang_hooks.expr_size (destvar), len))
8239         return 0;
8240       if (!var_decl_component_p (destvar))
8241         return 0;
8242
8243       if (srctype == desttype
8244           || (gimple_in_ssa_p (cfun)
8245               && tree_ssa_useless_type_conversion_1 (desttype, srctype)))
8246         expr = srcvar;
8247       else if ((INTEGRAL_TYPE_P (TREE_TYPE (srcvar))
8248            || POINTER_TYPE_P (TREE_TYPE (srcvar)))
8249           && (INTEGRAL_TYPE_P (TREE_TYPE (destvar))
8250               || POINTER_TYPE_P (TREE_TYPE (destvar))))
8251         expr = fold_convert (TREE_TYPE (destvar), srcvar);
8252       else
8253         expr = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (destvar), srcvar);
8254       expr = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (destvar), destvar, expr);
8255     }
8256
8257   if (ignore)
8258     return expr;
8259
8260   if (endp == 0 || endp == 3)
8261     return omit_one_operand (type, dest, expr);
8262
8263   if (expr == len)
8264     expr = 0;
8265
8266   if (endp == 2)
8267     len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
8268                        ssize_int (1));
8269
8270   len = fold_convert (TREE_TYPE (dest), len);
8271   dest = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
8272   dest = fold_convert (type, dest);
8273   if (expr)
8274     dest = omit_one_operand (type, dest, expr);
8275   return dest;
8276 }
8277
8278 /* Fold function call to builtin bcopy.  Return NULL_TREE if no
8279    simplification can be made.  */
8280
8281 static tree
8282 fold_builtin_bcopy (tree arglist, bool ignore)
8283 {
8284   tree src, dest, size, newarglist;
8285
8286   if (!validate_arglist (arglist,
8287                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8288     return 0;
8289
8290   if (! ignore)
8291     return 0;
8292
8293   src = TREE_VALUE (arglist);
8294   dest = TREE_VALUE (TREE_CHAIN (arglist));
8295   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8296
8297   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
8298      memmove(ptr y, ptr x, size_t z).   This is done this way
8299      so that if it isn't expanded inline, we fallback to
8300      calling bcopy instead of memmove.  */
8301
8302   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
8303   newarglist = tree_cons (NULL_TREE, src, newarglist);
8304   newarglist = tree_cons (NULL_TREE, dest, newarglist);
8305
8306   return fold_builtin_memory_op (newarglist, void_type_node, true, /*endp=*/3);
8307 }
8308
8309 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
8310    the length of the string to be copied.  Return NULL_TREE if no
8311    simplification can be made.  */
8312
8313 tree
8314 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
8315 {
8316   tree dest, src, fn;
8317
8318   if (!validate_arglist (arglist,
8319                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8320     return 0;
8321
8322   dest = TREE_VALUE (arglist);
8323   src = TREE_VALUE (TREE_CHAIN (arglist));
8324
8325   /* If SRC and DEST are the same (and not volatile), return DEST.  */
8326   if (operand_equal_p (src, dest, 0))
8327     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
8328
8329   if (optimize_size)
8330     return 0;
8331
8332   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8333   if (!fn)
8334     return 0;
8335
8336   if (!len)
8337     {
8338       len = c_strlen (src, 1);
8339       if (! len || TREE_SIDE_EFFECTS (len))
8340         return 0;
8341     }
8342
8343   len = size_binop (PLUS_EXPR, len, ssize_int (1));
8344   arglist = build_tree_list (NULL_TREE, len);
8345   arglist = tree_cons (NULL_TREE, src, arglist);
8346   arglist = tree_cons (NULL_TREE, dest, arglist);
8347   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8348                        build_function_call_expr (fn, arglist));
8349 }
8350
8351 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8352    the length of the source string.  Return NULL_TREE if no simplification
8353    can be made.  */
8354
8355 tree
8356 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8357 {
8358   tree dest, src, len, fn;
8359
8360   if (!validate_arglist (arglist,
8361                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8362     return 0;
8363
8364   dest = TREE_VALUE (arglist);
8365   src = TREE_VALUE (TREE_CHAIN (arglist));
8366   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8367
8368   /* If the LEN parameter is zero, return DEST.  */
8369   if (integer_zerop (len))
8370     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8371
8372   /* We can't compare slen with len as constants below if len is not a
8373      constant.  */
8374   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8375     return 0;
8376
8377   if (!slen)
8378     slen = c_strlen (src, 1);
8379
8380   /* Now, we must be passed a constant src ptr parameter.  */
8381   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8382     return 0;
8383
8384   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8385
8386   /* We do not support simplification of this case, though we do
8387      support it when expanding trees into RTL.  */
8388   /* FIXME: generate a call to __builtin_memset.  */
8389   if (tree_int_cst_lt (slen, len))
8390     return 0;
8391
8392   /* OK transform into builtin memcpy.  */
8393   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8394   if (!fn)
8395     return 0;
8396   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8397                        build_function_call_expr (fn, arglist));
8398 }
8399
8400 /* Fold function call to builtin memcmp.  Return
8401    NULL_TREE if no simplification can be made.  */
8402
8403 static tree
8404 fold_builtin_memcmp (tree arglist)
8405 {
8406   tree arg1, arg2, len;
8407   const char *p1, *p2;
8408
8409   if (!validate_arglist (arglist,
8410                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8411     return 0;
8412
8413   arg1 = TREE_VALUE (arglist);
8414   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8415   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8416
8417   /* If the LEN parameter is zero, return zero.  */
8418   if (integer_zerop (len))
8419     return omit_two_operands (integer_type_node, integer_zero_node,
8420                               arg1, arg2);
8421
8422   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8423   if (operand_equal_p (arg1, arg2, 0))
8424     return omit_one_operand (integer_type_node, integer_zero_node, len);
8425
8426   p1 = c_getstr (arg1);
8427   p2 = c_getstr (arg2);
8428
8429   /* If all arguments are constant, and the value of len is not greater
8430      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8431   if (host_integerp (len, 1) && p1 && p2
8432       && compare_tree_int (len, strlen (p1) + 1) <= 0
8433       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8434     {
8435       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8436
8437       if (r > 0)
8438         return integer_one_node;
8439       else if (r < 0)
8440         return integer_minus_one_node;
8441       else
8442         return integer_zero_node;
8443     }
8444
8445   /* If len parameter is one, return an expression corresponding to
8446      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8447   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8448     {
8449       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8450       tree cst_uchar_ptr_node
8451         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8452
8453       tree ind1 = fold_convert (integer_type_node,
8454                                 build1 (INDIRECT_REF, cst_uchar_node,
8455                                         fold_convert (cst_uchar_ptr_node,
8456                                                       arg1)));
8457       tree ind2 = fold_convert (integer_type_node,
8458                                 build1 (INDIRECT_REF, cst_uchar_node,
8459                                         fold_convert (cst_uchar_ptr_node,
8460                                                       arg2)));
8461       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8462     }
8463
8464   return 0;
8465 }
8466
8467 /* Fold function call to builtin strcmp.  Return
8468    NULL_TREE if no simplification can be made.  */
8469
8470 static tree
8471 fold_builtin_strcmp (tree arglist)
8472 {
8473   tree arg1, arg2;
8474   const char *p1, *p2;
8475
8476   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8477     return 0;
8478
8479   arg1 = TREE_VALUE (arglist);
8480   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8481
8482   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8483   if (operand_equal_p (arg1, arg2, 0))
8484     return integer_zero_node;
8485
8486   p1 = c_getstr (arg1);
8487   p2 = c_getstr (arg2);
8488
8489   if (p1 && p2)
8490     {
8491       const int i = strcmp (p1, p2);
8492       if (i < 0)
8493         return integer_minus_one_node;
8494       else if (i > 0)
8495         return integer_one_node;
8496       else
8497         return integer_zero_node;
8498     }
8499
8500   /* If the second arg is "", return *(const unsigned char*)arg1.  */
8501   if (p2 && *p2 == '\0')
8502     {
8503       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8504       tree cst_uchar_ptr_node
8505         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8506
8507       return fold_convert (integer_type_node,
8508                            build1 (INDIRECT_REF, cst_uchar_node,
8509                                    fold_convert (cst_uchar_ptr_node,
8510                                                  arg1)));
8511     }
8512
8513   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8514   if (p1 && *p1 == '\0')
8515     {
8516       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8517       tree cst_uchar_ptr_node
8518         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8519
8520       tree temp = fold_convert (integer_type_node,
8521                                 build1 (INDIRECT_REF, cst_uchar_node,
8522                                         fold_convert (cst_uchar_ptr_node,
8523                                                       arg2)));
8524       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8525     }
8526
8527   return 0;
8528 }
8529
8530 /* Fold function call to builtin strncmp.  Return
8531    NULL_TREE if no simplification can be made.  */
8532
8533 static tree
8534 fold_builtin_strncmp (tree arglist)
8535 {
8536   tree arg1, arg2, len;
8537   const char *p1, *p2;
8538
8539   if (!validate_arglist (arglist,
8540                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8541     return 0;
8542
8543   arg1 = TREE_VALUE (arglist);
8544   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8545   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8546
8547   /* If the LEN parameter is zero, return zero.  */
8548   if (integer_zerop (len))
8549     return omit_two_operands (integer_type_node, integer_zero_node,
8550                               arg1, arg2);
8551
8552   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8553   if (operand_equal_p (arg1, arg2, 0))
8554     return omit_one_operand (integer_type_node, integer_zero_node, len);
8555
8556   p1 = c_getstr (arg1);
8557   p2 = c_getstr (arg2);
8558
8559   if (host_integerp (len, 1) && p1 && p2)
8560     {
8561       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8562       if (i > 0)
8563         return integer_one_node;
8564       else if (i < 0)
8565         return integer_minus_one_node;
8566       else
8567         return integer_zero_node;
8568     }
8569
8570   /* If the second arg is "", and the length is greater than zero,
8571      return *(const unsigned char*)arg1.  */
8572   if (p2 && *p2 == '\0'
8573       && TREE_CODE (len) == INTEGER_CST
8574       && tree_int_cst_sgn (len) == 1)
8575     {
8576       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8577       tree cst_uchar_ptr_node
8578         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8579
8580       return fold_convert (integer_type_node,
8581                            build1 (INDIRECT_REF, cst_uchar_node,
8582                                    fold_convert (cst_uchar_ptr_node,
8583                                                  arg1)));
8584     }
8585
8586   /* If the first arg is "", and the length is greater than zero,
8587      return -*(const unsigned char*)arg2.  */
8588   if (p1 && *p1 == '\0'
8589       && TREE_CODE (len) == INTEGER_CST
8590       && tree_int_cst_sgn (len) == 1)
8591     {
8592       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8593       tree cst_uchar_ptr_node
8594         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8595
8596       tree temp = fold_convert (integer_type_node,
8597                                 build1 (INDIRECT_REF, cst_uchar_node,
8598                                         fold_convert (cst_uchar_ptr_node,
8599                                                       arg2)));
8600       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8601     }
8602
8603   /* If len parameter is one, return an expression corresponding to
8604      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8605   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8606     {
8607       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8608       tree cst_uchar_ptr_node
8609         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8610
8611       tree ind1 = fold_convert (integer_type_node,
8612                                 build1 (INDIRECT_REF, cst_uchar_node,
8613                                         fold_convert (cst_uchar_ptr_node,
8614                                                       arg1)));
8615       tree ind2 = fold_convert (integer_type_node,
8616                                 build1 (INDIRECT_REF, cst_uchar_node,
8617                                         fold_convert (cst_uchar_ptr_node,
8618                                                       arg2)));
8619       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8620     }
8621
8622   return 0;
8623 }
8624
8625 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8626    NULL_TREE if no simplification can be made.  */
8627
8628 static tree
8629 fold_builtin_signbit (tree fndecl, tree arglist)
8630 {
8631   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8632   tree arg, temp;
8633
8634   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8635     return NULL_TREE;
8636
8637   arg = TREE_VALUE (arglist);
8638
8639   /* If ARG is a compile-time constant, determine the result.  */
8640   if (TREE_CODE (arg) == REAL_CST
8641       && !TREE_CONSTANT_OVERFLOW (arg))
8642     {
8643       REAL_VALUE_TYPE c;
8644
8645       c = TREE_REAL_CST (arg);
8646       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8647       return fold_convert (type, temp);
8648     }
8649
8650   /* If ARG is non-negative, the result is always zero.  */
8651   if (tree_expr_nonnegative_p (arg))
8652     return omit_one_operand (type, integer_zero_node, arg);
8653
8654   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8655   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8656     return fold_build2 (LT_EXPR, type, arg,
8657                         build_real (TREE_TYPE (arg), dconst0));
8658
8659   return NULL_TREE;
8660 }
8661
8662 /* Fold function call to builtin copysign, copysignf or copysignl.
8663    Return NULL_TREE if no simplification can be made.  */
8664
8665 static tree
8666 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8667 {
8668   tree arg1, arg2, tem;
8669
8670   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8671     return NULL_TREE;
8672
8673   arg1 = TREE_VALUE (arglist);
8674   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8675
8676   /* copysign(X,X) is X.  */
8677   if (operand_equal_p (arg1, arg2, 0))
8678     return fold_convert (type, arg1);
8679
8680   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8681   if (TREE_CODE (arg1) == REAL_CST
8682       && TREE_CODE (arg2) == REAL_CST
8683       && !TREE_CONSTANT_OVERFLOW (arg1)
8684       && !TREE_CONSTANT_OVERFLOW (arg2))
8685     {
8686       REAL_VALUE_TYPE c1, c2;
8687
8688       c1 = TREE_REAL_CST (arg1);
8689       c2 = TREE_REAL_CST (arg2);
8690       /* c1.sign := c2.sign.  */
8691       real_copysign (&c1, &c2);
8692       return build_real (type, c1);
8693     }
8694
8695   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8696      Remember to evaluate Y for side-effects.  */
8697   if (tree_expr_nonnegative_p (arg2))
8698     return omit_one_operand (type,
8699                              fold_build1 (ABS_EXPR, type, arg1),
8700                              arg2);
8701
8702   /* Strip sign changing operations for the first argument.  */
8703   tem = fold_strip_sign_ops (arg1);
8704   if (tem)
8705     {
8706       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8707       return build_function_call_expr (fndecl, arglist);
8708     }
8709
8710   return NULL_TREE;
8711 }
8712
8713 /* Fold a call to builtin isascii.  */
8714
8715 static tree
8716 fold_builtin_isascii (tree arglist)
8717 {
8718   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8719     return 0;
8720   else
8721     {
8722       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8723       tree arg = TREE_VALUE (arglist);
8724
8725       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8726                     build_int_cst (NULL_TREE,
8727                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8728       return fold_build2 (EQ_EXPR, integer_type_node,
8729                           arg, integer_zero_node);
8730     }
8731 }
8732
8733 /* Fold a call to builtin toascii.  */
8734
8735 static tree
8736 fold_builtin_toascii (tree arglist)
8737 {
8738   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8739     return 0;
8740   else
8741     {
8742       /* Transform toascii(c) -> (c & 0x7f).  */
8743       tree arg = TREE_VALUE (arglist);
8744
8745       return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8746                           build_int_cst (NULL_TREE, 0x7f));
8747     }
8748 }
8749
8750 /* Fold a call to builtin isdigit.  */
8751
8752 static tree
8753 fold_builtin_isdigit (tree arglist)
8754 {
8755   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8756     return 0;
8757   else
8758     {
8759       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8760       /* According to the C standard, isdigit is unaffected by locale.
8761          However, it definitely is affected by the target character set.  */
8762       tree arg;
8763       unsigned HOST_WIDE_INT target_digit0
8764         = lang_hooks.to_target_charset ('0');
8765
8766       if (target_digit0 == 0)
8767         return NULL_TREE;
8768
8769       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8770       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8771                     build_int_cst (unsigned_type_node, target_digit0));
8772       return fold_build2 (LE_EXPR, integer_type_node, arg,
8773                           build_int_cst (unsigned_type_node, 9));
8774     }
8775 }
8776
8777 /* Fold a call to fabs, fabsf or fabsl.  */
8778
8779 static tree
8780 fold_builtin_fabs (tree arglist, tree type)
8781 {
8782   tree arg;
8783
8784   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8785     return 0;
8786
8787   arg = TREE_VALUE (arglist);
8788   arg = fold_convert (type, arg);
8789   if (TREE_CODE (arg) == REAL_CST)
8790     return fold_abs_const (arg, type);
8791   return fold_build1 (ABS_EXPR, type, arg);
8792 }
8793
8794 /* Fold a call to abs, labs, llabs or imaxabs.  */
8795
8796 static tree
8797 fold_builtin_abs (tree arglist, tree type)
8798 {
8799   tree arg;
8800
8801   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8802     return 0;
8803
8804   arg = TREE_VALUE (arglist);
8805   arg = fold_convert (type, arg);
8806   if (TREE_CODE (arg) == INTEGER_CST)
8807     return fold_abs_const (arg, type);
8808   return fold_build1 (ABS_EXPR, type, arg);
8809 }
8810
8811 /* Fold a call to builtin fmin or fmax.  */
8812
8813 static tree
8814 fold_builtin_fmin_fmax (tree arglist, tree type, bool max)
8815 {
8816   if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8817     {
8818       tree arg0 = TREE_VALUE (arglist);
8819       tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8820       /* Calculate the result when the argument is a constant.  */
8821       tree res = do_mpfr_arg2 (arg0, arg1, type, (max ? mpfr_max : mpfr_min));
8822
8823       if (res)
8824         return res;
8825
8826       /* If either argument is NaN, return the other one.  Avoid the
8827          transformation if we get (and honor) a signalling NaN.  Using
8828          omit_one_operand() ensures we create a non-lvalue.  */
8829       if (TREE_CODE (arg0) == REAL_CST
8830           && real_isnan (&TREE_REAL_CST (arg0))
8831           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
8832               || ! TREE_REAL_CST (arg0).signalling))
8833         return omit_one_operand (type, arg1, arg0);
8834       if (TREE_CODE (arg1) == REAL_CST
8835           && real_isnan (&TREE_REAL_CST (arg1))
8836           && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
8837               || ! TREE_REAL_CST (arg1).signalling))
8838         return omit_one_operand (type, arg0, arg1);
8839
8840       /* Transform fmin/fmax(x,x) -> x.  */
8841       if (operand_equal_p (arg0, arg1, OEP_PURE_SAME))
8842         return omit_one_operand (type, arg0, arg1);
8843       
8844       /* Convert fmin/fmax to MIN_EXPR/MAX_EXPR.  C99 requires these
8845          functions to return the numeric arg if the other one is NaN.
8846          These tree codes don't honor that, so only transform if
8847          -ffinite-math-only is set.  C99 doesn't require -0.0 to be
8848          handled, so we don't have to worry about it either.  */
8849       if (flag_finite_math_only)
8850         return fold_build2 ((max ? MAX_EXPR : MIN_EXPR), type,
8851                             fold_convert (type, arg0),
8852                             fold_convert (type, arg1));
8853     }
8854   return NULL_TREE;
8855 }
8856
8857 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8858    EXP is the CALL_EXPR for the call.  */
8859
8860 static tree
8861 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8862 {
8863   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8864   tree arg;
8865   REAL_VALUE_TYPE r;
8866
8867   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8868     {
8869       /* Check that we have exactly one argument.  */
8870       if (arglist == 0)
8871         {
8872           error ("too few arguments to function %qs",
8873                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8874           return error_mark_node;
8875         }
8876       else if (TREE_CHAIN (arglist) != 0)
8877         {
8878           error ("too many arguments to function %qs",
8879                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8880           return error_mark_node;
8881         }
8882       else
8883         {
8884           error ("non-floating-point argument to function %qs",
8885                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8886           return error_mark_node;
8887         }
8888     }
8889
8890   arg = TREE_VALUE (arglist);
8891   switch (builtin_index)
8892     {
8893     case BUILT_IN_ISINF:
8894       if (!HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8895         return omit_one_operand (type, integer_zero_node, arg);
8896
8897       if (TREE_CODE (arg) == REAL_CST)
8898         {
8899           r = TREE_REAL_CST (arg);
8900           if (real_isinf (&r))
8901             return real_compare (GT_EXPR, &r, &dconst0)
8902                    ? integer_one_node : integer_minus_one_node;
8903           else
8904             return integer_zero_node;
8905         }
8906
8907       return NULL_TREE;
8908
8909     case BUILT_IN_FINITE:
8910       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg)))
8911           && !HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8912         return omit_one_operand (type, integer_one_node, arg);
8913
8914       if (TREE_CODE (arg) == REAL_CST)
8915         {
8916           r = TREE_REAL_CST (arg);
8917           return real_isinf (&r) || real_isnan (&r)
8918                  ? integer_zero_node : integer_one_node;
8919         }
8920
8921       return NULL_TREE;
8922
8923     case BUILT_IN_ISNAN:
8924       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg))))
8925         return omit_one_operand (type, integer_zero_node, arg);
8926
8927       if (TREE_CODE (arg) == REAL_CST)
8928         {
8929           r = TREE_REAL_CST (arg);
8930           return real_isnan (&r) ? integer_one_node : integer_zero_node;
8931         }
8932
8933       arg = builtin_save_expr (arg);
8934       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8935
8936     default:
8937       gcc_unreachable ();
8938     }
8939 }
8940
8941 /* Fold a call to an unordered comparison function such as
8942    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8943    being called and ARGLIST is the argument list for the call.
8944    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8945    the opposite of the desired result.  UNORDERED_CODE is used
8946    for modes that can hold NaNs and ORDERED_CODE is used for
8947    the rest.  */
8948
8949 static tree
8950 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8951                             enum tree_code unordered_code,
8952                             enum tree_code ordered_code)
8953 {
8954   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8955   enum tree_code code;
8956   tree arg0, arg1;
8957   tree type0, type1;
8958   enum tree_code code0, code1;
8959   tree cmp_type = NULL_TREE;
8960
8961   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8962     {
8963       /* Check that we have exactly two arguments.  */
8964       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8965         {
8966           error ("too few arguments to function %qs",
8967                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8968           return error_mark_node;
8969         }
8970       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8971         {
8972           error ("too many arguments to function %qs",
8973                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8974           return error_mark_node;
8975         }
8976     }
8977
8978   arg0 = TREE_VALUE (arglist);
8979   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8980
8981   type0 = TREE_TYPE (arg0);
8982   type1 = TREE_TYPE (arg1);
8983
8984   code0 = TREE_CODE (type0);
8985   code1 = TREE_CODE (type1);
8986
8987   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8988     /* Choose the wider of two real types.  */
8989     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8990       ? type0 : type1;
8991   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8992     cmp_type = type0;
8993   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8994     cmp_type = type1;
8995   else
8996     {
8997       error ("non-floating-point argument to function %qs",
8998                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8999       return error_mark_node;
9000     }
9001
9002   arg0 = fold_convert (cmp_type, arg0);
9003   arg1 = fold_convert (cmp_type, arg1);
9004
9005   if (unordered_code == UNORDERED_EXPR)
9006     {
9007       if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
9008         return omit_two_operands (type, integer_zero_node, arg0, arg1);
9009       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
9010     }
9011
9012   code = HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
9013                                                    : ordered_code;
9014   return fold_build1 (TRUTH_NOT_EXPR, type,
9015                       fold_build2 (code, type, arg0, arg1));
9016 }
9017
9018 /* Used by constant folding to simplify calls to builtin functions.  EXP is
9019    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
9020    result of the function call is ignored.  This function returns NULL_TREE
9021    if no simplification was possible.  */
9022
9023 static tree
9024 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
9025 {
9026   tree type = TREE_TYPE (TREE_TYPE (fndecl));
9027   enum built_in_function fcode;
9028
9029   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
9030     return targetm.fold_builtin (fndecl, arglist, ignore);
9031
9032   fcode = DECL_FUNCTION_CODE (fndecl);
9033   switch (fcode)
9034     {
9035     case BUILT_IN_FPUTS:
9036       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
9037
9038     case BUILT_IN_FPUTS_UNLOCKED:
9039       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
9040
9041     case BUILT_IN_STRSTR:
9042       return fold_builtin_strstr (arglist, type);
9043
9044     case BUILT_IN_STRCAT:
9045       return fold_builtin_strcat (arglist);
9046
9047     case BUILT_IN_STRNCAT:
9048       return fold_builtin_strncat (arglist);
9049
9050     case BUILT_IN_STRSPN:
9051       return fold_builtin_strspn (arglist);
9052
9053     case BUILT_IN_STRCSPN:
9054       return fold_builtin_strcspn (arglist);
9055
9056     case BUILT_IN_STRCHR:
9057     case BUILT_IN_INDEX:
9058       return fold_builtin_strchr (arglist, type);
9059
9060     case BUILT_IN_STRRCHR:
9061     case BUILT_IN_RINDEX:
9062       return fold_builtin_strrchr (arglist, type);
9063
9064     case BUILT_IN_STRCPY:
9065       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
9066
9067     case BUILT_IN_STRNCPY:
9068       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
9069
9070     case BUILT_IN_STRCMP:
9071       return fold_builtin_strcmp (arglist);
9072
9073     case BUILT_IN_STRNCMP:
9074       return fold_builtin_strncmp (arglist);
9075
9076     case BUILT_IN_STRPBRK:
9077       return fold_builtin_strpbrk (arglist, type);
9078
9079     case BUILT_IN_BCMP:
9080     case BUILT_IN_MEMCMP:
9081       return fold_builtin_memcmp (arglist);
9082
9083     case BUILT_IN_SPRINTF:
9084       return fold_builtin_sprintf (arglist, ignore);
9085
9086     case BUILT_IN_CONSTANT_P:
9087       {
9088         tree val;
9089
9090         val = fold_builtin_constant_p (arglist);
9091         /* Gimplification will pull the CALL_EXPR for the builtin out of
9092            an if condition.  When not optimizing, we'll not CSE it back.
9093            To avoid link error types of regressions, return false now.  */
9094         if (!val && !optimize)
9095           val = integer_zero_node;
9096
9097         return val;
9098       }
9099
9100     case BUILT_IN_EXPECT:
9101       return fold_builtin_expect (arglist);
9102
9103     case BUILT_IN_CLASSIFY_TYPE:
9104       return fold_builtin_classify_type (arglist);
9105
9106     case BUILT_IN_STRLEN:
9107       return fold_builtin_strlen (arglist);
9108
9109     CASE_FLT_FN (BUILT_IN_FABS):
9110       return fold_builtin_fabs (arglist, type);
9111
9112     case BUILT_IN_ABS:
9113     case BUILT_IN_LABS:
9114     case BUILT_IN_LLABS:
9115     case BUILT_IN_IMAXABS:
9116       return fold_builtin_abs (arglist, type);
9117
9118     CASE_FLT_FN (BUILT_IN_CONJ):
9119       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9120         return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
9121       break;
9122
9123     CASE_FLT_FN (BUILT_IN_CREAL):
9124       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9125         return non_lvalue (fold_build1 (REALPART_EXPR, type,
9126                                         TREE_VALUE (arglist)));
9127       break;
9128
9129     CASE_FLT_FN (BUILT_IN_CIMAG):
9130       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
9131         return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
9132                                         TREE_VALUE (arglist)));
9133       break;
9134
9135     CASE_FLT_FN (BUILT_IN_CABS):
9136       return fold_builtin_cabs (arglist, type, fndecl);
9137
9138     CASE_FLT_FN (BUILT_IN_SQRT):
9139       return fold_builtin_sqrt (arglist, type);
9140
9141     CASE_FLT_FN (BUILT_IN_CBRT):
9142       return fold_builtin_cbrt (arglist, type);
9143
9144     CASE_FLT_FN (BUILT_IN_ASIN):
9145       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9146         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asin,
9147                              &dconstm1, &dconst1, true);
9148     break;
9149
9150     CASE_FLT_FN (BUILT_IN_ACOS):
9151       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9152         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acos,
9153                              &dconstm1, &dconst1, true);
9154     break;
9155
9156     CASE_FLT_FN (BUILT_IN_ATAN):
9157       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9158         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atan,
9159                              NULL, NULL, 0);
9160     break;
9161
9162     CASE_FLT_FN (BUILT_IN_ASINH):
9163       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9164         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_asinh,
9165                              NULL, NULL, 0);
9166     break;
9167
9168     CASE_FLT_FN (BUILT_IN_ACOSH):
9169       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9170         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_acosh,
9171                              &dconst1, NULL, true);
9172     break;
9173
9174     CASE_FLT_FN (BUILT_IN_ATANH):
9175       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9176         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_atanh,
9177                              &dconstm1, &dconst1, false);
9178     break;
9179
9180     CASE_FLT_FN (BUILT_IN_SIN):
9181       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9182         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sin,
9183                              NULL, NULL, 0);
9184     break;
9185
9186     CASE_FLT_FN (BUILT_IN_COS):
9187       return fold_builtin_cos (arglist, type, fndecl);
9188
9189     CASE_FLT_FN (BUILT_IN_TAN):
9190       return fold_builtin_tan (arglist, type);
9191
9192     CASE_FLT_FN (BUILT_IN_SINCOS):
9193       if (validate_arglist (arglist, REAL_TYPE, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9194         return do_mpfr_sincos (TREE_VALUE (arglist), TREE_VALUE (TREE_CHAIN (arglist)),
9195                                TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))));
9196     break;
9197
9198     CASE_FLT_FN (BUILT_IN_SINH):
9199       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9200         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_sinh,
9201                              NULL, NULL, 0);
9202     break;
9203
9204     CASE_FLT_FN (BUILT_IN_COSH):
9205       return fold_builtin_cosh (arglist, type, fndecl);
9206
9207     CASE_FLT_FN (BUILT_IN_TANH):
9208       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9209         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_tanh,
9210                              NULL, NULL, 0);
9211     break;
9212
9213     CASE_FLT_FN (BUILT_IN_ERF):
9214       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9215         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erf,
9216                              NULL, NULL, 0);
9217     break;
9218
9219     CASE_FLT_FN (BUILT_IN_ERFC):
9220       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9221         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_erfc,
9222                              NULL, NULL, 0);
9223     break;
9224
9225     CASE_FLT_FN (BUILT_IN_TGAMMA):
9226       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9227         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_gamma,
9228                              NULL, NULL, 0);
9229     break;
9230  
9231     CASE_FLT_FN (BUILT_IN_EXP):
9232       return fold_builtin_exponent (fndecl, arglist, mpfr_exp);
9233
9234     CASE_FLT_FN (BUILT_IN_EXP2):
9235       return fold_builtin_exponent (fndecl, arglist, mpfr_exp2);
9236
9237     CASE_FLT_FN (BUILT_IN_EXP10):
9238     CASE_FLT_FN (BUILT_IN_POW10):
9239       return fold_builtin_exponent (fndecl, arglist, mpfr_exp10);
9240
9241     CASE_FLT_FN (BUILT_IN_EXPM1):
9242       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9243         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_expm1,
9244                              NULL, NULL, 0);
9245     break;
9246  
9247     CASE_FLT_FN (BUILT_IN_LOG):
9248       return fold_builtin_logarithm (fndecl, arglist, mpfr_log);
9249
9250     CASE_FLT_FN (BUILT_IN_LOG2):
9251       return fold_builtin_logarithm (fndecl, arglist, mpfr_log2);
9252
9253     CASE_FLT_FN (BUILT_IN_LOG10):
9254       return fold_builtin_logarithm (fndecl, arglist, mpfr_log10);
9255
9256     CASE_FLT_FN (BUILT_IN_LOG1P):
9257       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
9258         return do_mpfr_arg1 (TREE_VALUE (arglist), type, mpfr_log1p,
9259                              &dconstm1, NULL, false);
9260     break;
9261
9262     CASE_FLT_FN (BUILT_IN_ATAN2):
9263       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9264         return do_mpfr_arg2 (TREE_VALUE (arglist),
9265                              TREE_VALUE (TREE_CHAIN (arglist)),
9266                              type, mpfr_atan2);
9267     break;
9268
9269     CASE_FLT_FN (BUILT_IN_FMA):
9270       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE, VOID_TYPE))
9271         return do_mpfr_arg3 (TREE_VALUE (arglist),
9272                              TREE_VALUE (TREE_CHAIN (arglist)),
9273                              TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
9274                              type, mpfr_fma);
9275     break;
9276
9277     CASE_FLT_FN (BUILT_IN_FMIN):
9278       return fold_builtin_fmin_fmax (arglist, type, /*max=*/false);
9279
9280     CASE_FLT_FN (BUILT_IN_FMAX):
9281       return fold_builtin_fmin_fmax (arglist, type, /*max=*/true);
9282
9283     CASE_FLT_FN (BUILT_IN_HYPOT):
9284       return fold_builtin_hypot (fndecl, arglist, type);
9285     
9286     CASE_FLT_FN (BUILT_IN_POW):
9287       return fold_builtin_pow (fndecl, arglist, type);
9288
9289     CASE_FLT_FN (BUILT_IN_POWI):
9290       return fold_builtin_powi (fndecl, arglist, type);
9291
9292     CASE_FLT_FN (BUILT_IN_INF):
9293     case BUILT_IN_INFD32:
9294     case BUILT_IN_INFD64:
9295     case BUILT_IN_INFD128:
9296       return fold_builtin_inf (type, true);
9297
9298     CASE_FLT_FN (BUILT_IN_HUGE_VAL):
9299       return fold_builtin_inf (type, false);
9300
9301     CASE_FLT_FN (BUILT_IN_NAN):
9302     case BUILT_IN_NAND32:
9303     case BUILT_IN_NAND64:
9304     case BUILT_IN_NAND128:
9305       return fold_builtin_nan (arglist, type, true);
9306
9307     CASE_FLT_FN (BUILT_IN_NANS):
9308       return fold_builtin_nan (arglist, type, false);
9309
9310     CASE_FLT_FN (BUILT_IN_FLOOR):
9311       return fold_builtin_floor (fndecl, arglist);
9312
9313     CASE_FLT_FN (BUILT_IN_CEIL):
9314       return fold_builtin_ceil (fndecl, arglist);
9315
9316     CASE_FLT_FN (BUILT_IN_TRUNC):
9317       return fold_builtin_trunc (fndecl, arglist);
9318
9319     CASE_FLT_FN (BUILT_IN_ROUND):
9320       return fold_builtin_round (fndecl, arglist);
9321
9322     CASE_FLT_FN (BUILT_IN_NEARBYINT):
9323     CASE_FLT_FN (BUILT_IN_RINT):
9324       return fold_trunc_transparent_mathfn (fndecl, arglist);
9325
9326     CASE_FLT_FN (BUILT_IN_LCEIL):
9327     CASE_FLT_FN (BUILT_IN_LLCEIL):
9328     CASE_FLT_FN (BUILT_IN_LFLOOR):
9329     CASE_FLT_FN (BUILT_IN_LLFLOOR):
9330     CASE_FLT_FN (BUILT_IN_LROUND):
9331     CASE_FLT_FN (BUILT_IN_LLROUND):
9332       return fold_builtin_int_roundingfn (fndecl, arglist);
9333
9334     CASE_FLT_FN (BUILT_IN_LRINT):
9335     CASE_FLT_FN (BUILT_IN_LLRINT):
9336       return fold_fixed_mathfn (fndecl, arglist);
9337
9338     case BUILT_IN_BSWAP32:
9339     case BUILT_IN_BSWAP64:
9340       return fold_builtin_bswap (fndecl, arglist);
9341
9342     CASE_INT_FN (BUILT_IN_FFS):
9343     CASE_INT_FN (BUILT_IN_CLZ):
9344     CASE_INT_FN (BUILT_IN_CTZ):
9345     CASE_INT_FN (BUILT_IN_POPCOUNT):
9346     CASE_INT_FN (BUILT_IN_PARITY):
9347       return fold_builtin_bitop (fndecl, arglist);
9348
9349     case BUILT_IN_MEMSET:
9350       return fold_builtin_memset (arglist, type, ignore);
9351
9352     case BUILT_IN_MEMCPY:
9353       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/0);
9354
9355     case BUILT_IN_MEMPCPY:
9356       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/1);
9357
9358     case BUILT_IN_MEMMOVE:
9359       return fold_builtin_memory_op (arglist, type, ignore, /*endp=*/3);
9360
9361     case BUILT_IN_BZERO:
9362       return fold_builtin_bzero (arglist, ignore);
9363
9364     case BUILT_IN_BCOPY:
9365       return fold_builtin_bcopy (arglist, ignore);
9366
9367     CASE_FLT_FN (BUILT_IN_SIGNBIT):
9368       return fold_builtin_signbit (fndecl, arglist);
9369
9370     case BUILT_IN_ISASCII:
9371       return fold_builtin_isascii (arglist);
9372
9373     case BUILT_IN_TOASCII:
9374       return fold_builtin_toascii (arglist);
9375
9376     case BUILT_IN_ISDIGIT:
9377       return fold_builtin_isdigit (arglist);
9378
9379     CASE_FLT_FN (BUILT_IN_COPYSIGN):
9380       return fold_builtin_copysign (fndecl, arglist, type);
9381
9382     CASE_FLT_FN (BUILT_IN_FINITE):
9383     case BUILT_IN_FINITED32:
9384     case BUILT_IN_FINITED64:
9385     case BUILT_IN_FINITED128:
9386       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
9387
9388     CASE_FLT_FN (BUILT_IN_ISINF):
9389     case BUILT_IN_ISINFD32:
9390     case BUILT_IN_ISINFD64:
9391     case BUILT_IN_ISINFD128:
9392       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
9393
9394     CASE_FLT_FN (BUILT_IN_ISNAN):
9395     case BUILT_IN_ISNAND32:
9396     case BUILT_IN_ISNAND64:
9397     case BUILT_IN_ISNAND128:
9398       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
9399
9400     case BUILT_IN_ISGREATER:
9401       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
9402     case BUILT_IN_ISGREATEREQUAL:
9403       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
9404     case BUILT_IN_ISLESS:
9405       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
9406     case BUILT_IN_ISLESSEQUAL:
9407       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
9408     case BUILT_IN_ISLESSGREATER:
9409       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
9410     case BUILT_IN_ISUNORDERED:
9411       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
9412                                          NOP_EXPR);
9413
9414       /* We do the folding for va_start in the expander.  */
9415     case BUILT_IN_VA_START:
9416       break;
9417
9418     case BUILT_IN_OBJECT_SIZE:
9419       return fold_builtin_object_size (arglist);
9420     case BUILT_IN_MEMCPY_CHK:
9421     case BUILT_IN_MEMPCPY_CHK:
9422     case BUILT_IN_MEMMOVE_CHK:
9423     case BUILT_IN_MEMSET_CHK:
9424       return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
9425                                       DECL_FUNCTION_CODE (fndecl));
9426     case BUILT_IN_STRCPY_CHK:
9427     case BUILT_IN_STPCPY_CHK:
9428       return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
9429                                       DECL_FUNCTION_CODE (fndecl));
9430     case BUILT_IN_STRNCPY_CHK:
9431       return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9432     case BUILT_IN_STRCAT_CHK:
9433       return fold_builtin_strcat_chk (fndecl, arglist);
9434     case BUILT_IN_STRNCAT_CHK:
9435       return fold_builtin_strncat_chk (fndecl, arglist);
9436     case BUILT_IN_SPRINTF_CHK:
9437     case BUILT_IN_VSPRINTF_CHK:
9438       return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9439     case BUILT_IN_SNPRINTF_CHK:
9440     case BUILT_IN_VSNPRINTF_CHK:
9441       return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9442                                         DECL_FUNCTION_CODE (fndecl));
9443
9444     case BUILT_IN_PRINTF:
9445     case BUILT_IN_PRINTF_UNLOCKED:
9446     case BUILT_IN_VPRINTF:
9447     case BUILT_IN_PRINTF_CHK:
9448     case BUILT_IN_VPRINTF_CHK:
9449       return fold_builtin_printf (fndecl, arglist, ignore,
9450                                   DECL_FUNCTION_CODE (fndecl));
9451
9452     case BUILT_IN_FPRINTF:
9453     case BUILT_IN_FPRINTF_UNLOCKED:
9454     case BUILT_IN_VFPRINTF:
9455     case BUILT_IN_FPRINTF_CHK:
9456     case BUILT_IN_VFPRINTF_CHK:
9457       return fold_builtin_fprintf (fndecl, arglist, ignore,
9458                                    DECL_FUNCTION_CODE (fndecl));
9459
9460     default:
9461       break;
9462     }
9463
9464   return 0;
9465 }
9466
9467 /* A wrapper function for builtin folding that prevents warnings for
9468    "statement without effect" and the like, caused by removing the
9469    call node earlier than the warning is generated.  */
9470
9471 tree
9472 fold_builtin (tree fndecl, tree arglist, bool ignore)
9473 {
9474   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9475   if (exp && !ignore)
9476     {
9477       exp = build1 (NOP_EXPR, GENERIC_TREE_TYPE (exp), exp);
9478       TREE_NO_WARNING (exp) = 1;
9479     }
9480
9481   return exp;
9482 }
9483
9484 /* Conveniently construct a function call expression.  */
9485
9486 tree
9487 build_function_call_expr (tree fn, tree arglist)
9488 {
9489   tree call_expr;
9490
9491   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9492   return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9493                       call_expr, arglist, NULL_TREE);
9494 }
9495
9496 /* This function validates the types of a function call argument list
9497    represented as a tree chain of parameters against a specified list
9498    of tree_codes.  If the last specifier is a 0, that represents an
9499    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9500
9501 static int
9502 validate_arglist (tree arglist, ...)
9503 {
9504   enum tree_code code;
9505   int res = 0;
9506   va_list ap;
9507
9508   va_start (ap, arglist);
9509
9510   do
9511     {
9512       code = va_arg (ap, enum tree_code);
9513       switch (code)
9514         {
9515         case 0:
9516           /* This signifies an ellipses, any further arguments are all ok.  */
9517           res = 1;
9518           goto end;
9519         case VOID_TYPE:
9520           /* This signifies an endlink, if no arguments remain, return
9521              true, otherwise return false.  */
9522           res = arglist == 0;
9523           goto end;
9524         default:
9525           /* If no parameters remain or the parameter's code does not
9526              match the specified code, return false.  Otherwise continue
9527              checking any remaining arguments.  */
9528           if (arglist == 0)
9529             goto end;
9530           if (code == POINTER_TYPE)
9531             {
9532               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9533                 goto end;
9534             }
9535           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9536             goto end;
9537           break;
9538         }
9539       arglist = TREE_CHAIN (arglist);
9540     }
9541   while (1);
9542
9543   /* We need gotos here since we can only have one VA_CLOSE in a
9544      function.  */
9545  end: ;
9546   va_end (ap);
9547
9548   return res;
9549 }
9550
9551 /* Default target-specific builtin expander that does nothing.  */
9552
9553 rtx
9554 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9555                         rtx target ATTRIBUTE_UNUSED,
9556                         rtx subtarget ATTRIBUTE_UNUSED,
9557                         enum machine_mode mode ATTRIBUTE_UNUSED,
9558                         int ignore ATTRIBUTE_UNUSED)
9559 {
9560   return NULL_RTX;
9561 }
9562
9563 /* Returns true is EXP represents data that would potentially reside
9564    in a readonly section.  */
9565
9566 static bool
9567 readonly_data_expr (tree exp)
9568 {
9569   STRIP_NOPS (exp);
9570
9571   if (TREE_CODE (exp) != ADDR_EXPR)
9572     return false;
9573
9574   exp = get_base_address (TREE_OPERAND (exp, 0));
9575   if (!exp)
9576     return false;
9577
9578   /* Make sure we call decl_readonly_section only for trees it
9579      can handle (since it returns true for everything it doesn't
9580      understand).  */
9581   if (TREE_CODE (exp) == STRING_CST
9582       || TREE_CODE (exp) == CONSTRUCTOR
9583       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9584     return decl_readonly_section (exp, 0);
9585   else
9586     return false;
9587 }
9588
9589 /* Simplify a call to the strstr builtin.
9590
9591    Return 0 if no simplification was possible, otherwise return the
9592    simplified form of the call as a tree.
9593
9594    The simplified form may be a constant or other expression which
9595    computes the same value, but in a more efficient manner (including
9596    calls to other builtin functions).
9597
9598    The call may contain arguments which need to be evaluated, but
9599    which are not useful to determine the result of the call.  In
9600    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9601    COMPOUND_EXPR will be an argument which must be evaluated.
9602    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9603    COMPOUND_EXPR in the chain will contain the tree for the simplified
9604    form of the builtin function call.  */
9605
9606 static tree
9607 fold_builtin_strstr (tree arglist, tree type)
9608 {
9609   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9610     return 0;
9611   else
9612     {
9613       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9614       tree fn;
9615       const char *p1, *p2;
9616
9617       p2 = c_getstr (s2);
9618       if (p2 == NULL)
9619         return 0;
9620
9621       p1 = c_getstr (s1);
9622       if (p1 != NULL)
9623         {
9624           const char *r = strstr (p1, p2);
9625           tree tem;
9626
9627           if (r == NULL)
9628             return build_int_cst (TREE_TYPE (s1), 0);
9629
9630           /* Return an offset into the constant string argument.  */
9631           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9632                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9633           return fold_convert (type, tem);
9634         }
9635
9636       /* The argument is const char *, and the result is char *, so we need
9637          a type conversion here to avoid a warning.  */
9638       if (p2[0] == '\0')
9639         return fold_convert (type, s1);
9640
9641       if (p2[1] != '\0')
9642         return 0;
9643
9644       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9645       if (!fn)
9646         return 0;
9647
9648       /* New argument list transforming strstr(s1, s2) to
9649          strchr(s1, s2[0]).  */
9650       arglist = build_tree_list (NULL_TREE,
9651                                  build_int_cst (NULL_TREE, p2[0]));
9652       arglist = tree_cons (NULL_TREE, s1, arglist);
9653       return build_function_call_expr (fn, arglist);
9654     }
9655 }
9656
9657 /* Simplify a call to the strchr builtin.
9658
9659    Return 0 if no simplification was possible, otherwise return the
9660    simplified form of the call as a tree.
9661
9662    The simplified form may be a constant or other expression which
9663    computes the same value, but in a more efficient manner (including
9664    calls to other builtin functions).
9665
9666    The call may contain arguments which need to be evaluated, but
9667    which are not useful to determine the result of the call.  In
9668    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9669    COMPOUND_EXPR will be an argument which must be evaluated.
9670    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9671    COMPOUND_EXPR in the chain will contain the tree for the simplified
9672    form of the builtin function call.  */
9673
9674 static tree
9675 fold_builtin_strchr (tree arglist, tree type)
9676 {
9677   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9678     return 0;
9679   else
9680     {
9681       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9682       const char *p1;
9683
9684       if (TREE_CODE (s2) != INTEGER_CST)
9685         return 0;
9686
9687       p1 = c_getstr (s1);
9688       if (p1 != NULL)
9689         {
9690           char c;
9691           const char *r;
9692           tree tem;
9693
9694           if (target_char_cast (s2, &c))
9695             return 0;
9696
9697           r = strchr (p1, c);
9698
9699           if (r == NULL)
9700             return build_int_cst (TREE_TYPE (s1), 0);
9701
9702           /* Return an offset into the constant string argument.  */
9703           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9704                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9705           return fold_convert (type, tem);
9706         }
9707       return 0;
9708     }
9709 }
9710
9711 /* Simplify a call to the strrchr builtin.
9712
9713    Return 0 if no simplification was possible, otherwise return the
9714    simplified form of the call as a tree.
9715
9716    The simplified form may be a constant or other expression which
9717    computes the same value, but in a more efficient manner (including
9718    calls to other builtin functions).
9719
9720    The call may contain arguments which need to be evaluated, but
9721    which are not useful to determine the result of the call.  In
9722    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9723    COMPOUND_EXPR will be an argument which must be evaluated.
9724    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9725    COMPOUND_EXPR in the chain will contain the tree for the simplified
9726    form of the builtin function call.  */
9727
9728 static tree
9729 fold_builtin_strrchr (tree arglist, tree type)
9730 {
9731   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9732     return 0;
9733   else
9734     {
9735       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9736       tree fn;
9737       const char *p1;
9738
9739       if (TREE_CODE (s2) != INTEGER_CST)
9740         return 0;
9741
9742       p1 = c_getstr (s1);
9743       if (p1 != NULL)
9744         {
9745           char c;
9746           const char *r;
9747           tree tem;
9748
9749           if (target_char_cast (s2, &c))
9750             return 0;
9751
9752           r = strrchr (p1, c);
9753
9754           if (r == NULL)
9755             return build_int_cst (TREE_TYPE (s1), 0);
9756
9757           /* Return an offset into the constant string argument.  */
9758           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9759                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9760           return fold_convert (type, tem);
9761         }
9762
9763       if (! integer_zerop (s2))
9764         return 0;
9765
9766       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9767       if (!fn)
9768         return 0;
9769
9770       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9771       return build_function_call_expr (fn, arglist);
9772     }
9773 }
9774
9775 /* Simplify a call to the strpbrk builtin.
9776
9777    Return 0 if no simplification was possible, otherwise return the
9778    simplified form of the call as a tree.
9779
9780    The simplified form may be a constant or other expression which
9781    computes the same value, but in a more efficient manner (including
9782    calls to other builtin functions).
9783
9784    The call may contain arguments which need to be evaluated, but
9785    which are not useful to determine the result of the call.  In
9786    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9787    COMPOUND_EXPR will be an argument which must be evaluated.
9788    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9789    COMPOUND_EXPR in the chain will contain the tree for the simplified
9790    form of the builtin function call.  */
9791
9792 static tree
9793 fold_builtin_strpbrk (tree arglist, tree type)
9794 {
9795   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9796     return 0;
9797   else
9798     {
9799       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9800       tree fn;
9801       const char *p1, *p2;
9802
9803       p2 = c_getstr (s2);
9804       if (p2 == NULL)
9805         return 0;
9806
9807       p1 = c_getstr (s1);
9808       if (p1 != NULL)
9809         {
9810           const char *r = strpbrk (p1, p2);
9811           tree tem;
9812
9813           if (r == NULL)
9814             return build_int_cst (TREE_TYPE (s1), 0);
9815
9816           /* Return an offset into the constant string argument.  */
9817           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9818                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9819           return fold_convert (type, tem);
9820         }
9821
9822       if (p2[0] == '\0')
9823         /* strpbrk(x, "") == NULL.
9824            Evaluate and ignore s1 in case it had side-effects.  */
9825         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9826
9827       if (p2[1] != '\0')
9828         return 0;  /* Really call strpbrk.  */
9829
9830       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9831       if (!fn)
9832         return 0;
9833
9834       /* New argument list transforming strpbrk(s1, s2) to
9835          strchr(s1, s2[0]).  */
9836       arglist = build_tree_list (NULL_TREE,
9837                                  build_int_cst (NULL_TREE, p2[0]));
9838       arglist = tree_cons (NULL_TREE, s1, arglist);
9839       return build_function_call_expr (fn, arglist);
9840     }
9841 }
9842
9843 /* Simplify a call to the strcat builtin.
9844
9845    Return 0 if no simplification was possible, otherwise return the
9846    simplified form of the call as a tree.
9847
9848    The simplified form may be a constant or other expression which
9849    computes the same value, but in a more efficient manner (including
9850    calls to other builtin functions).
9851
9852    The call may contain arguments which need to be evaluated, but
9853    which are not useful to determine the result of the call.  In
9854    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9855    COMPOUND_EXPR will be an argument which must be evaluated.
9856    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9857    COMPOUND_EXPR in the chain will contain the tree for the simplified
9858    form of the builtin function call.  */
9859
9860 static tree
9861 fold_builtin_strcat (tree arglist)
9862 {
9863   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9864     return 0;
9865   else
9866     {
9867       tree dst = TREE_VALUE (arglist),
9868         src = TREE_VALUE (TREE_CHAIN (arglist));
9869       const char *p = c_getstr (src);
9870
9871       /* If the string length is zero, return the dst parameter.  */
9872       if (p && *p == '\0')
9873         return dst;
9874
9875       return 0;
9876     }
9877 }
9878
9879 /* Simplify a call to the strncat builtin.
9880
9881    Return 0 if no simplification was possible, otherwise return the
9882    simplified form of the call as a tree.
9883
9884    The simplified form may be a constant or other expression which
9885    computes the same value, but in a more efficient manner (including
9886    calls to other builtin functions).
9887
9888    The call may contain arguments which need to be evaluated, but
9889    which are not useful to determine the result of the call.  In
9890    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9891    COMPOUND_EXPR will be an argument which must be evaluated.
9892    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9893    COMPOUND_EXPR in the chain will contain the tree for the simplified
9894    form of the builtin function call.  */
9895
9896 static tree
9897 fold_builtin_strncat (tree arglist)
9898 {
9899   if (!validate_arglist (arglist,
9900                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9901     return 0;
9902   else
9903     {
9904       tree dst = TREE_VALUE (arglist);
9905       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9906       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9907       const char *p = c_getstr (src);
9908
9909       /* If the requested length is zero, or the src parameter string
9910          length is zero, return the dst parameter.  */
9911       if (integer_zerop (len) || (p && *p == '\0'))
9912         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9913
9914       /* If the requested len is greater than or equal to the string
9915          length, call strcat.  */
9916       if (TREE_CODE (len) == INTEGER_CST && p
9917           && compare_tree_int (len, strlen (p)) >= 0)
9918         {
9919           tree newarglist
9920             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9921           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9922
9923           /* If the replacement _DECL isn't initialized, don't do the
9924              transformation.  */
9925           if (!fn)
9926             return 0;
9927
9928           return build_function_call_expr (fn, newarglist);
9929         }
9930       return 0;
9931     }
9932 }
9933
9934 /* Simplify a call to the strspn builtin.
9935
9936    Return 0 if no simplification was possible, otherwise return the
9937    simplified form of the call as a tree.
9938
9939    The simplified form may be a constant or other expression which
9940    computes the same value, but in a more efficient manner (including
9941    calls to other builtin functions).
9942
9943    The call may contain arguments which need to be evaluated, but
9944    which are not useful to determine the result of the call.  In
9945    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9946    COMPOUND_EXPR will be an argument which must be evaluated.
9947    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9948    COMPOUND_EXPR in the chain will contain the tree for the simplified
9949    form of the builtin function call.  */
9950
9951 static tree
9952 fold_builtin_strspn (tree arglist)
9953 {
9954   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9955     return 0;
9956   else
9957     {
9958       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9959       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9960
9961       /* If both arguments are constants, evaluate at compile-time.  */
9962       if (p1 && p2)
9963         {
9964           const size_t r = strspn (p1, p2);
9965           return size_int (r);
9966         }
9967
9968       /* If either argument is "", return 0.  */
9969       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9970         /* Evaluate and ignore both arguments in case either one has
9971            side-effects.  */
9972         return omit_two_operands (integer_type_node, integer_zero_node,
9973                                   s1, s2);
9974       return 0;
9975     }
9976 }
9977
9978 /* Simplify a call to the strcspn builtin.
9979
9980    Return 0 if no simplification was possible, otherwise return the
9981    simplified form of the call as a tree.
9982
9983    The simplified form may be a constant or other expression which
9984    computes the same value, but in a more efficient manner (including
9985    calls to other builtin functions).
9986
9987    The call may contain arguments which need to be evaluated, but
9988    which are not useful to determine the result of the call.  In
9989    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9990    COMPOUND_EXPR will be an argument which must be evaluated.
9991    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9992    COMPOUND_EXPR in the chain will contain the tree for the simplified
9993    form of the builtin function call.  */
9994
9995 static tree
9996 fold_builtin_strcspn (tree arglist)
9997 {
9998   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9999     return 0;
10000   else
10001     {
10002       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
10003       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
10004
10005       /* If both arguments are constants, evaluate at compile-time.  */
10006       if (p1 && p2)
10007         {
10008           const size_t r = strcspn (p1, p2);
10009           return size_int (r);
10010         }
10011
10012       /* If the first argument is "", return 0.  */
10013       if (p1 && *p1 == '\0')
10014         {
10015           /* Evaluate and ignore argument s2 in case it has
10016              side-effects.  */
10017           return omit_one_operand (integer_type_node,
10018                                    integer_zero_node, s2);
10019         }
10020
10021       /* If the second argument is "", return __builtin_strlen(s1).  */
10022       if (p2 && *p2 == '\0')
10023         {
10024           tree newarglist = build_tree_list (NULL_TREE, s1),
10025             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
10026
10027           /* If the replacement _DECL isn't initialized, don't do the
10028              transformation.  */
10029           if (!fn)
10030             return 0;
10031
10032           return build_function_call_expr (fn, newarglist);
10033         }
10034       return 0;
10035     }
10036 }
10037
10038 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
10039    by the builtin will be ignored.  UNLOCKED is true is true if this
10040    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
10041    the known length of the string.  Return NULL_TREE if no simplification
10042    was possible.  */
10043
10044 tree
10045 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
10046 {
10047   tree fn;
10048   /* If we're using an unlocked function, assume the other unlocked
10049      functions exist explicitly.  */
10050   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
10051     : implicit_built_in_decls[BUILT_IN_FPUTC];
10052   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
10053     : implicit_built_in_decls[BUILT_IN_FWRITE];
10054
10055   /* If the return value is used, don't do the transformation.  */
10056   if (!ignore)
10057     return 0;
10058
10059   /* Verify the arguments in the original call.  */
10060   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
10061     return 0;
10062
10063   if (! len)
10064     len = c_strlen (TREE_VALUE (arglist), 0);
10065
10066   /* Get the length of the string passed to fputs.  If the length
10067      can't be determined, punt.  */
10068   if (!len
10069       || TREE_CODE (len) != INTEGER_CST)
10070     return 0;
10071
10072   switch (compare_tree_int (len, 1))
10073     {
10074     case -1: /* length is 0, delete the call entirely .  */
10075       return omit_one_operand (integer_type_node, integer_zero_node,
10076                                TREE_VALUE (TREE_CHAIN (arglist)));
10077
10078     case 0: /* length is 1, call fputc.  */
10079       {
10080         const char *p = c_getstr (TREE_VALUE (arglist));
10081
10082         if (p != NULL)
10083           {
10084             /* New argument list transforming fputs(string, stream) to
10085                fputc(string[0], stream).  */
10086             arglist = build_tree_list (NULL_TREE,
10087                                        TREE_VALUE (TREE_CHAIN (arglist)));
10088             arglist = tree_cons (NULL_TREE,
10089                                  build_int_cst (NULL_TREE, p[0]),
10090                                  arglist);
10091             fn = fn_fputc;
10092             break;
10093           }
10094       }
10095       /* FALLTHROUGH */
10096     case 1: /* length is greater than 1, call fwrite.  */
10097       {
10098         tree string_arg;
10099
10100         /* If optimizing for size keep fputs.  */
10101         if (optimize_size)
10102           return 0;
10103         string_arg = TREE_VALUE (arglist);
10104         /* New argument list transforming fputs(string, stream) to
10105            fwrite(string, 1, len, stream).  */
10106         arglist = build_tree_list (NULL_TREE,
10107                                    TREE_VALUE (TREE_CHAIN (arglist)));
10108         arglist = tree_cons (NULL_TREE, len, arglist);
10109         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
10110         arglist = tree_cons (NULL_TREE, string_arg, arglist);
10111         fn = fn_fwrite;
10112         break;
10113       }
10114     default:
10115       gcc_unreachable ();
10116     }
10117
10118   /* If the replacement _DECL isn't initialized, don't do the
10119      transformation.  */
10120   if (!fn)
10121     return 0;
10122
10123   /* These optimizations are only performed when the result is ignored,
10124      hence there's no need to cast the result to integer_type_node.  */
10125   return build_function_call_expr (fn, arglist);
10126 }
10127
10128 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
10129    produced.  False otherwise.  This is done so that we don't output the error
10130    or warning twice or three times.  */
10131 bool
10132 fold_builtin_next_arg (tree arglist)
10133 {
10134   tree fntype = TREE_TYPE (current_function_decl);
10135
10136   if (TYPE_ARG_TYPES (fntype) == 0
10137       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
10138           == void_type_node))
10139     {
10140       error ("%<va_start%> used in function with fixed args");
10141       return true;
10142     }
10143   else if (!arglist)
10144     {
10145       /* Evidently an out of date version of <stdarg.h>; can't validate
10146          va_start's second argument, but can still work as intended.  */
10147       warning (0, "%<__builtin_next_arg%> called without an argument");
10148       return true;
10149     }
10150   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
10151      when we checked the arguments and if needed issued a warning.  */
10152   else if (!TREE_CHAIN (arglist)
10153            || !integer_zerop (TREE_VALUE (arglist))
10154            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
10155            || TREE_CHAIN (TREE_CHAIN (arglist)))
10156     {
10157       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
10158       tree arg = TREE_VALUE (arglist);
10159
10160       if (TREE_CHAIN (arglist))
10161         {
10162           error ("%<va_start%> used with too many arguments");
10163           return true;
10164         }
10165
10166       /* Strip off all nops for the sake of the comparison.  This
10167          is not quite the same as STRIP_NOPS.  It does more.
10168          We must also strip off INDIRECT_EXPR for C++ reference
10169          parameters.  */
10170       while (TREE_CODE (arg) == NOP_EXPR
10171              || TREE_CODE (arg) == CONVERT_EXPR
10172              || TREE_CODE (arg) == NON_LVALUE_EXPR
10173              || TREE_CODE (arg) == INDIRECT_REF)
10174         arg = TREE_OPERAND (arg, 0);
10175       if (arg != last_parm)
10176         {
10177           /* FIXME: Sometimes with the tree optimizers we can get the
10178              not the last argument even though the user used the last
10179              argument.  We just warn and set the arg to be the last
10180              argument so that we will get wrong-code because of
10181              it.  */
10182           warning (0, "second parameter of %<va_start%> not last named argument");
10183         }
10184       /* We want to verify the second parameter just once before the tree
10185          optimizers are run and then avoid keeping it in the tree,
10186          as otherwise we could warn even for correct code like:
10187          void foo (int i, ...)
10188          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
10189       TREE_VALUE (arglist) = integer_zero_node;
10190       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
10191     }
10192   return false;
10193 }
10194
10195
10196 /* Simplify a call to the sprintf builtin.
10197
10198    Return 0 if no simplification was possible, otherwise return the
10199    simplified form of the call as a tree.  If IGNORED is true, it means that
10200    the caller does not use the returned value of the function.  */
10201
10202 static tree
10203 fold_builtin_sprintf (tree arglist, int ignored)
10204 {
10205   tree call, retval, dest, fmt;
10206   const char *fmt_str = NULL;
10207
10208   /* Verify the required arguments in the original call.  We deal with two
10209      types of sprintf() calls: 'sprintf (str, fmt)' and
10210      'sprintf (dest, "%s", orig)'.  */
10211   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
10212       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
10213                             VOID_TYPE))
10214     return NULL_TREE;
10215
10216   /* Get the destination string and the format specifier.  */
10217   dest = TREE_VALUE (arglist);
10218   fmt = TREE_VALUE (TREE_CHAIN (arglist));
10219
10220   /* Check whether the format is a literal string constant.  */
10221   fmt_str = c_getstr (fmt);
10222   if (fmt_str == NULL)
10223     return NULL_TREE;
10224
10225   call = NULL_TREE;
10226   retval = NULL_TREE;
10227
10228   if (!init_target_chars())
10229     return 0;
10230
10231   /* If the format doesn't contain % args or %%, use strcpy.  */
10232   if (strchr (fmt_str, target_percent) == NULL)
10233     {
10234       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10235
10236       if (!fn)
10237         return NULL_TREE;
10238
10239       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
10240          'format' is known to contain no % formats.  */
10241       arglist = build_tree_list (NULL_TREE, fmt);
10242       arglist = tree_cons (NULL_TREE, dest, arglist);
10243       call = build_function_call_expr (fn, arglist);
10244       if (!ignored)
10245         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
10246     }
10247
10248   /* If the format is "%s", use strcpy if the result isn't used.  */
10249   else if (fmt_str && strcmp (fmt_str, target_percent_s) == 0)
10250     {
10251       tree fn, orig;
10252       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
10253
10254       if (!fn)
10255         return NULL_TREE;
10256
10257       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
10258       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10259       arglist = build_tree_list (NULL_TREE, orig);
10260       arglist = tree_cons (NULL_TREE, dest, arglist);
10261       if (!ignored)
10262         {
10263           retval = c_strlen (orig, 1);
10264           if (!retval || TREE_CODE (retval) != INTEGER_CST)
10265             return NULL_TREE;
10266         }
10267       call = build_function_call_expr (fn, arglist);
10268     }
10269
10270   if (call && retval)
10271     {
10272       retval = fold_convert
10273         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
10274          retval);
10275       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
10276     }
10277   else
10278     return call;
10279 }
10280
10281 /* Expand a call to __builtin_object_size.  */
10282
10283 rtx
10284 expand_builtin_object_size (tree exp)
10285 {
10286   tree ost;
10287   int object_size_type;
10288   tree fndecl = get_callee_fndecl (exp);
10289   tree arglist = TREE_OPERAND (exp, 1);
10290   location_t locus = EXPR_LOCATION (exp);
10291
10292   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10293     {
10294       error ("%Hfirst argument of %D must be a pointer, second integer constant",
10295              &locus, fndecl);
10296       expand_builtin_trap ();
10297       return const0_rtx;
10298     }
10299
10300   ost = TREE_VALUE (TREE_CHAIN (arglist));
10301   STRIP_NOPS (ost);
10302
10303   if (TREE_CODE (ost) != INTEGER_CST
10304       || tree_int_cst_sgn (ost) < 0
10305       || compare_tree_int (ost, 3) > 0)
10306     {
10307       error ("%Hlast argument of %D is not integer constant between 0 and 3",
10308              &locus, fndecl);
10309       expand_builtin_trap ();
10310       return const0_rtx;
10311     }
10312
10313   object_size_type = tree_low_cst (ost, 0);
10314
10315   return object_size_type < 2 ? constm1_rtx : const0_rtx;
10316 }
10317
10318 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10319    FCODE is the BUILT_IN_* to use.
10320    Return 0 if we failed; the caller should emit a normal call,
10321    otherwise try to get the result in TARGET, if convenient (and in
10322    mode MODE if that's convenient).  */
10323
10324 static rtx
10325 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
10326                            enum built_in_function fcode)
10327 {
10328   tree arglist = TREE_OPERAND (exp, 1);
10329   tree dest, src, len, size;
10330
10331   if (!validate_arglist (arglist,
10332                          POINTER_TYPE,
10333                          fcode == BUILT_IN_MEMSET_CHK
10334                          ? INTEGER_TYPE : POINTER_TYPE,
10335                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10336     return 0;
10337
10338   dest = TREE_VALUE (arglist);
10339   src = TREE_VALUE (TREE_CHAIN (arglist));
10340   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10341   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10342
10343   if (! host_integerp (size, 1))
10344     return 0;
10345
10346   if (host_integerp (len, 1) || integer_all_onesp (size))
10347     {
10348       tree fn;
10349
10350       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
10351         {
10352           location_t locus = EXPR_LOCATION (exp);
10353           warning (0, "%Hcall to %D will always overflow destination buffer",
10354                    &locus, get_callee_fndecl (exp));
10355           return 0;
10356         }
10357
10358       arglist = build_tree_list (NULL_TREE, len);
10359       arglist = tree_cons (NULL_TREE, src, arglist);
10360       arglist = tree_cons (NULL_TREE, dest, arglist);
10361
10362       fn = NULL_TREE;
10363       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10364          mem{cpy,pcpy,move,set} is available.  */
10365       switch (fcode)
10366         {
10367         case BUILT_IN_MEMCPY_CHK:
10368           fn = built_in_decls[BUILT_IN_MEMCPY];
10369           break;
10370         case BUILT_IN_MEMPCPY_CHK:
10371           fn = built_in_decls[BUILT_IN_MEMPCPY];
10372           break;
10373         case BUILT_IN_MEMMOVE_CHK:
10374           fn = built_in_decls[BUILT_IN_MEMMOVE];
10375           break;
10376         case BUILT_IN_MEMSET_CHK:
10377           fn = built_in_decls[BUILT_IN_MEMSET];
10378           break;
10379         default:
10380           break;
10381         }
10382
10383       if (! fn)
10384         return 0;
10385
10386       fn = build_function_call_expr (fn, arglist);
10387       if (TREE_CODE (fn) == CALL_EXPR)
10388         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10389       return expand_expr (fn, target, mode, EXPAND_NORMAL);
10390     }
10391   else if (fcode == BUILT_IN_MEMSET_CHK)
10392     return 0;
10393   else
10394     {
10395       unsigned int dest_align
10396         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
10397
10398       /* If DEST is not a pointer type, call the normal function.  */
10399       if (dest_align == 0)
10400         return 0;
10401
10402       /* If SRC and DEST are the same (and not volatile), do nothing.  */
10403       if (operand_equal_p (src, dest, 0))
10404         {
10405           tree expr;
10406
10407           if (fcode != BUILT_IN_MEMPCPY_CHK)
10408             {
10409               /* Evaluate and ignore LEN in case it has side-effects.  */
10410               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
10411               return expand_expr (dest, target, mode, EXPAND_NORMAL);
10412             }
10413
10414           len = fold_convert (TREE_TYPE (dest), len);
10415           expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
10416           return expand_expr (expr, target, mode, EXPAND_NORMAL);
10417         }
10418
10419       /* __memmove_chk special case.  */
10420       if (fcode == BUILT_IN_MEMMOVE_CHK)
10421         {
10422           unsigned int src_align
10423             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
10424
10425           if (src_align == 0)
10426             return 0;
10427
10428           /* If src is categorized for a readonly section we can use
10429              normal __memcpy_chk.  */
10430           if (readonly_data_expr (src))
10431             {
10432               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10433               if (!fn)
10434                 return 0;
10435               fn = build_function_call_expr (fn, arglist);
10436               if (TREE_CODE (fn) == CALL_EXPR)
10437                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10438               return expand_expr (fn, target, mode, EXPAND_NORMAL);
10439             }
10440         }
10441       return 0;
10442     }
10443 }
10444
10445 /* Emit warning if a buffer overflow is detected at compile time.  */
10446
10447 static void
10448 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10449 {
10450   int arg_mask, is_strlen = 0;
10451   tree arglist = TREE_OPERAND (exp, 1), a;
10452   tree len, size;
10453   location_t locus;
10454
10455   switch (fcode)
10456     {
10457     case BUILT_IN_STRCPY_CHK:
10458     case BUILT_IN_STPCPY_CHK:
10459     /* For __strcat_chk the warning will be emitted only if overflowing
10460        by at least strlen (dest) + 1 bytes.  */
10461     case BUILT_IN_STRCAT_CHK:
10462       arg_mask = 6;
10463       is_strlen = 1;
10464       break;
10465     case BUILT_IN_STRNCAT_CHK:
10466     /* For __strncat_chk the warning will be emitted only if overflowing
10467        by at least strlen (dest) + 1 bytes.  */
10468       arg_mask = 12;
10469       break;
10470     case BUILT_IN_STRNCPY_CHK:
10471       arg_mask = 12;
10472       break;
10473     case BUILT_IN_SNPRINTF_CHK:
10474     case BUILT_IN_VSNPRINTF_CHK:
10475       arg_mask = 10;
10476       break;
10477     default:
10478       gcc_unreachable ();
10479     }
10480
10481   len = NULL_TREE;
10482   size = NULL_TREE;
10483   for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10484     if (arg_mask & 1)
10485       {
10486         if (len)
10487           size = a;
10488         else
10489           len = a;
10490       }
10491
10492   if (!len || !size)
10493     return;
10494
10495   len = TREE_VALUE (len);
10496   size = TREE_VALUE (size);
10497
10498   if (! host_integerp (size, 1) || integer_all_onesp (size))
10499     return;
10500
10501   if (is_strlen)
10502     {
10503       len = c_strlen (len, 1);
10504       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10505         return;
10506     }
10507   else if (fcode == BUILT_IN_STRNCAT_CHK)
10508     {
10509       tree src = TREE_VALUE (TREE_CHAIN (arglist));
10510       if (! src || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10511         return;
10512       src = c_strlen (src, 1);
10513       if (! src || ! host_integerp (src, 1))
10514         {
10515           locus = EXPR_LOCATION (exp);
10516           warning (0, "%Hcall to %D might overflow destination buffer",
10517                    &locus, get_callee_fndecl (exp));
10518           return;
10519         }
10520       else if (tree_int_cst_lt (src, size))
10521         return;
10522     }
10523   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10524     return;
10525
10526   locus = EXPR_LOCATION (exp);
10527   warning (0, "%Hcall to %D will always overflow destination buffer",
10528            &locus, get_callee_fndecl (exp));
10529 }
10530
10531 /* Emit warning if a buffer overflow is detected at compile time
10532    in __sprintf_chk/__vsprintf_chk calls.  */
10533
10534 static void
10535 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10536 {
10537   tree arglist = TREE_OPERAND (exp, 1);
10538   tree dest, size, len, fmt, flag;
10539   const char *fmt_str;
10540
10541   /* Verify the required arguments in the original call.  */
10542   if (! arglist)
10543     return;
10544   dest = TREE_VALUE (arglist);
10545   arglist = TREE_CHAIN (arglist);
10546   if (! arglist)
10547     return;
10548   flag = TREE_VALUE (arglist);
10549   arglist = TREE_CHAIN (arglist);
10550   if (! arglist)
10551     return;
10552   size = TREE_VALUE (arglist);
10553   arglist = TREE_CHAIN (arglist);
10554   if (! arglist)
10555     return;
10556   fmt = TREE_VALUE (arglist);
10557   arglist = TREE_CHAIN (arglist);
10558
10559   if (! host_integerp (size, 1) || integer_all_onesp (size))
10560     return;
10561
10562   /* Check whether the format is a literal string constant.  */
10563   fmt_str = c_getstr (fmt);
10564   if (fmt_str == NULL)
10565     return;
10566
10567   if (!init_target_chars())
10568     return;
10569
10570   /* If the format doesn't contain % args or %%, we know its size.  */
10571   if (strchr (fmt_str, target_percent) == 0)
10572     len = build_int_cstu (size_type_node, strlen (fmt_str));
10573   /* If the format is "%s" and first ... argument is a string literal,
10574      we know it too.  */
10575   else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
10576     {
10577       tree arg;
10578
10579       if (! arglist)
10580         return;
10581       arg = TREE_VALUE (arglist);
10582       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10583         return;
10584
10585       len = c_strlen (arg, 1);
10586       if (!len || ! host_integerp (len, 1))
10587         return;
10588     }
10589   else
10590     return;
10591
10592   if (! tree_int_cst_lt (len, size))
10593     {
10594       location_t locus = EXPR_LOCATION (exp);
10595       warning (0, "%Hcall to %D will always overflow destination buffer",
10596                &locus, get_callee_fndecl (exp));
10597     }
10598 }
10599
10600 /* Fold a call to __builtin_object_size, if possible.  */
10601
10602 tree
10603 fold_builtin_object_size (tree arglist)
10604 {
10605   tree ptr, ost, ret = 0;
10606   int object_size_type;
10607
10608   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10609     return 0;
10610
10611   ptr = TREE_VALUE (arglist);
10612   ost = TREE_VALUE (TREE_CHAIN (arglist));
10613   STRIP_NOPS (ost);
10614
10615   if (TREE_CODE (ost) != INTEGER_CST
10616       || tree_int_cst_sgn (ost) < 0
10617       || compare_tree_int (ost, 3) > 0)
10618     return 0;
10619
10620   object_size_type = tree_low_cst (ost, 0);
10621
10622   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10623      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10624      and (size_t) 0 for types 2 and 3.  */
10625   if (TREE_SIDE_EFFECTS (ptr))
10626     return fold_convert (size_type_node,
10627                          object_size_type < 2
10628                          ? integer_minus_one_node : integer_zero_node);
10629
10630   if (TREE_CODE (ptr) == ADDR_EXPR)
10631     ret = build_int_cstu (size_type_node,
10632                         compute_builtin_object_size (ptr, object_size_type));
10633
10634   else if (TREE_CODE (ptr) == SSA_NAME)
10635     {
10636       unsigned HOST_WIDE_INT bytes;
10637
10638       /* If object size is not known yet, delay folding until
10639        later.  Maybe subsequent passes will help determining
10640        it.  */
10641       bytes = compute_builtin_object_size (ptr, object_size_type);
10642       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10643                                              ? -1 : 0))
10644         ret = build_int_cstu (size_type_node, bytes);
10645     }
10646
10647   if (ret)
10648     {
10649       ret = force_fit_type (ret, -1, false, false);
10650       if (TREE_CONSTANT_OVERFLOW (ret))
10651         ret = 0;
10652     }
10653
10654   return ret;
10655 }
10656
10657 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10658    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10659    code of the builtin.  If MAXLEN is not NULL, it is maximum length
10660    passed as third argument.  */
10661
10662 tree
10663 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10664                          enum built_in_function fcode)
10665 {
10666   tree dest, src, len, size, fn;
10667
10668   if (!validate_arglist (arglist,
10669                          POINTER_TYPE,
10670                          fcode == BUILT_IN_MEMSET_CHK
10671                          ? INTEGER_TYPE : POINTER_TYPE,
10672                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10673     return 0;
10674
10675   dest = TREE_VALUE (arglist);
10676   /* Actually val for __memset_chk, but it doesn't matter.  */
10677   src = TREE_VALUE (TREE_CHAIN (arglist));
10678   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10679   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10680
10681   /* If SRC and DEST are the same (and not volatile), return DEST
10682      (resp. DEST+LEN for __mempcpy_chk).  */
10683   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10684     {
10685       if (fcode != BUILT_IN_MEMPCPY_CHK)
10686         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10687       else
10688         {
10689           tree temp = fold_convert (TREE_TYPE (dest), len);
10690           temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10691           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10692         }
10693     }
10694
10695   if (! host_integerp (size, 1))
10696     return 0;
10697
10698   if (! integer_all_onesp (size))
10699     {
10700       if (! host_integerp (len, 1))
10701         {
10702           /* If LEN is not constant, try MAXLEN too.
10703              For MAXLEN only allow optimizing into non-_ocs function
10704              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10705           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10706             {
10707               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10708                 {
10709                   /* (void) __mempcpy_chk () can be optimized into
10710                      (void) __memcpy_chk ().  */
10711                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10712                   if (!fn)
10713                     return 0;
10714
10715                   return build_function_call_expr (fn, arglist);
10716                 }
10717               return 0;
10718             }
10719         }
10720       else
10721         maxlen = len;
10722
10723       if (tree_int_cst_lt (size, maxlen))
10724         return 0;
10725     }
10726
10727   arglist = build_tree_list (NULL_TREE, len);
10728   arglist = tree_cons (NULL_TREE, src, arglist);
10729   arglist = tree_cons (NULL_TREE, dest, arglist);
10730
10731   fn = NULL_TREE;
10732   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10733      mem{cpy,pcpy,move,set} is available.  */
10734   switch (fcode)
10735     {
10736     case BUILT_IN_MEMCPY_CHK:
10737       fn = built_in_decls[BUILT_IN_MEMCPY];
10738       break;
10739     case BUILT_IN_MEMPCPY_CHK:
10740       fn = built_in_decls[BUILT_IN_MEMPCPY];
10741       break;
10742     case BUILT_IN_MEMMOVE_CHK:
10743       fn = built_in_decls[BUILT_IN_MEMMOVE];
10744       break;
10745     case BUILT_IN_MEMSET_CHK:
10746       fn = built_in_decls[BUILT_IN_MEMSET];
10747       break;
10748     default:
10749       break;
10750     }
10751
10752   if (!fn)
10753     return 0;
10754
10755   return build_function_call_expr (fn, arglist);
10756 }
10757
10758 /* Fold a call to the __st[rp]cpy_chk builtin.
10759    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10760    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10761    strings passed as second argument.  */
10762
10763 tree
10764 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10765                          enum built_in_function fcode)
10766 {
10767   tree dest, src, size, len, fn;
10768
10769   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10770                          VOID_TYPE))
10771     return 0;
10772
10773   dest = TREE_VALUE (arglist);
10774   src = TREE_VALUE (TREE_CHAIN (arglist));
10775   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10776
10777   /* If SRC and DEST are the same (and not volatile), return DEST.  */
10778   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10779     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10780
10781   if (! host_integerp (size, 1))
10782     return 0;
10783
10784   if (! integer_all_onesp (size))
10785     {
10786       len = c_strlen (src, 1);
10787       if (! len || ! host_integerp (len, 1))
10788         {
10789           /* If LEN is not constant, try MAXLEN too.
10790              For MAXLEN only allow optimizing into non-_ocs function
10791              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10792           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10793             {
10794               if (fcode == BUILT_IN_STPCPY_CHK)
10795                 {
10796                   if (! ignore)
10797                     return 0;
10798
10799                   /* If return value of __stpcpy_chk is ignored,
10800                      optimize into __strcpy_chk.  */
10801                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10802                   if (!fn)
10803                     return 0;
10804
10805                   return build_function_call_expr (fn, arglist);
10806                 }
10807
10808               if (! len || TREE_SIDE_EFFECTS (len))
10809                 return 0;
10810
10811               /* If c_strlen returned something, but not a constant,
10812                  transform __strcpy_chk into __memcpy_chk.  */
10813               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10814               if (!fn)
10815                 return 0;
10816
10817               len = size_binop (PLUS_EXPR, len, ssize_int (1));
10818               arglist = build_tree_list (NULL_TREE, size);
10819               arglist = tree_cons (NULL_TREE, len, arglist);
10820               arglist = tree_cons (NULL_TREE, src, arglist);
10821               arglist = tree_cons (NULL_TREE, dest, arglist);
10822               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10823                                    build_function_call_expr (fn, arglist));
10824             }
10825         }
10826       else
10827         maxlen = len;
10828
10829       if (! tree_int_cst_lt (maxlen, size))
10830         return 0;
10831     }
10832
10833   arglist = build_tree_list (NULL_TREE, src);
10834   arglist = tree_cons (NULL_TREE, dest, arglist);
10835
10836   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10837   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10838                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10839   if (!fn)
10840     return 0;
10841
10842   return build_function_call_expr (fn, arglist);
10843 }
10844
10845 /* Fold a call to the __strncpy_chk builtin.
10846    If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10847
10848 tree
10849 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10850 {
10851   tree dest, src, size, len, fn;
10852
10853   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10854                          INTEGER_TYPE, VOID_TYPE))
10855     return 0;
10856
10857   dest = TREE_VALUE (arglist);
10858   src = TREE_VALUE (TREE_CHAIN (arglist));
10859   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10860   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10861
10862   if (! host_integerp (size, 1))
10863     return 0;
10864
10865   if (! integer_all_onesp (size))
10866     {
10867       if (! host_integerp (len, 1))
10868         {
10869           /* If LEN is not constant, try MAXLEN too.
10870              For MAXLEN only allow optimizing into non-_ocs function
10871              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10872           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10873             return 0;
10874         }
10875       else
10876         maxlen = len;
10877
10878       if (tree_int_cst_lt (size, maxlen))
10879         return 0;
10880     }
10881
10882   arglist = build_tree_list (NULL_TREE, len);
10883   arglist = tree_cons (NULL_TREE, src, arglist);
10884   arglist = tree_cons (NULL_TREE, dest, arglist);
10885
10886   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10887   fn = built_in_decls[BUILT_IN_STRNCPY];
10888   if (!fn)
10889     return 0;
10890
10891   return build_function_call_expr (fn, arglist);
10892 }
10893
10894 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10895
10896 static tree
10897 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10898 {
10899   tree dest, src, size, fn;
10900   const char *p;
10901
10902   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10903                          VOID_TYPE))
10904     return 0;
10905
10906   dest = TREE_VALUE (arglist);
10907   src = TREE_VALUE (TREE_CHAIN (arglist));
10908   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10909
10910   p = c_getstr (src);
10911   /* If the SRC parameter is "", return DEST.  */
10912   if (p && *p == '\0')
10913     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10914
10915   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10916     return 0;
10917
10918   arglist = build_tree_list (NULL_TREE, src);
10919   arglist = tree_cons (NULL_TREE, dest, arglist);
10920
10921   /* If __builtin_strcat_chk is used, assume strcat is available.  */
10922   fn = built_in_decls[BUILT_IN_STRCAT];
10923   if (!fn)
10924     return 0;
10925
10926   return build_function_call_expr (fn, arglist);
10927 }
10928
10929 /* Fold a call to the __strncat_chk builtin EXP.  */
10930
10931 static tree
10932 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10933 {
10934   tree dest, src, size, len, fn;
10935   const char *p;
10936
10937   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10938                          INTEGER_TYPE, VOID_TYPE))
10939     return 0;
10940
10941   dest = TREE_VALUE (arglist);
10942   src = TREE_VALUE (TREE_CHAIN (arglist));
10943   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10944   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10945
10946   p = c_getstr (src);
10947   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10948   if (p && *p == '\0')
10949     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10950   else if (integer_zerop (len))
10951     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10952
10953   if (! host_integerp (size, 1))
10954     return 0;
10955
10956   if (! integer_all_onesp (size))
10957     {
10958       tree src_len = c_strlen (src, 1);
10959       if (src_len
10960           && host_integerp (src_len, 1)
10961           && host_integerp (len, 1)
10962           && ! tree_int_cst_lt (len, src_len))
10963         {
10964           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10965           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10966           if (!fn)
10967             return 0;
10968
10969           arglist = build_tree_list (NULL_TREE, size);
10970           arglist = tree_cons (NULL_TREE, src, arglist);
10971           arglist = tree_cons (NULL_TREE, dest, arglist);
10972           return build_function_call_expr (fn, arglist);
10973         }
10974       return 0;
10975     }
10976
10977   arglist = build_tree_list (NULL_TREE, len);
10978   arglist = tree_cons (NULL_TREE, src, arglist);
10979   arglist = tree_cons (NULL_TREE, dest, arglist);
10980
10981   /* If __builtin_strncat_chk is used, assume strncat is available.  */
10982   fn = built_in_decls[BUILT_IN_STRNCAT];
10983   if (!fn)
10984     return 0;
10985
10986   return build_function_call_expr (fn, arglist);
10987 }
10988
10989 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10990    a normal call should be emitted rather than expanding the function
10991    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10992
10993 static tree
10994 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10995 {
10996   tree dest, size, len, fn, fmt, flag;
10997   const char *fmt_str;
10998
10999   /* Verify the required arguments in the original call.  */
11000   if (! arglist)
11001     return 0;
11002   dest = TREE_VALUE (arglist);
11003   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11004     return 0;
11005   arglist = TREE_CHAIN (arglist);
11006   if (! arglist)
11007     return 0;
11008   flag = TREE_VALUE (arglist);
11009   if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
11010     return 0;
11011   arglist = TREE_CHAIN (arglist);
11012   if (! arglist)
11013     return 0;
11014   size = TREE_VALUE (arglist);
11015   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11016     return 0;
11017   arglist = TREE_CHAIN (arglist);
11018   if (! arglist)
11019     return 0;
11020   fmt = TREE_VALUE (arglist);
11021   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11022     return 0;
11023   arglist = TREE_CHAIN (arglist);
11024
11025   if (! host_integerp (size, 1))
11026     return 0;
11027
11028   len = NULL_TREE;
11029
11030   if (!init_target_chars())
11031     return 0;
11032
11033   /* Check whether the format is a literal string constant.  */
11034   fmt_str = c_getstr (fmt);
11035   if (fmt_str != NULL)
11036     {
11037       /* If the format doesn't contain % args or %%, we know the size.  */
11038       if (strchr (fmt_str, target_percent) == 0)
11039         {
11040           if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
11041             len = build_int_cstu (size_type_node, strlen (fmt_str));
11042         }
11043       /* If the format is "%s" and first ... argument is a string literal,
11044          we know the size too.  */
11045       else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, target_percent_s) == 0)
11046         {
11047           tree arg;
11048
11049           if (arglist && !TREE_CHAIN (arglist))
11050             {
11051               arg = TREE_VALUE (arglist);
11052               if (POINTER_TYPE_P (TREE_TYPE (arg)))
11053                 {
11054                   len = c_strlen (arg, 1);
11055                   if (! len || ! host_integerp (len, 1))
11056                     len = NULL_TREE;
11057                 }
11058             }
11059         }
11060     }
11061
11062   if (! integer_all_onesp (size))
11063     {
11064       if (! len || ! tree_int_cst_lt (len, size))
11065         return 0;
11066     }
11067
11068   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
11069      or if format doesn't contain % chars or is "%s".  */
11070   if (! integer_zerop (flag))
11071     {
11072       if (fmt_str == NULL)
11073         return 0;
11074       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11075         return 0;
11076     }
11077
11078   arglist = tree_cons (NULL_TREE, fmt, arglist);
11079   arglist = tree_cons (NULL_TREE, dest, arglist);
11080
11081   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
11082   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
11083                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
11084   if (!fn)
11085     return 0;
11086
11087   return build_function_call_expr (fn, arglist);
11088 }
11089
11090 /* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
11091    a normal call should be emitted rather than expanding the function
11092    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
11093    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
11094    passed as second argument.  */
11095
11096 tree
11097 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
11098                            enum built_in_function fcode)
11099 {
11100   tree dest, size, len, fn, fmt, flag;
11101   const char *fmt_str;
11102
11103   /* Verify the required arguments in the original call.  */
11104   if (! arglist)
11105     return 0;
11106   dest = TREE_VALUE (arglist);
11107   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
11108     return 0;
11109   arglist = TREE_CHAIN (arglist);
11110   if (! arglist)
11111     return 0;
11112   len = TREE_VALUE (arglist);
11113   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11114     return 0;
11115   arglist = TREE_CHAIN (arglist);
11116   if (! arglist)
11117     return 0;
11118   flag = TREE_VALUE (arglist);
11119   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
11120     return 0;
11121   arglist = TREE_CHAIN (arglist);
11122   if (! arglist)
11123     return 0;
11124   size = TREE_VALUE (arglist);
11125   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
11126     return 0;
11127   arglist = TREE_CHAIN (arglist);
11128   if (! arglist)
11129     return 0;
11130   fmt = TREE_VALUE (arglist);
11131   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11132     return 0;
11133   arglist = TREE_CHAIN (arglist);
11134
11135   if (! host_integerp (size, 1))
11136     return 0;
11137
11138   if (! integer_all_onesp (size))
11139     {
11140       if (! host_integerp (len, 1))
11141         {
11142           /* If LEN is not constant, try MAXLEN too.
11143              For MAXLEN only allow optimizing into non-_ocs function
11144              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
11145           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
11146             return 0;
11147         }
11148       else
11149         maxlen = len;
11150
11151       if (tree_int_cst_lt (size, maxlen))
11152         return 0;
11153     }
11154
11155   if (!init_target_chars())
11156     return 0;
11157
11158   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
11159      or if format doesn't contain % chars or is "%s".  */
11160   if (! integer_zerop (flag))
11161     {
11162       fmt_str = c_getstr (fmt);
11163       if (fmt_str == NULL)
11164         return 0;
11165       if (strchr (fmt_str, target_percent) != NULL && strcmp (fmt_str, target_percent_s))
11166         return 0;
11167     }
11168
11169   arglist = tree_cons (NULL_TREE, fmt, arglist);
11170   arglist = tree_cons (NULL_TREE, len, arglist);
11171   arglist = tree_cons (NULL_TREE, dest, arglist);
11172
11173   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
11174      available.  */
11175   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
11176                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
11177   if (!fn)
11178     return 0;
11179
11180   return build_function_call_expr (fn, arglist);
11181 }
11182
11183 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
11184
11185    Return 0 if no simplification was possible, otherwise return the
11186    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11187    code of the function to be simplified.  */
11188
11189 static tree
11190 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
11191                      enum built_in_function fcode)
11192 {
11193   tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
11194   const char *fmt_str = NULL;
11195
11196   /* If the return value is used, don't do the transformation.  */
11197   if (! ignore)
11198     return 0;
11199
11200   /* Verify the required arguments in the original call.  */
11201   if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
11202     {
11203       tree flag;
11204
11205       if (! arglist)
11206         return 0;
11207       flag = TREE_VALUE (arglist);
11208       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11209           || TREE_SIDE_EFFECTS (flag))
11210         return 0;
11211       arglist = TREE_CHAIN (arglist);
11212     }
11213
11214   if (! arglist)
11215     return 0;
11216   fmt = TREE_VALUE (arglist);
11217   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11218     return 0;
11219   arglist = TREE_CHAIN (arglist);
11220
11221   /* Check whether the format is a literal string constant.  */
11222   fmt_str = c_getstr (fmt);
11223   if (fmt_str == NULL)
11224     return NULL_TREE;
11225
11226   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
11227     {
11228       /* If we're using an unlocked function, assume the other
11229          unlocked functions exist explicitly.  */
11230       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
11231       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
11232     }
11233   else
11234     {
11235       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
11236       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
11237     }
11238
11239   if (!init_target_chars())
11240     return 0;
11241
11242   if (strcmp (fmt_str, target_percent_s) == 0 || strchr (fmt_str, target_percent) == NULL)
11243     {
11244       const char *str;
11245
11246       if (strcmp (fmt_str, target_percent_s) == 0)
11247         {
11248           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11249             return 0;
11250
11251           if (! arglist
11252               || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11253               || TREE_CHAIN (arglist))
11254             return 0;
11255
11256           str = c_getstr (TREE_VALUE (arglist));
11257           if (str == NULL)
11258             return 0;
11259         }
11260       else
11261         {
11262           /* The format specifier doesn't contain any '%' characters.  */
11263           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
11264               && arglist)
11265             return 0;
11266           str = fmt_str;
11267         }
11268
11269       /* If the string was "", printf does nothing.  */
11270       if (str[0] == '\0')
11271         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11272
11273       /* If the string has length of 1, call putchar.  */
11274       if (str[1] == '\0')
11275         {
11276           /* Given printf("c"), (where c is any one character,)
11277              convert "c"[0] to an int and pass that to the replacement
11278              function.  */
11279           arg = build_int_cst (NULL_TREE, str[0]);
11280           arglist = build_tree_list (NULL_TREE, arg);
11281           fn = fn_putchar;
11282         }
11283       else
11284         {
11285           /* If the string was "string\n", call puts("string").  */
11286           size_t len = strlen (str);
11287           if ((unsigned char)str[len - 1] == target_newline)
11288             {
11289               /* Create a NUL-terminated string that's one char shorter
11290                  than the original, stripping off the trailing '\n'.  */
11291               char *newstr = alloca (len);
11292               memcpy (newstr, str, len - 1);
11293               newstr[len - 1] = 0;
11294
11295               arg = build_string_literal (len, newstr);
11296               arglist = build_tree_list (NULL_TREE, arg);
11297               fn = fn_puts;
11298             }
11299           else
11300             /* We'd like to arrange to call fputs(string,stdout) here,
11301                but we need stdout and don't have a way to get it yet.  */
11302             return 0;
11303         }
11304     }
11305
11306   /* The other optimizations can be done only on the non-va_list variants.  */
11307   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
11308     return 0;
11309
11310   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
11311   else if (strcmp (fmt_str, target_percent_s_newline) == 0)
11312     {
11313       if (! arglist
11314           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11315           || TREE_CHAIN (arglist))
11316         return 0;
11317       fn = fn_puts;
11318     }
11319
11320   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
11321   else if (strcmp (fmt_str, target_percent_c) == 0)
11322     {
11323       if (! arglist
11324           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11325           || TREE_CHAIN (arglist))
11326         return 0;
11327       fn = fn_putchar;
11328     }
11329
11330   if (!fn)
11331     return 0;
11332
11333   call = build_function_call_expr (fn, arglist);
11334   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11335 }
11336
11337 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
11338
11339    Return 0 if no simplification was possible, otherwise return the
11340    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
11341    code of the function to be simplified.  */
11342
11343 static tree
11344 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
11345                       enum built_in_function fcode)
11346 {
11347   tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
11348   const char *fmt_str = NULL;
11349
11350   /* If the return value is used, don't do the transformation.  */
11351   if (! ignore)
11352     return 0;
11353
11354   /* Verify the required arguments in the original call.  */
11355   if (! arglist)
11356     return 0;
11357   fp = TREE_VALUE (arglist);
11358   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
11359     return 0;
11360   arglist = TREE_CHAIN (arglist);
11361
11362   if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
11363     {
11364       tree flag;
11365
11366       if (! arglist)
11367         return 0;
11368       flag = TREE_VALUE (arglist);
11369       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
11370           || TREE_SIDE_EFFECTS (flag))
11371         return 0;
11372       arglist = TREE_CHAIN (arglist);
11373     }
11374
11375   if (! arglist)
11376     return 0;
11377   fmt = TREE_VALUE (arglist);
11378   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
11379     return 0;
11380   arglist = TREE_CHAIN (arglist);
11381
11382   /* Check whether the format is a literal string constant.  */
11383   fmt_str = c_getstr (fmt);
11384   if (fmt_str == NULL)
11385     return NULL_TREE;
11386
11387   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
11388     {
11389       /* If we're using an unlocked function, assume the other
11390          unlocked functions exist explicitly.  */
11391       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
11392       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
11393     }
11394   else
11395     {
11396       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
11397       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
11398     }
11399
11400   if (!init_target_chars())
11401     return 0;
11402
11403   /* If the format doesn't contain % args or %%, use strcpy.  */
11404   if (strchr (fmt_str, target_percent) == NULL)
11405     {
11406       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
11407           && arglist)
11408         return 0;
11409
11410       /* If the format specifier was "", fprintf does nothing.  */
11411       if (fmt_str[0] == '\0')
11412         {
11413           /* If FP has side-effects, just wait until gimplification is
11414              done.  */
11415           if (TREE_SIDE_EFFECTS (fp))
11416             return 0;
11417
11418           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
11419         }
11420
11421       /* When "string" doesn't contain %, replace all cases of
11422          fprintf (fp, string) with fputs (string, fp).  The fputs
11423          builtin will take care of special cases like length == 1.  */
11424       arglist = build_tree_list (NULL_TREE, fp);
11425       arglist = tree_cons (NULL_TREE, fmt, arglist);
11426       fn = fn_fputs;
11427     }
11428
11429   /* The other optimizations can be done only on the non-va_list variants.  */
11430   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
11431     return 0;
11432
11433   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
11434   else if (strcmp (fmt_str, target_percent_s) == 0)
11435     {
11436       if (! arglist
11437           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
11438           || TREE_CHAIN (arglist))
11439         return 0;
11440       arg = TREE_VALUE (arglist);
11441       arglist = build_tree_list (NULL_TREE, fp);
11442       arglist = tree_cons (NULL_TREE, arg, arglist);
11443       fn = fn_fputs;
11444     }
11445
11446   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
11447   else if (strcmp (fmt_str, target_percent_c) == 0)
11448     {
11449       if (! arglist
11450           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
11451           || TREE_CHAIN (arglist))
11452         return 0;
11453       arg = TREE_VALUE (arglist);
11454       arglist = build_tree_list (NULL_TREE, fp);
11455       arglist = tree_cons (NULL_TREE, arg, arglist);
11456       fn = fn_fputc;
11457     }
11458
11459   if (!fn)
11460     return 0;
11461
11462   call = build_function_call_expr (fn, arglist);
11463   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
11464 }
11465
11466 /* Initialize format string characters in the target charset.  */
11467
11468 static bool
11469 init_target_chars (void)
11470 {
11471   static bool init;
11472   if (!init)
11473     {
11474       target_newline = lang_hooks.to_target_charset ('\n');
11475       target_percent = lang_hooks.to_target_charset ('%');
11476       target_c = lang_hooks.to_target_charset ('c');
11477       target_s = lang_hooks.to_target_charset ('s');
11478       if (target_newline == 0 || target_percent == 0 || target_c == 0
11479           || target_s == 0)
11480         return false;
11481
11482       target_percent_c[0] = target_percent;
11483       target_percent_c[1] = target_c;
11484       target_percent_c[2] = '\0';
11485
11486       target_percent_s[0] = target_percent;
11487       target_percent_s[1] = target_s;
11488       target_percent_s[2] = '\0';
11489
11490       target_percent_s_newline[0] = target_percent;
11491       target_percent_s_newline[1] = target_s;
11492       target_percent_s_newline[2] = target_newline;
11493       target_percent_s_newline[3] = '\0';
11494
11495       init = true;
11496     }
11497   return true;
11498 }
11499
11500 /* Helper function for do_mpfr_arg*().  Ensure M is a normal number
11501    and no overflow/underflow occurred.  INEXACT is true if M was not
11502    exactly calculated.  TYPE is the tree type for the result.  This
11503    function assumes that you cleared the MPFR flags and then
11504    calculated M to see if anything subsequently set a flag prior to
11505    entering this function.  Return NULL_TREE if any checks fail.  */
11506
11507 static tree
11508 do_mpfr_ckconv(mpfr_srcptr m, tree type, int inexact)
11509 {
11510   /* Proceed iff we get a normal number, i.e. not NaN or Inf and no
11511      overflow/underflow occurred.  If -frounding-math, proceed iff the
11512      result of calling FUNC was exact.  */
11513   if (mpfr_number_p (m) && !mpfr_overflow_p() && !mpfr_underflow_p()
11514       && (!flag_rounding_math || !inexact))
11515     {
11516       REAL_VALUE_TYPE rr;
11517
11518       real_from_mpfr (&rr, m);
11519       /* Proceed iff GCC's REAL_VALUE_TYPE can hold the MPFR value,
11520          check for overflow/underflow.  If the REAL_VALUE_TYPE is zero
11521          but the mpft_t is not, then we underflowed in the
11522          conversion.  */
11523       if (!real_isnan (&rr) && !real_isinf (&rr)
11524           && (rr.cl == rvc_zero) == (mpfr_zero_p (m) != 0))
11525         {
11526           REAL_VALUE_TYPE rmode;
11527
11528           real_convert (&rmode, TYPE_MODE (type), &rr);
11529           /* Proceed iff the specified mode can hold the value.  */
11530           if (real_identical (&rmode, &rr))
11531             return build_real (type, rmode);
11532         }
11533     }
11534   return NULL_TREE;
11535 }
11536
11537 /* If argument ARG is a REAL_CST, call the one-argument mpfr function
11538    FUNC on it and return the resulting value as a tree with type TYPE.
11539    If MIN and/or MAX are not NULL, then the supplied ARG must be
11540    within those bounds.  If INCLUSIVE is true, then MIN/MAX are
11541    acceptable values, otherwise they are not.  The mpfr precision is
11542    set to the precision of TYPE.  We assume that function FUNC returns
11543    zero if the result could be calculated exactly within the requested
11544    precision.  */
11545
11546 static tree
11547 do_mpfr_arg1 (tree arg, tree type, int (*func)(mpfr_ptr, mpfr_srcptr, mp_rnd_t),
11548               const REAL_VALUE_TYPE *min, const REAL_VALUE_TYPE *max,
11549               bool inclusive)
11550 {
11551   tree result = NULL_TREE;
11552   
11553   STRIP_NOPS (arg);
11554
11555   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11556     {
11557       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11558
11559       if (!real_isnan (ra) && !real_isinf (ra)
11560           && (!min || real_compare (inclusive ? GE_EXPR: GT_EXPR , ra, min))
11561           && (!max || real_compare (inclusive ? LE_EXPR: LT_EXPR , ra, max)))
11562         {
11563           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11564           int inexact;
11565           mpfr_t m;
11566
11567           mpfr_init2 (m, prec);
11568           mpfr_from_real (m, ra);
11569           mpfr_clear_flags();
11570           inexact = func (m, m, GMP_RNDN);
11571           result = do_mpfr_ckconv (m, type, inexact);
11572           mpfr_clear (m);
11573         }
11574     }
11575   
11576   return result;
11577 }
11578
11579 /* If argument ARG is a REAL_CST, call the two-argument mpfr function
11580    FUNC on it and return the resulting value as a tree with type TYPE.
11581    The mpfr precision is set to the precision of TYPE.  We assume that
11582    function FUNC returns zero if the result could be calculated
11583    exactly within the requested precision.  */
11584
11585 static tree
11586 do_mpfr_arg2 (tree arg1, tree arg2, tree type,
11587               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11588 {
11589   tree result = NULL_TREE;
11590   
11591   STRIP_NOPS (arg1);
11592   STRIP_NOPS (arg2);
11593
11594   if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11595       && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2))
11596     {
11597       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11598       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11599
11600       if (!real_isnan (ra1) && !real_isinf (ra1)
11601           && !real_isnan (ra2) && !real_isinf (ra2))
11602         {
11603           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11604           int inexact;
11605           mpfr_t m1, m2;
11606
11607           mpfr_inits2 (prec, m1, m2, NULL);
11608           mpfr_from_real (m1, ra1);
11609           mpfr_from_real (m2, ra2);
11610           mpfr_clear_flags();
11611           inexact = func (m1, m1, m2, GMP_RNDN);
11612           result = do_mpfr_ckconv (m1, type, inexact);
11613           mpfr_clears (m1, m2, NULL);
11614         }
11615     }
11616   
11617   return result;
11618 }
11619
11620 /* If argument ARG is a REAL_CST, call the three-argument mpfr function
11621    FUNC on it and return the resulting value as a tree with type TYPE.
11622    The mpfr precision is set to the precision of TYPE.  We assume that
11623    function FUNC returns zero if the result could be calculated
11624    exactly within the requested precision.  */
11625
11626 static tree
11627 do_mpfr_arg3 (tree arg1, tree arg2, tree arg3, tree type,
11628               int (*func)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr, mp_rnd_t))
11629 {
11630   tree result = NULL_TREE;
11631   
11632   STRIP_NOPS (arg1);
11633   STRIP_NOPS (arg2);
11634   STRIP_NOPS (arg3);
11635
11636   if (TREE_CODE (arg1) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg1)
11637       && TREE_CODE (arg2) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg2)
11638       && TREE_CODE (arg3) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg3))
11639     {
11640       const REAL_VALUE_TYPE *const ra1 = &TREE_REAL_CST (arg1);
11641       const REAL_VALUE_TYPE *const ra2 = &TREE_REAL_CST (arg2);
11642       const REAL_VALUE_TYPE *const ra3 = &TREE_REAL_CST (arg3);
11643
11644       if (!real_isnan (ra1) && !real_isinf (ra1)
11645           && !real_isnan (ra2) && !real_isinf (ra2)
11646           && !real_isnan (ra3) && !real_isinf (ra3))
11647         {
11648           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11649           int inexact;
11650           mpfr_t m1, m2, m3;
11651
11652           mpfr_inits2 (prec, m1, m2, m3, NULL);
11653           mpfr_from_real (m1, ra1);
11654           mpfr_from_real (m2, ra2);
11655           mpfr_from_real (m3, ra3);
11656           mpfr_clear_flags();
11657           inexact = func (m1, m1, m2, m3, GMP_RNDN);
11658           result = do_mpfr_ckconv (m1, type, inexact);
11659           mpfr_clears (m1, m2, m3, NULL);
11660         }
11661     }
11662   
11663   return result;
11664 }
11665
11666 /* If argument ARG is a REAL_CST, call mpfr_sin_cos() on it and set
11667    the pointers *(ARG_SINP) and *(ARG_COSP) to the resulting values.
11668    The type is taken from the type of ARG and is used for setting the
11669    precision of the calculation and results.  */
11670
11671 static tree
11672 do_mpfr_sincos (tree arg, tree arg_sinp, tree arg_cosp)
11673 {
11674   tree result = NULL_TREE;
11675   
11676   STRIP_NOPS (arg);
11677   
11678   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
11679     {
11680       const REAL_VALUE_TYPE *const ra = &TREE_REAL_CST (arg);
11681
11682       if (!real_isnan (ra) && !real_isinf (ra))
11683         {
11684           tree const type = TREE_TYPE (arg);
11685           const int prec = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
11686           tree result_s, result_c;
11687           int inexact;
11688           mpfr_t m, ms, mc;
11689
11690           mpfr_inits2 (prec, m, ms, mc, NULL);
11691           mpfr_from_real (m, ra);
11692           mpfr_clear_flags();
11693           inexact = mpfr_sin_cos (ms, mc, m, GMP_RNDN);
11694           result_s = do_mpfr_ckconv (ms, type, inexact);
11695           result_c = do_mpfr_ckconv (mc, type, inexact);
11696           mpfr_clears (m, ms, mc, NULL);
11697           if (result_s && result_c)
11698             {
11699               /* Dereference the sin/cos pointer arguments.  */
11700               arg_sinp = build_fold_indirect_ref (arg_sinp);
11701               arg_cosp = build_fold_indirect_ref (arg_cosp);
11702               /* Proceed if valid pointer type were passed in.  */
11703               if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_sinp)) == TYPE_MAIN_VARIANT (type)
11704                   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_cosp)) == TYPE_MAIN_VARIANT (type))
11705                 {
11706                   /* Set the values. */
11707                   result_s = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_sinp,
11708                                           result_s);
11709                   TREE_SIDE_EFFECTS (result_s) = 1;
11710                   result_c = fold_build2 (GIMPLE_MODIFY_STMT, type, arg_cosp,
11711                                           result_c);
11712                   TREE_SIDE_EFFECTS (result_c) = 1;
11713                   /* Combine the assignments into a compound expr.  */
11714                   result = non_lvalue (fold_build2 (COMPOUND_EXPR, type,
11715                                                     result_s, result_c));
11716                 }
11717             }
11718         }
11719     }
11720   return result;
11721 }