OSDN Git Service

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