OSDN Git Service

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