OSDN Git Service

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