OSDN Git Service

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