OSDN Git Service

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