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