OSDN Git Service

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