OSDN Git Service

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