OSDN Git Service

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