OSDN Git Service

PR middle-end/25022
[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   /* If we're using an unlocked function, assume the other unlocked
4847      functions exist explicitly.  */
4848   tree const fn_putchar = unlocked ? built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4849     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4850   tree const fn_puts = unlocked ? built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4851     : implicit_built_in_decls[BUILT_IN_PUTS];
4852   const char *fmt_str;
4853   tree fn, fmt, arg;
4854
4855   /* If the return value is used, don't do the transformation.  */
4856   if (target != const0_rtx)
4857     return 0;
4858
4859   /* Verify the required arguments in the original call.  */
4860   if (! arglist)
4861     return 0;
4862   fmt = TREE_VALUE (arglist);
4863   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4864     return 0;
4865   arglist = TREE_CHAIN (arglist);
4866
4867   /* Check whether the format is a literal string constant.  */
4868   fmt_str = c_getstr (fmt);
4869   if (fmt_str == NULL)
4870     return 0;
4871
4872   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4873   if (strcmp (fmt_str, "%s\n") == 0)
4874     {
4875       if (! arglist
4876           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4877           || TREE_CHAIN (arglist))
4878         return 0;
4879       fn = fn_puts;
4880     }
4881   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4882   else if (strcmp (fmt_str, "%c") == 0)
4883     {
4884       if (! arglist
4885           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4886           || TREE_CHAIN (arglist))
4887         return 0;
4888       fn = fn_putchar;
4889     }
4890   else
4891     {
4892       /* We can't handle anything else with % args or %% ... yet.  */
4893       if (strchr (fmt_str, '%'))
4894         return 0;
4895
4896       if (arglist)
4897         return 0;
4898
4899       /* If the format specifier was "", printf does nothing.  */
4900       if (fmt_str[0] == '\0')
4901         return const0_rtx;
4902       /* If the format specifier has length of 1, call putchar.  */
4903       if (fmt_str[1] == '\0')
4904         {
4905           /* Given printf("c"), (where c is any one character,)
4906              convert "c"[0] to an int and pass that to the replacement
4907              function.  */
4908           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4909           arglist = build_tree_list (NULL_TREE, arg);
4910           fn = fn_putchar;
4911         }
4912       else
4913         {
4914           /* If the format specifier was "string\n", call puts("string").  */
4915           size_t len = strlen (fmt_str);
4916           if (fmt_str[len - 1] == '\n')
4917             {
4918               /* Create a NUL-terminated string that's one char shorter
4919                  than the original, stripping off the trailing '\n'.  */
4920               char *newstr = alloca (len);
4921               memcpy (newstr, fmt_str, len - 1);
4922               newstr[len - 1] = 0;
4923
4924               arg = build_string_literal (len, newstr);
4925               arglist = build_tree_list (NULL_TREE, arg);
4926               fn = fn_puts;
4927             }
4928           else
4929             /* We'd like to arrange to call fputs(string,stdout) here,
4930                but we need stdout and don't have a way to get it yet.  */
4931             return 0;
4932         }
4933     }
4934
4935   if (!fn)
4936     return 0;
4937   fn = build_function_call_expr (fn, arglist);
4938   if (TREE_CODE (fn) == CALL_EXPR)
4939     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
4940   return expand_expr (fn, target, mode, EXPAND_NORMAL);
4941 }
4942
4943 /* Expand EXP, a call to fprintf or fprintf_unlocked.
4944    Return 0 if a normal call should be emitted rather than transforming
4945    the function inline.  If convenient, the result should be placed in
4946    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4947    call.  */
4948 static rtx
4949 expand_builtin_fprintf (tree exp, rtx target, enum machine_mode mode,
4950                         bool unlocked)
4951 {
4952   tree arglist = TREE_OPERAND (exp, 1);
4953   /* If we're using an unlocked function, assume the other unlocked
4954      functions exist explicitly.  */
4955   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4956     : implicit_built_in_decls[BUILT_IN_FPUTC];
4957   tree const fn_fputs = unlocked ? built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4958     : implicit_built_in_decls[BUILT_IN_FPUTS];
4959   const char *fmt_str;
4960   tree fn, fmt, fp, arg;
4961
4962   /* If the return value is used, don't do the transformation.  */
4963   if (target != const0_rtx)
4964     return 0;
4965
4966   /* Verify the required arguments in the original call.  */
4967   if (! arglist)
4968     return 0;
4969   fp = TREE_VALUE (arglist);
4970   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
4971     return 0;
4972   arglist = TREE_CHAIN (arglist);
4973   if (! arglist)
4974     return 0;
4975   fmt = TREE_VALUE (arglist);
4976   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
4977     return 0;
4978   arglist = TREE_CHAIN (arglist);
4979
4980   /* Check whether the format is a literal string constant.  */
4981   fmt_str = c_getstr (fmt);
4982   if (fmt_str == NULL)
4983     return 0;
4984
4985   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4986   if (strcmp (fmt_str, "%s") == 0)
4987     {
4988       if (! arglist
4989           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
4990           || TREE_CHAIN (arglist))
4991         return 0;
4992       arg = TREE_VALUE (arglist);
4993       arglist = build_tree_list (NULL_TREE, fp);
4994       arglist = tree_cons (NULL_TREE, arg, arglist);
4995       fn = fn_fputs;
4996     }
4997   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4998   else if (strcmp (fmt_str, "%c") == 0)
4999     {
5000       if (! arglist
5001           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5002           || TREE_CHAIN (arglist))
5003         return 0;
5004       arg = TREE_VALUE (arglist);
5005       arglist = build_tree_list (NULL_TREE, fp);
5006       arglist = tree_cons (NULL_TREE, arg, arglist);
5007       fn = fn_fputc;
5008     }
5009   else
5010     {
5011       /* We can't handle anything else with % args or %% ... yet.  */
5012       if (strchr (fmt_str, '%'))
5013         return 0;
5014
5015       if (arglist)
5016         return 0;
5017
5018       /* If the format specifier was "", fprintf does nothing.  */
5019       if (fmt_str[0] == '\0')
5020         {
5021           /* Evaluate and ignore FILE* argument for side-effects.  */
5022           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5023           return const0_rtx;
5024         }
5025
5026       /* When "string" doesn't contain %, replace all cases of
5027          fprintf(stream,string) with fputs(string,stream).  The fputs
5028          builtin will take care of special cases like length == 1.  */
5029       arglist = build_tree_list (NULL_TREE, fp);
5030       arglist = tree_cons (NULL_TREE, fmt, arglist);
5031       fn = fn_fputs;
5032     }
5033
5034   if (!fn)
5035     return 0;
5036   fn = build_function_call_expr (fn, arglist);
5037   if (TREE_CODE (fn) == CALL_EXPR)
5038     CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
5039   return expand_expr (fn, target, mode, EXPAND_NORMAL);
5040 }
5041
5042 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5043    a normal call should be emitted rather than expanding the function
5044    inline.  If convenient, the result should be placed in TARGET with
5045    mode MODE.  */
5046
5047 static rtx
5048 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5049 {
5050   tree orig_arglist, dest, fmt;
5051   const char *fmt_str;
5052
5053   orig_arglist = arglist;
5054
5055   /* Verify the required arguments in the original call.  */
5056   if (! arglist)
5057     return 0;
5058   dest = TREE_VALUE (arglist);
5059   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
5060     return 0;
5061   arglist = TREE_CHAIN (arglist);
5062   if (! arglist)
5063     return 0;
5064   fmt = TREE_VALUE (arglist);
5065   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
5066     return 0;
5067   arglist = TREE_CHAIN (arglist);
5068
5069   /* Check whether the format is a literal string constant.  */
5070   fmt_str = c_getstr (fmt);
5071   if (fmt_str == NULL)
5072     return 0;
5073
5074   /* If the format doesn't contain % args or %%, use strcpy.  */
5075   if (strchr (fmt_str, '%') == 0)
5076     {
5077       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5078       tree exp;
5079
5080       if (arglist || ! fn)
5081         return 0;
5082       expand_expr (build_function_call_expr (fn, orig_arglist),
5083                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5084       if (target == const0_rtx)
5085         return const0_rtx;
5086       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
5087       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5088     }
5089   /* If the format is "%s", use strcpy if the result isn't used.  */
5090   else if (strcmp (fmt_str, "%s") == 0)
5091     {
5092       tree fn, arg, len;
5093       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5094
5095       if (! fn)
5096         return 0;
5097
5098       if (! arglist || TREE_CHAIN (arglist))
5099         return 0;
5100       arg = TREE_VALUE (arglist);
5101       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
5102         return 0;
5103
5104       if (target != const0_rtx)
5105         {
5106           len = c_strlen (arg, 1);
5107           if (! len || TREE_CODE (len) != INTEGER_CST)
5108             return 0;
5109         }
5110       else
5111         len = NULL_TREE;
5112
5113       arglist = build_tree_list (NULL_TREE, arg);
5114       arglist = tree_cons (NULL_TREE, dest, arglist);
5115       expand_expr (build_function_call_expr (fn, arglist),
5116                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5117
5118       if (target == const0_rtx)
5119         return const0_rtx;
5120       return expand_expr (len, target, mode, EXPAND_NORMAL);
5121     }
5122
5123   return 0;
5124 }
5125
5126 /* Expand a call to either the entry or exit function profiler.  */
5127
5128 static rtx
5129 expand_builtin_profile_func (bool exitp)
5130 {
5131   rtx this, which;
5132
5133   this = DECL_RTL (current_function_decl);
5134   gcc_assert (MEM_P (this));
5135   this = XEXP (this, 0);
5136
5137   if (exitp)
5138     which = profile_function_exit_libfunc;
5139   else
5140     which = profile_function_entry_libfunc;
5141
5142   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5143                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5144                                                  0),
5145                      Pmode);
5146
5147   return const0_rtx;
5148 }
5149
5150 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5151
5152 static rtx
5153 round_trampoline_addr (rtx tramp)
5154 {
5155   rtx temp, addend, mask;
5156
5157   /* If we don't need too much alignment, we'll have been guaranteed
5158      proper alignment by get_trampoline_type.  */
5159   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5160     return tramp;
5161
5162   /* Round address up to desired boundary.  */
5163   temp = gen_reg_rtx (Pmode);
5164   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5165   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5166
5167   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5168                                temp, 0, OPTAB_LIB_WIDEN);
5169   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5170                                temp, 0, OPTAB_LIB_WIDEN);
5171
5172   return tramp;
5173 }
5174
5175 static rtx
5176 expand_builtin_init_trampoline (tree arglist)
5177 {
5178   tree t_tramp, t_func, t_chain;
5179   rtx r_tramp, r_func, r_chain;
5180 #ifdef TRAMPOLINE_TEMPLATE
5181   rtx blktramp;
5182 #endif
5183
5184   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5185                          POINTER_TYPE, VOID_TYPE))
5186     return NULL_RTX;
5187
5188   t_tramp = TREE_VALUE (arglist);
5189   arglist = TREE_CHAIN (arglist);
5190   t_func = TREE_VALUE (arglist);
5191   arglist = TREE_CHAIN (arglist);
5192   t_chain = TREE_VALUE (arglist);
5193
5194   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5195   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5196   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5197
5198   /* Generate insns to initialize the trampoline.  */
5199   r_tramp = round_trampoline_addr (r_tramp);
5200 #ifdef TRAMPOLINE_TEMPLATE
5201   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5202   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5203   emit_block_move (blktramp, assemble_trampoline_template (),
5204                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5205 #endif
5206   trampolines_created = 1;
5207   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5208
5209   return const0_rtx;
5210 }
5211
5212 static rtx
5213 expand_builtin_adjust_trampoline (tree arglist)
5214 {
5215   rtx tramp;
5216
5217   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5218     return NULL_RTX;
5219
5220   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5221   tramp = round_trampoline_addr (tramp);
5222 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5223   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5224 #endif
5225
5226   return tramp;
5227 }
5228
5229 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5230    Return NULL_RTX if a normal call should be emitted rather than expanding
5231    the function in-line.  EXP is the expression that is a call to the builtin
5232    function; if convenient, the result should be placed in TARGET.  */
5233
5234 static rtx
5235 expand_builtin_signbit (tree exp, rtx target)
5236 {
5237   const struct real_format *fmt;
5238   enum machine_mode fmode, imode, rmode;
5239   HOST_WIDE_INT hi, lo;
5240   tree arg, arglist;
5241   int word, bitpos;
5242   rtx temp;
5243
5244   arglist = TREE_OPERAND (exp, 1);
5245   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5246     return 0;
5247
5248   arg = TREE_VALUE (arglist);
5249   fmode = TYPE_MODE (TREE_TYPE (arg));
5250   rmode = TYPE_MODE (TREE_TYPE (exp));
5251   fmt = REAL_MODE_FORMAT (fmode);
5252
5253   /* For floating point formats without a sign bit, implement signbit
5254      as "ARG < 0.0".  */
5255   bitpos = fmt->signbit_ro;
5256   if (bitpos < 0)
5257   {
5258     /* But we can't do this if the format supports signed zero.  */
5259     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5260       return 0;
5261
5262     arg = fold_build2 (LT_EXPR, TREE_TYPE (exp), arg,
5263                        build_real (TREE_TYPE (arg), dconst0));
5264     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5265   }
5266
5267   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5268   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
5269     {
5270       imode = int_mode_for_mode (fmode);
5271       if (imode == BLKmode)
5272         return 0;
5273       temp = gen_lowpart (imode, temp);
5274     }
5275   else
5276     {
5277       imode = word_mode;
5278       /* Handle targets with different FP word orders.  */
5279       if (FLOAT_WORDS_BIG_ENDIAN)
5280         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5281       else
5282         word = bitpos / BITS_PER_WORD;
5283       temp = operand_subword_force (temp, word, fmode);
5284       bitpos = bitpos % BITS_PER_WORD;
5285     }
5286
5287   /* Force the intermediate word_mode (or narrower) result into a
5288      register.  This avoids attempting to create paradoxical SUBREGs
5289      of floating point modes below.  */
5290   temp = force_reg (imode, temp);
5291
5292   /* If the bitpos is within the "result mode" lowpart, the operation
5293      can be implement with a single bitwise AND.  Otherwise, we need
5294      a right shift and an AND.  */
5295
5296   if (bitpos < GET_MODE_BITSIZE (rmode))
5297     {
5298       if (bitpos < HOST_BITS_PER_WIDE_INT)
5299         {
5300           hi = 0;
5301           lo = (HOST_WIDE_INT) 1 << bitpos;
5302         }
5303       else
5304         {
5305           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5306           lo = 0;
5307         }
5308
5309       if (imode != rmode)
5310         temp = gen_lowpart (rmode, temp);
5311       temp = expand_binop (rmode, and_optab, temp,
5312                            immed_double_const (lo, hi, rmode),
5313                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5314     }
5315   else
5316     {
5317       /* Perform a logical right shift to place the signbit in the least
5318          significant bit, then truncate the result to the desired mode
5319          and mask just this bit.  */
5320       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5321                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5322       temp = gen_lowpart (rmode, temp);
5323       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5324                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5325     }
5326
5327   return temp;
5328 }
5329
5330 /* Expand fork or exec calls.  TARGET is the desired target of the
5331    call.  ARGLIST is the list of arguments of the call.  FN is the
5332    identificator of the actual function.  IGNORE is nonzero if the
5333    value is to be ignored.  */
5334
5335 static rtx
5336 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5337 {
5338   tree id, decl;
5339   tree call;
5340
5341   /* If we are not profiling, just call the function.  */
5342   if (!profile_arc_flag)
5343     return NULL_RTX;
5344
5345   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5346      compiler, so the code does not diverge, and the wrapper may run the
5347      code necessary for keeping the profiling sane.  */
5348
5349   switch (DECL_FUNCTION_CODE (fn))
5350     {
5351     case BUILT_IN_FORK:
5352       id = get_identifier ("__gcov_fork");
5353       break;
5354
5355     case BUILT_IN_EXECL:
5356       id = get_identifier ("__gcov_execl");
5357       break;
5358
5359     case BUILT_IN_EXECV:
5360       id = get_identifier ("__gcov_execv");
5361       break;
5362
5363     case BUILT_IN_EXECLP:
5364       id = get_identifier ("__gcov_execlp");
5365       break;
5366
5367     case BUILT_IN_EXECLE:
5368       id = get_identifier ("__gcov_execle");
5369       break;
5370
5371     case BUILT_IN_EXECVP:
5372       id = get_identifier ("__gcov_execvp");
5373       break;
5374
5375     case BUILT_IN_EXECVE:
5376       id = get_identifier ("__gcov_execve");
5377       break;
5378
5379     default:
5380       gcc_unreachable ();
5381     }
5382
5383   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5384   DECL_EXTERNAL (decl) = 1;
5385   TREE_PUBLIC (decl) = 1;
5386   DECL_ARTIFICIAL (decl) = 1;
5387   TREE_NOTHROW (decl) = 1;
5388   call = build_function_call_expr (decl, arglist);
5389
5390   return expand_call (call, target, ignore);
5391 }
5392
5393 \f
5394 /* Reconstitute a mode for a __sync intrinsic operation.  Since the type of
5395    the pointer in these functions is void*, the tree optimizers may remove
5396    casts.  The mode computed in expand_builtin isn't reliable either, due
5397    to __sync_bool_compare_and_swap.
5398
5399    FCODE_DIFF should be fcode - base, where base is the FOO_1 code for the
5400    group of builtins.  This gives us log2 of the mode size.  */
5401
5402 static inline enum machine_mode
5403 get_builtin_sync_mode (int fcode_diff)
5404 {
5405   /* The size is not negotiable, so ask not to get BLKmode in return
5406      if the target indicates that a smaller size would be better.  */
5407   return mode_for_size (BITS_PER_UNIT << fcode_diff, MODE_INT, 0);
5408 }
5409
5410 /* Expand the __sync_xxx_and_fetch and __sync_fetch_and_xxx intrinsics.
5411    ARGLIST is the operands list to the function.  CODE is the rtx code 
5412    that corresponds to the arithmetic or logical operation from the name;
5413    an exception here is that NOT actually means NAND.  TARGET is an optional
5414    place for us to store the results; AFTER is true if this is the
5415    fetch_and_xxx form.  IGNORE is true if we don't actually care about
5416    the result of the operation at all.  */
5417
5418 static rtx
5419 expand_builtin_sync_operation (enum machine_mode mode, tree arglist,
5420                                enum rtx_code code, bool after,
5421                                rtx target, bool ignore)
5422 {
5423   rtx addr, val, mem;
5424
5425   /* Expand the operands.  */
5426   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5427
5428   arglist = TREE_CHAIN (arglist);
5429   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5430
5431   /* Note that we explicitly do not want any alias information for this
5432      memory, so that we kill all other live memories.  Otherwise we don't
5433      satisfy the full barrier semantics of the intrinsic.  */
5434   mem = validize_mem (gen_rtx_MEM (mode, addr));
5435   MEM_VOLATILE_P (mem) = 1;
5436
5437   if (ignore)
5438     return expand_sync_operation (mem, val, code);
5439   else
5440     return expand_sync_fetch_operation (mem, val, code, after, target);
5441 }
5442
5443 /* Expand the __sync_val_compare_and_swap and __sync_bool_compare_and_swap
5444    intrinsics.  ARGLIST is the operands list to the function.  IS_BOOL is
5445    true if this is the boolean form.  TARGET is a place for us to store the
5446    results; this is NOT optional if IS_BOOL is true.  */
5447
5448 static rtx
5449 expand_builtin_compare_and_swap (enum machine_mode mode, tree arglist,
5450                                  bool is_bool, rtx target)
5451 {
5452   rtx addr, old_val, new_val, mem;
5453
5454   /* Expand the operands.  */
5455   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_SUM);
5456
5457   arglist = TREE_CHAIN (arglist);
5458   old_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5459
5460   arglist = TREE_CHAIN (arglist);
5461   new_val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5462
5463   /* Note that we explicitly do not want any alias information for this
5464      memory, so that we kill all other live memories.  Otherwise we don't
5465      satisfy the full barrier semantics of the intrinsic.  */
5466   mem = validize_mem (gen_rtx_MEM (mode, addr));
5467   MEM_VOLATILE_P (mem) = 1;
5468
5469   if (is_bool)
5470     return expand_bool_compare_and_swap (mem, old_val, new_val, target);
5471   else
5472     return expand_val_compare_and_swap (mem, old_val, new_val, target);
5473 }
5474
5475 /* Expand the __sync_lock_test_and_set intrinsic.  Note that the most
5476    general form is actually an atomic exchange, and some targets only
5477    support a reduced form with the second argument being a constant 1.
5478    ARGLIST is the operands list to the function; TARGET is an optional
5479    place for us to store the results.  */
5480
5481 static rtx
5482 expand_builtin_lock_test_and_set (enum machine_mode mode, tree arglist,
5483                                   rtx target)
5484 {
5485   rtx addr, val, mem;
5486
5487   /* Expand the operands.  */
5488   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5489
5490   arglist = TREE_CHAIN (arglist);
5491   val = expand_expr (TREE_VALUE (arglist), NULL, mode, EXPAND_NORMAL);
5492
5493   /* Note that we explicitly do not want any alias information for this
5494      memory, so that we kill all other live memories.  Otherwise we don't
5495      satisfy the barrier semantics of the intrinsic.  */
5496   mem = validize_mem (gen_rtx_MEM (mode, addr));
5497   MEM_VOLATILE_P (mem) = 1;
5498
5499   return expand_sync_lock_test_and_set (mem, val, target);
5500 }
5501
5502 /* Expand the __sync_synchronize intrinsic.  */
5503
5504 static void
5505 expand_builtin_synchronize (void)
5506 {
5507   tree x;
5508
5509 #ifdef HAVE_memory_barrier
5510   if (HAVE_memory_barrier)
5511     {
5512       emit_insn (gen_memory_barrier ());
5513       return;
5514     }
5515 #endif
5516
5517   /* If no explicit memory barrier instruction is available, create an
5518      empty asm stmt with a memory clobber.  */
5519   x = build4 (ASM_EXPR, void_type_node, build_string (0, ""), NULL, NULL,
5520               tree_cons (NULL, build_string (6, "memory"), NULL));
5521   ASM_VOLATILE_P (x) = 1;
5522   expand_asm_expr (x);
5523 }
5524
5525 /* Expand the __sync_lock_release intrinsic.  ARGLIST is the operands list
5526    to the function.  */
5527
5528 static void
5529 expand_builtin_lock_release (enum machine_mode mode, tree arglist)
5530 {
5531   enum insn_code icode;
5532   rtx addr, mem, insn;
5533   rtx val = const0_rtx;
5534
5535   /* Expand the operands.  */
5536   addr = expand_expr (TREE_VALUE (arglist), NULL, Pmode, EXPAND_NORMAL);
5537
5538   /* Note that we explicitly do not want any alias information for this
5539      memory, so that we kill all other live memories.  Otherwise we don't
5540      satisfy the barrier semantics of the intrinsic.  */
5541   mem = validize_mem (gen_rtx_MEM (mode, addr));
5542   MEM_VOLATILE_P (mem) = 1;
5543
5544   /* If there is an explicit operation in the md file, use it.  */
5545   icode = sync_lock_release[mode];
5546   if (icode != CODE_FOR_nothing)
5547     {
5548       if (!insn_data[icode].operand[1].predicate (val, mode))
5549         val = force_reg (mode, val);
5550
5551       insn = GEN_FCN (icode) (mem, val);
5552       if (insn)
5553         {
5554           emit_insn (insn);
5555           return;
5556         }
5557     }
5558
5559   /* Otherwise we can implement this operation by emitting a barrier
5560      followed by a store of zero.  */
5561   expand_builtin_synchronize ();
5562   emit_move_insn (mem, val);
5563 }
5564 \f
5565 /* Expand an expression EXP that calls a built-in function,
5566    with result going to TARGET if that's convenient
5567    (and in mode MODE if that's convenient).
5568    SUBTARGET may be used as the target for computing one of EXP's operands.
5569    IGNORE is nonzero if the value is to be ignored.  */
5570
5571 rtx
5572 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5573                 int ignore)
5574 {
5575   tree fndecl = get_callee_fndecl (exp);
5576   tree arglist = TREE_OPERAND (exp, 1);
5577   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5578   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5579
5580   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5581     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5582
5583   /* When not optimizing, generate calls to library functions for a certain
5584      set of builtins.  */
5585   if (!optimize
5586       && !called_as_built_in (fndecl)
5587       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5588       && fcode != BUILT_IN_ALLOCA)
5589     return expand_call (exp, target, ignore);
5590
5591   /* The built-in function expanders test for target == const0_rtx
5592      to determine whether the function's result will be ignored.  */
5593   if (ignore)
5594     target = const0_rtx;
5595
5596   /* If the result of a pure or const built-in function is ignored, and
5597      none of its arguments are volatile, we can avoid expanding the
5598      built-in call and just evaluate the arguments for side-effects.  */
5599   if (target == const0_rtx
5600       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5601     {
5602       bool volatilep = false;
5603       tree arg;
5604
5605       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5606         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5607           {
5608             volatilep = true;
5609             break;
5610           }
5611
5612       if (! volatilep)
5613         {
5614           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5615             expand_expr (TREE_VALUE (arg), const0_rtx,
5616                          VOIDmode, EXPAND_NORMAL);
5617           return const0_rtx;
5618         }
5619     }
5620
5621   switch (fcode)
5622     {
5623     case BUILT_IN_FABS:
5624     case BUILT_IN_FABSF:
5625     case BUILT_IN_FABSL:
5626       target = expand_builtin_fabs (arglist, target, subtarget);
5627       if (target)
5628         return target;
5629       break;
5630
5631     case BUILT_IN_COPYSIGN:
5632     case BUILT_IN_COPYSIGNF:
5633     case BUILT_IN_COPYSIGNL:
5634       target = expand_builtin_copysign (arglist, target, subtarget);
5635       if (target)
5636         return target;
5637       break;
5638
5639       /* Just do a normal library call if we were unable to fold
5640          the values.  */
5641     case BUILT_IN_CABS:
5642     case BUILT_IN_CABSF:
5643     case BUILT_IN_CABSL:
5644       break;
5645
5646     case BUILT_IN_EXP:
5647     case BUILT_IN_EXPF:
5648     case BUILT_IN_EXPL:
5649     case BUILT_IN_EXP10:
5650     case BUILT_IN_EXP10F:
5651     case BUILT_IN_EXP10L:
5652     case BUILT_IN_POW10:
5653     case BUILT_IN_POW10F:
5654     case BUILT_IN_POW10L:
5655     case BUILT_IN_EXP2:
5656     case BUILT_IN_EXP2F:
5657     case BUILT_IN_EXP2L:
5658     case BUILT_IN_EXPM1:
5659     case BUILT_IN_EXPM1F:
5660     case BUILT_IN_EXPM1L:
5661     case BUILT_IN_LOGB:
5662     case BUILT_IN_LOGBF:
5663     case BUILT_IN_LOGBL:
5664     case BUILT_IN_ILOGB:
5665     case BUILT_IN_ILOGBF:
5666     case BUILT_IN_ILOGBL:
5667     case BUILT_IN_LOG:
5668     case BUILT_IN_LOGF:
5669     case BUILT_IN_LOGL:
5670     case BUILT_IN_LOG10:
5671     case BUILT_IN_LOG10F:
5672     case BUILT_IN_LOG10L:
5673     case BUILT_IN_LOG2:
5674     case BUILT_IN_LOG2F:
5675     case BUILT_IN_LOG2L:
5676     case BUILT_IN_LOG1P:
5677     case BUILT_IN_LOG1PF:
5678     case BUILT_IN_LOG1PL:
5679     case BUILT_IN_TAN:
5680     case BUILT_IN_TANF:
5681     case BUILT_IN_TANL:
5682     case BUILT_IN_ASIN:
5683     case BUILT_IN_ASINF:
5684     case BUILT_IN_ASINL:
5685     case BUILT_IN_ACOS:
5686     case BUILT_IN_ACOSF:
5687     case BUILT_IN_ACOSL:
5688     case BUILT_IN_ATAN:
5689     case BUILT_IN_ATANF:
5690     case BUILT_IN_ATANL:
5691       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5692          because of possible accuracy problems.  */
5693       if (! flag_unsafe_math_optimizations)
5694         break;
5695     case BUILT_IN_SQRT:
5696     case BUILT_IN_SQRTF:
5697     case BUILT_IN_SQRTL:
5698     case BUILT_IN_FLOOR:
5699     case BUILT_IN_FLOORF:
5700     case BUILT_IN_FLOORL:
5701     case BUILT_IN_CEIL:
5702     case BUILT_IN_CEILF:
5703     case BUILT_IN_CEILL:
5704     case BUILT_IN_TRUNC:
5705     case BUILT_IN_TRUNCF:
5706     case BUILT_IN_TRUNCL:
5707     case BUILT_IN_ROUND:
5708     case BUILT_IN_ROUNDF:
5709     case BUILT_IN_ROUNDL:
5710     case BUILT_IN_NEARBYINT:
5711     case BUILT_IN_NEARBYINTF:
5712     case BUILT_IN_NEARBYINTL:
5713     case BUILT_IN_RINT:
5714     case BUILT_IN_RINTF:
5715     case BUILT_IN_RINTL:
5716     case BUILT_IN_LRINT:
5717     case BUILT_IN_LRINTF:
5718     case BUILT_IN_LRINTL:
5719     case BUILT_IN_LLRINT:
5720     case BUILT_IN_LLRINTF:
5721     case BUILT_IN_LLRINTL:
5722       target = expand_builtin_mathfn (exp, target, subtarget);
5723       if (target)
5724         return target;
5725       break;
5726
5727     case BUILT_IN_LCEIL:
5728     case BUILT_IN_LCEILF:
5729     case BUILT_IN_LCEILL:
5730     case BUILT_IN_LLCEIL:
5731     case BUILT_IN_LLCEILF:
5732     case BUILT_IN_LLCEILL:
5733     case BUILT_IN_LFLOOR:
5734     case BUILT_IN_LFLOORF:
5735     case BUILT_IN_LFLOORL:
5736     case BUILT_IN_LLFLOOR:
5737     case BUILT_IN_LLFLOORF:
5738     case BUILT_IN_LLFLOORL:
5739       target = expand_builtin_int_roundingfn (exp, target, subtarget);
5740       if (target)
5741         return target;
5742       break;
5743
5744     case BUILT_IN_POW:
5745     case BUILT_IN_POWF:
5746     case BUILT_IN_POWL:
5747       target = expand_builtin_pow (exp, target, subtarget);
5748       if (target)
5749         return target;
5750       break;
5751
5752     case BUILT_IN_POWI:
5753     case BUILT_IN_POWIF:
5754     case BUILT_IN_POWIL:
5755       target = expand_builtin_powi (exp, target, subtarget);
5756       if (target)
5757         return target;
5758       break;
5759
5760     case BUILT_IN_ATAN2:
5761     case BUILT_IN_ATAN2F:
5762     case BUILT_IN_ATAN2L:
5763     case BUILT_IN_LDEXP:
5764     case BUILT_IN_LDEXPF:
5765     case BUILT_IN_LDEXPL:
5766     case BUILT_IN_FMOD:
5767     case BUILT_IN_FMODF:
5768     case BUILT_IN_FMODL:
5769     case BUILT_IN_DREM:
5770     case BUILT_IN_DREMF:
5771     case BUILT_IN_DREML:
5772       if (! flag_unsafe_math_optimizations)
5773         break;
5774       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5775       if (target)
5776         return target;
5777       break;
5778
5779     case BUILT_IN_SIN:
5780     case BUILT_IN_SINF:
5781     case BUILT_IN_SINL:
5782     case BUILT_IN_COS:
5783     case BUILT_IN_COSF:
5784     case BUILT_IN_COSL:
5785       if (! flag_unsafe_math_optimizations)
5786         break;
5787       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5788       if (target)
5789         return target;
5790       break;
5791
5792     case BUILT_IN_APPLY_ARGS:
5793       return expand_builtin_apply_args ();
5794
5795       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5796          FUNCTION with a copy of the parameters described by
5797          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5798          allocated on the stack into which is stored all the registers
5799          that might possibly be used for returning the result of a
5800          function.  ARGUMENTS is the value returned by
5801          __builtin_apply_args.  ARGSIZE is the number of bytes of
5802          arguments that must be copied.  ??? How should this value be
5803          computed?  We'll also need a safe worst case value for varargs
5804          functions.  */
5805     case BUILT_IN_APPLY:
5806       if (!validate_arglist (arglist, POINTER_TYPE,
5807                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5808           && !validate_arglist (arglist, REFERENCE_TYPE,
5809                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5810         return const0_rtx;
5811       else
5812         {
5813           int i;
5814           tree t;
5815           rtx ops[3];
5816
5817           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5818             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5819
5820           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5821         }
5822
5823       /* __builtin_return (RESULT) causes the function to return the
5824          value described by RESULT.  RESULT is address of the block of
5825          memory returned by __builtin_apply.  */
5826     case BUILT_IN_RETURN:
5827       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5828         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5829                                             NULL_RTX, VOIDmode, 0));
5830       return const0_rtx;
5831
5832     case BUILT_IN_SAVEREGS:
5833       return expand_builtin_saveregs ();
5834
5835     case BUILT_IN_ARGS_INFO:
5836       return expand_builtin_args_info (arglist);
5837
5838       /* Return the address of the first anonymous stack arg.  */
5839     case BUILT_IN_NEXT_ARG:
5840       if (fold_builtin_next_arg (arglist))
5841         return const0_rtx;
5842       return expand_builtin_next_arg ();
5843
5844     case BUILT_IN_CLASSIFY_TYPE:
5845       return expand_builtin_classify_type (arglist);
5846
5847     case BUILT_IN_CONSTANT_P:
5848       return const0_rtx;
5849
5850     case BUILT_IN_FRAME_ADDRESS:
5851     case BUILT_IN_RETURN_ADDRESS:
5852       return expand_builtin_frame_address (fndecl, arglist);
5853
5854     /* Returns the address of the area where the structure is returned.
5855        0 otherwise.  */
5856     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5857       if (arglist != 0
5858           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5859           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5860         return const0_rtx;
5861       else
5862         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5863
5864     case BUILT_IN_ALLOCA:
5865       target = expand_builtin_alloca (arglist, target);
5866       if (target)
5867         return target;
5868       break;
5869
5870     case BUILT_IN_STACK_SAVE:
5871       return expand_stack_save ();
5872
5873     case BUILT_IN_STACK_RESTORE:
5874       expand_stack_restore (TREE_VALUE (arglist));
5875       return const0_rtx;
5876
5877     case BUILT_IN_FFS:
5878     case BUILT_IN_FFSL:
5879     case BUILT_IN_FFSLL:
5880     case BUILT_IN_FFSIMAX:
5881       target = expand_builtin_unop (target_mode, arglist, target,
5882                                     subtarget, ffs_optab);
5883       if (target)
5884         return target;
5885       break;
5886
5887     case BUILT_IN_CLZ:
5888     case BUILT_IN_CLZL:
5889     case BUILT_IN_CLZLL:
5890     case BUILT_IN_CLZIMAX:
5891       target = expand_builtin_unop (target_mode, arglist, target,
5892                                     subtarget, clz_optab);
5893       if (target)
5894         return target;
5895       break;
5896
5897     case BUILT_IN_CTZ:
5898     case BUILT_IN_CTZL:
5899     case BUILT_IN_CTZLL:
5900     case BUILT_IN_CTZIMAX:
5901       target = expand_builtin_unop (target_mode, arglist, target,
5902                                     subtarget, ctz_optab);
5903       if (target)
5904         return target;
5905       break;
5906
5907     case BUILT_IN_POPCOUNT:
5908     case BUILT_IN_POPCOUNTL:
5909     case BUILT_IN_POPCOUNTLL:
5910     case BUILT_IN_POPCOUNTIMAX:
5911       target = expand_builtin_unop (target_mode, arglist, target,
5912                                     subtarget, popcount_optab);
5913       if (target)
5914         return target;
5915       break;
5916
5917     case BUILT_IN_PARITY:
5918     case BUILT_IN_PARITYL:
5919     case BUILT_IN_PARITYLL:
5920     case BUILT_IN_PARITYIMAX:
5921       target = expand_builtin_unop (target_mode, arglist, target,
5922                                     subtarget, parity_optab);
5923       if (target)
5924         return target;
5925       break;
5926
5927     case BUILT_IN_STRLEN:
5928       target = expand_builtin_strlen (arglist, target, target_mode);
5929       if (target)
5930         return target;
5931       break;
5932
5933     case BUILT_IN_STRCPY:
5934       target = expand_builtin_strcpy (fndecl, arglist, target, mode);
5935       if (target)
5936         return target;
5937       break;
5938
5939     case BUILT_IN_STRNCPY:
5940       target = expand_builtin_strncpy (exp, target, mode);
5941       if (target)
5942         return target;
5943       break;
5944
5945     case BUILT_IN_STPCPY:
5946       target = expand_builtin_stpcpy (exp, target, mode);
5947       if (target)
5948         return target;
5949       break;
5950
5951     case BUILT_IN_STRCAT:
5952       target = expand_builtin_strcat (fndecl, arglist, target, mode);
5953       if (target)
5954         return target;
5955       break;
5956
5957     case BUILT_IN_STRNCAT:
5958       target = expand_builtin_strncat (arglist, target, mode);
5959       if (target)
5960         return target;
5961       break;
5962
5963     case BUILT_IN_STRSPN:
5964       target = expand_builtin_strspn (arglist, target, mode);
5965       if (target)
5966         return target;
5967       break;
5968
5969     case BUILT_IN_STRCSPN:
5970       target = expand_builtin_strcspn (arglist, target, mode);
5971       if (target)
5972         return target;
5973       break;
5974
5975     case BUILT_IN_STRSTR:
5976       target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5977       if (target)
5978         return target;
5979       break;
5980
5981     case BUILT_IN_STRPBRK:
5982       target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5983       if (target)
5984         return target;
5985       break;
5986
5987     case BUILT_IN_INDEX:
5988     case BUILT_IN_STRCHR:
5989       target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5990       if (target)
5991         return target;
5992       break;
5993
5994     case BUILT_IN_RINDEX:
5995     case BUILT_IN_STRRCHR:
5996       target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5997       if (target)
5998         return target;
5999       break;
6000
6001     case BUILT_IN_MEMCPY:
6002       target = expand_builtin_memcpy (exp, target, mode);
6003       if (target)
6004         return target;
6005       break;
6006
6007     case BUILT_IN_MEMPCPY:
6008       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
6009       if (target)
6010         return target;
6011       break;
6012
6013     case BUILT_IN_MEMMOVE:
6014       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target,
6015                                        mode, exp);
6016       if (target)
6017         return target;
6018       break;
6019
6020     case BUILT_IN_BCOPY:
6021       target = expand_builtin_bcopy (exp);
6022       if (target)
6023         return target;
6024       break;
6025
6026     case BUILT_IN_MEMSET:
6027       target = expand_builtin_memset (arglist, target, mode, exp);
6028       if (target)
6029         return target;
6030       break;
6031
6032     case BUILT_IN_BZERO:
6033       target = expand_builtin_bzero (exp);
6034       if (target)
6035         return target;
6036       break;
6037
6038     case BUILT_IN_STRCMP:
6039       target = expand_builtin_strcmp (exp, target, mode);
6040       if (target)
6041         return target;
6042       break;
6043
6044     case BUILT_IN_STRNCMP:
6045       target = expand_builtin_strncmp (exp, target, mode);
6046       if (target)
6047         return target;
6048       break;
6049
6050     case BUILT_IN_BCMP:
6051     case BUILT_IN_MEMCMP:
6052       target = expand_builtin_memcmp (exp, arglist, target, mode);
6053       if (target)
6054         return target;
6055       break;
6056
6057     case BUILT_IN_SETJMP:
6058       target = expand_builtin_setjmp (arglist, target);
6059       if (target)
6060         return target;
6061       break;
6062
6063       /* __builtin_longjmp is passed a pointer to an array of five words.
6064          It's similar to the C library longjmp function but works with
6065          __builtin_setjmp above.  */
6066     case BUILT_IN_LONGJMP:
6067       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6068         break;
6069       else
6070         {
6071           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
6072                                       VOIDmode, 0);
6073           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
6074                                    NULL_RTX, VOIDmode, 0);
6075
6076           if (value != const1_rtx)
6077             {
6078               error ("%<__builtin_longjmp%> second argument must be 1");
6079               return const0_rtx;
6080             }
6081
6082           expand_builtin_longjmp (buf_addr, value);
6083           return const0_rtx;
6084         }
6085
6086     case BUILT_IN_NONLOCAL_GOTO:
6087       target = expand_builtin_nonlocal_goto (arglist);
6088       if (target)
6089         return target;
6090       break;
6091
6092       /* This updates the setjmp buffer that is its argument with the value
6093          of the current stack pointer.  */
6094     case BUILT_IN_UPDATE_SETJMP_BUF:
6095       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6096         {
6097           rtx buf_addr
6098             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
6099
6100           expand_builtin_update_setjmp_buf (buf_addr);
6101           return const0_rtx;
6102         }
6103       break;
6104
6105     case BUILT_IN_TRAP:
6106       expand_builtin_trap ();
6107       return const0_rtx;
6108
6109     case BUILT_IN_PRINTF:
6110       target = expand_builtin_printf (exp, target, mode, false);
6111       if (target)
6112         return target;
6113       break;
6114
6115     case BUILT_IN_PRINTF_UNLOCKED:
6116       target = expand_builtin_printf (exp, target, mode, true);
6117       if (target)
6118         return target;
6119       break;
6120
6121     case BUILT_IN_FPUTS:
6122       target = expand_builtin_fputs (arglist, target, false);
6123       if (target)
6124         return target;
6125       break;
6126     case BUILT_IN_FPUTS_UNLOCKED:
6127       target = expand_builtin_fputs (arglist, target, true);
6128       if (target)
6129         return target;
6130       break;
6131
6132     case BUILT_IN_FPRINTF:
6133       target = expand_builtin_fprintf (exp, target, mode, false);
6134       if (target)
6135         return target;
6136       break;
6137
6138     case BUILT_IN_FPRINTF_UNLOCKED:
6139       target = expand_builtin_fprintf (exp, target, mode, true);
6140       if (target)
6141         return target;
6142       break;
6143
6144     case BUILT_IN_SPRINTF:
6145       target = expand_builtin_sprintf (arglist, target, mode);
6146       if (target)
6147         return target;
6148       break;
6149
6150     case BUILT_IN_SIGNBIT:
6151     case BUILT_IN_SIGNBITF:
6152     case BUILT_IN_SIGNBITL:
6153       target = expand_builtin_signbit (exp, target);
6154       if (target)
6155         return target;
6156       break;
6157
6158       /* Various hooks for the DWARF 2 __throw routine.  */
6159     case BUILT_IN_UNWIND_INIT:
6160       expand_builtin_unwind_init ();
6161       return const0_rtx;
6162     case BUILT_IN_DWARF_CFA:
6163       return virtual_cfa_rtx;
6164 #ifdef DWARF2_UNWIND_INFO
6165     case BUILT_IN_DWARF_SP_COLUMN:
6166       return expand_builtin_dwarf_sp_column ();
6167     case BUILT_IN_INIT_DWARF_REG_SIZES:
6168       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6169       return const0_rtx;
6170 #endif
6171     case BUILT_IN_FROB_RETURN_ADDR:
6172       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6173     case BUILT_IN_EXTRACT_RETURN_ADDR:
6174       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6175     case BUILT_IN_EH_RETURN:
6176       expand_builtin_eh_return (TREE_VALUE (arglist),
6177                                 TREE_VALUE (TREE_CHAIN (arglist)));
6178       return const0_rtx;
6179 #ifdef EH_RETURN_DATA_REGNO
6180     case BUILT_IN_EH_RETURN_DATA_REGNO:
6181       return expand_builtin_eh_return_data_regno (arglist);
6182 #endif
6183     case BUILT_IN_EXTEND_POINTER:
6184       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6185
6186     case BUILT_IN_VA_START:
6187     case BUILT_IN_STDARG_START:
6188       return expand_builtin_va_start (arglist);
6189     case BUILT_IN_VA_END:
6190       return expand_builtin_va_end (arglist);
6191     case BUILT_IN_VA_COPY:
6192       return expand_builtin_va_copy (arglist);
6193     case BUILT_IN_EXPECT:
6194       return expand_builtin_expect (arglist, target);
6195     case BUILT_IN_PREFETCH:
6196       expand_builtin_prefetch (arglist);
6197       return const0_rtx;
6198
6199     case BUILT_IN_PROFILE_FUNC_ENTER:
6200       return expand_builtin_profile_func (false);
6201     case BUILT_IN_PROFILE_FUNC_EXIT:
6202       return expand_builtin_profile_func (true);
6203
6204     case BUILT_IN_INIT_TRAMPOLINE:
6205       return expand_builtin_init_trampoline (arglist);
6206     case BUILT_IN_ADJUST_TRAMPOLINE:
6207       return expand_builtin_adjust_trampoline (arglist);
6208
6209     case BUILT_IN_FORK:
6210     case BUILT_IN_EXECL:
6211     case BUILT_IN_EXECV:
6212     case BUILT_IN_EXECLP:
6213     case BUILT_IN_EXECLE:
6214     case BUILT_IN_EXECVP:
6215     case BUILT_IN_EXECVE:
6216       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6217       if (target)
6218         return target;
6219       break;
6220
6221     case BUILT_IN_FETCH_AND_ADD_1:
6222     case BUILT_IN_FETCH_AND_ADD_2:
6223     case BUILT_IN_FETCH_AND_ADD_4:
6224     case BUILT_IN_FETCH_AND_ADD_8:
6225       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_ADD_1);
6226       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6227                                               false, target, ignore);
6228       if (target)
6229         return target;
6230       break;
6231
6232     case BUILT_IN_FETCH_AND_SUB_1:
6233     case BUILT_IN_FETCH_AND_SUB_2:
6234     case BUILT_IN_FETCH_AND_SUB_4:
6235     case BUILT_IN_FETCH_AND_SUB_8:
6236       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_SUB_1);
6237       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6238                                               false, target, ignore);
6239       if (target)
6240         return target;
6241       break;
6242
6243     case BUILT_IN_FETCH_AND_OR_1:
6244     case BUILT_IN_FETCH_AND_OR_2:
6245     case BUILT_IN_FETCH_AND_OR_4:
6246     case BUILT_IN_FETCH_AND_OR_8:
6247       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_OR_1);
6248       target = expand_builtin_sync_operation (mode, arglist, IOR,
6249                                               false, target, ignore);
6250       if (target)
6251         return target;
6252       break;
6253
6254     case BUILT_IN_FETCH_AND_AND_1:
6255     case BUILT_IN_FETCH_AND_AND_2:
6256     case BUILT_IN_FETCH_AND_AND_4:
6257     case BUILT_IN_FETCH_AND_AND_8:
6258       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_AND_1);
6259       target = expand_builtin_sync_operation (mode, arglist, AND,
6260                                               false, target, ignore);
6261       if (target)
6262         return target;
6263       break;
6264
6265     case BUILT_IN_FETCH_AND_XOR_1:
6266     case BUILT_IN_FETCH_AND_XOR_2:
6267     case BUILT_IN_FETCH_AND_XOR_4:
6268     case BUILT_IN_FETCH_AND_XOR_8:
6269       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_XOR_1);
6270       target = expand_builtin_sync_operation (mode, arglist, XOR,
6271                                               false, target, ignore);
6272       if (target)
6273         return target;
6274       break;
6275
6276     case BUILT_IN_FETCH_AND_NAND_1:
6277     case BUILT_IN_FETCH_AND_NAND_2:
6278     case BUILT_IN_FETCH_AND_NAND_4:
6279     case BUILT_IN_FETCH_AND_NAND_8:
6280       mode = get_builtin_sync_mode (fcode - BUILT_IN_FETCH_AND_NAND_1);
6281       target = expand_builtin_sync_operation (mode, arglist, NOT,
6282                                               false, target, ignore);
6283       if (target)
6284         return target;
6285       break;
6286
6287     case BUILT_IN_ADD_AND_FETCH_1:
6288     case BUILT_IN_ADD_AND_FETCH_2:
6289     case BUILT_IN_ADD_AND_FETCH_4:
6290     case BUILT_IN_ADD_AND_FETCH_8:
6291       mode = get_builtin_sync_mode (fcode - BUILT_IN_ADD_AND_FETCH_1);
6292       target = expand_builtin_sync_operation (mode, arglist, PLUS,
6293                                               true, target, ignore);
6294       if (target)
6295         return target;
6296       break;
6297
6298     case BUILT_IN_SUB_AND_FETCH_1:
6299     case BUILT_IN_SUB_AND_FETCH_2:
6300     case BUILT_IN_SUB_AND_FETCH_4:
6301     case BUILT_IN_SUB_AND_FETCH_8:
6302       mode = get_builtin_sync_mode (fcode - BUILT_IN_SUB_AND_FETCH_1);
6303       target = expand_builtin_sync_operation (mode, arglist, MINUS,
6304                                               true, target, ignore);
6305       if (target)
6306         return target;
6307       break;
6308
6309     case BUILT_IN_OR_AND_FETCH_1:
6310     case BUILT_IN_OR_AND_FETCH_2:
6311     case BUILT_IN_OR_AND_FETCH_4:
6312     case BUILT_IN_OR_AND_FETCH_8:
6313       mode = get_builtin_sync_mode (fcode - BUILT_IN_OR_AND_FETCH_1);
6314       target = expand_builtin_sync_operation (mode, arglist, IOR,
6315                                               true, target, ignore);
6316       if (target)
6317         return target;
6318       break;
6319
6320     case BUILT_IN_AND_AND_FETCH_1:
6321     case BUILT_IN_AND_AND_FETCH_2:
6322     case BUILT_IN_AND_AND_FETCH_4:
6323     case BUILT_IN_AND_AND_FETCH_8:
6324       mode = get_builtin_sync_mode (fcode - BUILT_IN_AND_AND_FETCH_1);
6325       target = expand_builtin_sync_operation (mode, arglist, AND,
6326                                               true, target, ignore);
6327       if (target)
6328         return target;
6329       break;
6330
6331     case BUILT_IN_XOR_AND_FETCH_1:
6332     case BUILT_IN_XOR_AND_FETCH_2:
6333     case BUILT_IN_XOR_AND_FETCH_4:
6334     case BUILT_IN_XOR_AND_FETCH_8:
6335       mode = get_builtin_sync_mode (fcode - BUILT_IN_XOR_AND_FETCH_1);
6336       target = expand_builtin_sync_operation (mode, arglist, XOR,
6337                                               true, target, ignore);
6338       if (target)
6339         return target;
6340       break;
6341
6342     case BUILT_IN_NAND_AND_FETCH_1:
6343     case BUILT_IN_NAND_AND_FETCH_2:
6344     case BUILT_IN_NAND_AND_FETCH_4:
6345     case BUILT_IN_NAND_AND_FETCH_8:
6346       mode = get_builtin_sync_mode (fcode - BUILT_IN_NAND_AND_FETCH_1);
6347       target = expand_builtin_sync_operation (mode, arglist, NOT,
6348                                               true, target, ignore);
6349       if (target)
6350         return target;
6351       break;
6352
6353     case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
6354     case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
6355     case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
6356     case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
6357       if (mode == VOIDmode)
6358         mode = TYPE_MODE (boolean_type_node);
6359       if (!target || !register_operand (target, mode))
6360         target = gen_reg_rtx (mode);
6361
6362       mode = get_builtin_sync_mode (fcode - BUILT_IN_BOOL_COMPARE_AND_SWAP_1);
6363       target = expand_builtin_compare_and_swap (mode, arglist, true, target);
6364       if (target)
6365         return target;
6366       break;
6367
6368     case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
6369     case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
6370     case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
6371     case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
6372       mode = get_builtin_sync_mode (fcode - BUILT_IN_VAL_COMPARE_AND_SWAP_1);
6373       target = expand_builtin_compare_and_swap (mode, arglist, false, target);
6374       if (target)
6375         return target;
6376       break;
6377
6378     case BUILT_IN_LOCK_TEST_AND_SET_1:
6379     case BUILT_IN_LOCK_TEST_AND_SET_2:
6380     case BUILT_IN_LOCK_TEST_AND_SET_4:
6381     case BUILT_IN_LOCK_TEST_AND_SET_8:
6382       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_TEST_AND_SET_1);
6383       target = expand_builtin_lock_test_and_set (mode, arglist, target);
6384       if (target)
6385         return target;
6386       break;
6387
6388     case BUILT_IN_LOCK_RELEASE_1:
6389     case BUILT_IN_LOCK_RELEASE_2:
6390     case BUILT_IN_LOCK_RELEASE_4:
6391     case BUILT_IN_LOCK_RELEASE_8:
6392       mode = get_builtin_sync_mode (fcode - BUILT_IN_LOCK_RELEASE_1);
6393       expand_builtin_lock_release (mode, arglist);
6394       return const0_rtx;
6395
6396     case BUILT_IN_SYNCHRONIZE:
6397       expand_builtin_synchronize ();
6398       return const0_rtx;
6399
6400     case BUILT_IN_OBJECT_SIZE:
6401       return expand_builtin_object_size (exp);
6402
6403     case BUILT_IN_MEMCPY_CHK:
6404     case BUILT_IN_MEMPCPY_CHK:
6405     case BUILT_IN_MEMMOVE_CHK:
6406     case BUILT_IN_MEMSET_CHK:
6407       target = expand_builtin_memory_chk (exp, target, mode, fcode);
6408       if (target)
6409         return target;
6410       break;
6411
6412     case BUILT_IN_STRCPY_CHK:
6413     case BUILT_IN_STPCPY_CHK:
6414     case BUILT_IN_STRNCPY_CHK:
6415     case BUILT_IN_STRCAT_CHK:
6416     case BUILT_IN_SNPRINTF_CHK:
6417     case BUILT_IN_VSNPRINTF_CHK:
6418       maybe_emit_chk_warning (exp, fcode);
6419       break;
6420
6421     case BUILT_IN_SPRINTF_CHK:
6422     case BUILT_IN_VSPRINTF_CHK:
6423       maybe_emit_sprintf_chk_warning (exp, fcode);
6424       break;
6425
6426     default:    /* just do library call, if unknown builtin */
6427       break;
6428     }
6429
6430   /* The switch statement above can drop through to cause the function
6431      to be called normally.  */
6432   return expand_call (exp, target, ignore);
6433 }
6434
6435 /* Determine whether a tree node represents a call to a built-in
6436    function.  If the tree T is a call to a built-in function with
6437    the right number of arguments of the appropriate types, return
6438    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6439    Otherwise the return value is END_BUILTINS.  */
6440
6441 enum built_in_function
6442 builtin_mathfn_code (tree t)
6443 {
6444   tree fndecl, arglist, parmlist;
6445   tree argtype, parmtype;
6446
6447   if (TREE_CODE (t) != CALL_EXPR
6448       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6449     return END_BUILTINS;
6450
6451   fndecl = get_callee_fndecl (t);
6452   if (fndecl == NULL_TREE
6453       || TREE_CODE (fndecl) != FUNCTION_DECL
6454       || ! DECL_BUILT_IN (fndecl)
6455       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6456     return END_BUILTINS;
6457
6458   arglist = TREE_OPERAND (t, 1);
6459   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6460   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6461     {
6462       /* If a function doesn't take a variable number of arguments,
6463          the last element in the list will have type `void'.  */
6464       parmtype = TREE_VALUE (parmlist);
6465       if (VOID_TYPE_P (parmtype))
6466         {
6467           if (arglist)
6468             return END_BUILTINS;
6469           return DECL_FUNCTION_CODE (fndecl);
6470         }
6471
6472       if (! arglist)
6473         return END_BUILTINS;
6474
6475       argtype = TREE_TYPE (TREE_VALUE (arglist));
6476
6477       if (SCALAR_FLOAT_TYPE_P (parmtype))
6478         {
6479           if (! SCALAR_FLOAT_TYPE_P (argtype))
6480             return END_BUILTINS;
6481         }
6482       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6483         {
6484           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6485             return END_BUILTINS;
6486         }
6487       else if (POINTER_TYPE_P (parmtype))
6488         {
6489           if (! POINTER_TYPE_P (argtype))
6490             return END_BUILTINS;
6491         }
6492       else if (INTEGRAL_TYPE_P (parmtype))
6493         {
6494           if (! INTEGRAL_TYPE_P (argtype))
6495             return END_BUILTINS;
6496         }
6497       else
6498         return END_BUILTINS;
6499
6500       arglist = TREE_CHAIN (arglist);
6501     }
6502
6503   /* Variable-length argument list.  */
6504   return DECL_FUNCTION_CODE (fndecl);
6505 }
6506
6507 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6508    constant.  ARGLIST is the argument list of the call.  */
6509
6510 static tree
6511 fold_builtin_constant_p (tree arglist)
6512 {
6513   if (arglist == 0)
6514     return 0;
6515
6516   arglist = TREE_VALUE (arglist);
6517
6518   /* We return 1 for a numeric type that's known to be a constant
6519      value at compile-time or for an aggregate type that's a
6520      literal constant.  */
6521   STRIP_NOPS (arglist);
6522
6523   /* If we know this is a constant, emit the constant of one.  */
6524   if (CONSTANT_CLASS_P (arglist)
6525       || (TREE_CODE (arglist) == CONSTRUCTOR
6526           && TREE_CONSTANT (arglist)))
6527     return integer_one_node;
6528   if (TREE_CODE (arglist) == ADDR_EXPR)
6529     {
6530        tree op = TREE_OPERAND (arglist, 0);
6531        if (TREE_CODE (op) == STRING_CST
6532            || (TREE_CODE (op) == ARRAY_REF
6533                && integer_zerop (TREE_OPERAND (op, 1))
6534                && TREE_CODE (TREE_OPERAND (op, 0)) == STRING_CST))
6535          return integer_one_node;
6536     }
6537
6538   /* If this expression has side effects, show we don't know it to be a
6539      constant.  Likewise if it's a pointer or aggregate type since in
6540      those case we only want literals, since those are only optimized
6541      when generating RTL, not later.
6542      And finally, if we are compiling an initializer, not code, we
6543      need to return a definite result now; there's not going to be any
6544      more optimization done.  */
6545   if (TREE_SIDE_EFFECTS (arglist)
6546       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6547       || POINTER_TYPE_P (TREE_TYPE (arglist))
6548       || cfun == 0)
6549     return integer_zero_node;
6550
6551   return 0;
6552 }
6553
6554 /* Fold a call to __builtin_expect, if we expect that a comparison against
6555    the argument will fold to a constant.  In practice, this means a true
6556    constant or the address of a non-weak symbol.  ARGLIST is the argument
6557    list of the call.  */
6558
6559 static tree
6560 fold_builtin_expect (tree arglist)
6561 {
6562   tree arg, inner;
6563
6564   if (arglist == 0)
6565     return 0;
6566
6567   arg = TREE_VALUE (arglist);
6568
6569   /* If the argument isn't invariant, then there's nothing we can do.  */
6570   if (!TREE_INVARIANT (arg))
6571     return 0;
6572
6573   /* If we're looking at an address of a weak decl, then do not fold.  */
6574   inner = arg;
6575   STRIP_NOPS (inner);
6576   if (TREE_CODE (inner) == ADDR_EXPR)
6577     {
6578       do
6579         {
6580           inner = TREE_OPERAND (inner, 0);
6581         }
6582       while (TREE_CODE (inner) == COMPONENT_REF
6583              || TREE_CODE (inner) == ARRAY_REF);
6584       if (DECL_P (inner) && DECL_WEAK (inner))
6585         return 0;
6586     }
6587
6588   /* Otherwise, ARG already has the proper type for the return value.  */
6589   return arg;
6590 }
6591
6592 /* Fold a call to __builtin_classify_type.  */
6593
6594 static tree
6595 fold_builtin_classify_type (tree arglist)
6596 {
6597   if (arglist == 0)
6598     return build_int_cst (NULL_TREE, no_type_class);
6599
6600   return build_int_cst (NULL_TREE,
6601                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
6602 }
6603
6604 /* Fold a call to __builtin_strlen.  */
6605
6606 static tree
6607 fold_builtin_strlen (tree arglist)
6608 {
6609   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6610     return NULL_TREE;
6611   else
6612     {
6613       tree len = c_strlen (TREE_VALUE (arglist), 0);
6614
6615       if (len)
6616         {
6617           /* Convert from the internal "sizetype" type to "size_t".  */
6618           if (size_type_node)
6619             len = fold_convert (size_type_node, len);
6620           return len;
6621         }
6622
6623       return NULL_TREE;
6624     }
6625 }
6626
6627 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6628
6629 static tree
6630 fold_builtin_inf (tree type, int warn)
6631 {
6632   REAL_VALUE_TYPE real;
6633
6634   /* __builtin_inff is intended to be usable to define INFINITY on all
6635      targets.  If an infinity is not available, INFINITY expands "to a
6636      positive constant of type float that overflows at translation
6637      time", footnote "In this case, using INFINITY will violate the
6638      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
6639      Thus we pedwarn to ensure this constraint violation is
6640      diagnosed.  */
6641   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6642     pedwarn ("target format does not support infinity");
6643
6644   real_inf (&real);
6645   return build_real (type, real);
6646 }
6647
6648 /* Fold a call to __builtin_nan or __builtin_nans.  */
6649
6650 static tree
6651 fold_builtin_nan (tree arglist, tree type, int quiet)
6652 {
6653   REAL_VALUE_TYPE real;
6654   const char *str;
6655
6656   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6657     return 0;
6658   str = c_getstr (TREE_VALUE (arglist));
6659   if (!str)
6660     return 0;
6661
6662   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6663     return 0;
6664
6665   return build_real (type, real);
6666 }
6667
6668 /* Return true if the floating point expression T has an integer value.
6669    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6670
6671 static bool
6672 integer_valued_real_p (tree t)
6673 {
6674   switch (TREE_CODE (t))
6675     {
6676     case FLOAT_EXPR:
6677       return true;
6678
6679     case ABS_EXPR:
6680     case SAVE_EXPR:
6681     case NON_LVALUE_EXPR:
6682       return integer_valued_real_p (TREE_OPERAND (t, 0));
6683
6684     case COMPOUND_EXPR:
6685     case MODIFY_EXPR:
6686     case BIND_EXPR:
6687       return integer_valued_real_p (TREE_OPERAND (t, 1));
6688
6689     case PLUS_EXPR:
6690     case MINUS_EXPR:
6691     case MULT_EXPR:
6692     case MIN_EXPR:
6693     case MAX_EXPR:
6694       return integer_valued_real_p (TREE_OPERAND (t, 0))
6695              && integer_valued_real_p (TREE_OPERAND (t, 1));
6696
6697     case COND_EXPR:
6698       return integer_valued_real_p (TREE_OPERAND (t, 1))
6699              && integer_valued_real_p (TREE_OPERAND (t, 2));
6700
6701     case REAL_CST:
6702       if (! TREE_CONSTANT_OVERFLOW (t))
6703       {
6704         REAL_VALUE_TYPE c, cint;
6705
6706         c = TREE_REAL_CST (t);
6707         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6708         return real_identical (&c, &cint);
6709       }
6710       break;
6711
6712     case NOP_EXPR:
6713       {
6714         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6715         if (TREE_CODE (type) == INTEGER_TYPE)
6716           return true;
6717         if (TREE_CODE (type) == REAL_TYPE)
6718           return integer_valued_real_p (TREE_OPERAND (t, 0));
6719         break;
6720       }
6721
6722     case CALL_EXPR:
6723       switch (builtin_mathfn_code (t))
6724         {
6725         case BUILT_IN_CEIL:
6726         case BUILT_IN_CEILF:
6727         case BUILT_IN_CEILL:
6728         case BUILT_IN_FLOOR:
6729         case BUILT_IN_FLOORF:
6730         case BUILT_IN_FLOORL:
6731         case BUILT_IN_NEARBYINT:
6732         case BUILT_IN_NEARBYINTF:
6733         case BUILT_IN_NEARBYINTL:
6734         case BUILT_IN_RINT:
6735         case BUILT_IN_RINTF:
6736         case BUILT_IN_RINTL:
6737         case BUILT_IN_ROUND:
6738         case BUILT_IN_ROUNDF:
6739         case BUILT_IN_ROUNDL:
6740         case BUILT_IN_TRUNC:
6741         case BUILT_IN_TRUNCF:
6742         case BUILT_IN_TRUNCL:
6743           return true;
6744
6745         default:
6746           break;
6747         }
6748       break;
6749
6750     default:
6751       break;
6752     }
6753   return false;
6754 }
6755
6756 /* EXP is assumed to be builtin call where truncation can be propagated
6757    across (for instance floor((double)f) == (double)floorf (f).
6758    Do the transformation.  */
6759
6760 static tree
6761 fold_trunc_transparent_mathfn (tree fndecl, tree arglist)
6762 {
6763   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6764   tree arg;
6765
6766   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6767     return 0;
6768
6769   arg = TREE_VALUE (arglist);
6770   /* Integer rounding functions are idempotent.  */
6771   if (fcode == builtin_mathfn_code (arg))
6772     return arg;
6773
6774   /* If argument is already integer valued, and we don't need to worry
6775      about setting errno, there's no need to perform rounding.  */
6776   if (! flag_errno_math && integer_valued_real_p (arg))
6777     return arg;
6778
6779   if (optimize)
6780     {
6781       tree arg0 = strip_float_extensions (arg);
6782       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6783       tree newtype = TREE_TYPE (arg0);
6784       tree decl;
6785
6786       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6787           && (decl = mathfn_built_in (newtype, fcode)))
6788         {
6789           arglist =
6790             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6791           return fold_convert (ftype,
6792                                build_function_call_expr (decl, arglist));
6793         }
6794     }
6795   return 0;
6796 }
6797
6798 /* EXP is assumed to be builtin call which can narrow the FP type of
6799    the argument, for instance lround((double)f) -> lroundf (f).  */
6800
6801 static tree
6802 fold_fixed_mathfn (tree fndecl, tree arglist)
6803 {
6804   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6805   tree arg;
6806
6807   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6808     return 0;
6809
6810   arg = TREE_VALUE (arglist);
6811
6812   /* If argument is already integer valued, and we don't need to worry
6813      about setting errno, there's no need to perform rounding.  */
6814   if (! flag_errno_math && integer_valued_real_p (arg))
6815     return fold_build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg);
6816
6817   if (optimize)
6818     {
6819       tree ftype = TREE_TYPE (arg);
6820       tree arg0 = strip_float_extensions (arg);
6821       tree newtype = TREE_TYPE (arg0);
6822       tree decl;
6823
6824       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6825           && (decl = mathfn_built_in (newtype, fcode)))
6826         {
6827           arglist =
6828             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6829           return build_function_call_expr (decl, arglist);
6830         }
6831     }
6832   return 0;
6833 }
6834
6835 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6836    is the argument list and TYPE is the return type.  Return
6837    NULL_TREE if no if no simplification can be made.  */
6838
6839 static tree
6840 fold_builtin_cabs (tree arglist, tree type)
6841 {
6842   tree arg;
6843
6844   if (!arglist || TREE_CHAIN (arglist))
6845     return NULL_TREE;
6846
6847   arg = TREE_VALUE (arglist);
6848   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6849       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6850     return NULL_TREE;
6851
6852   /* Evaluate cabs of a constant at compile-time.  */
6853   if (flag_unsafe_math_optimizations
6854       && TREE_CODE (arg) == COMPLEX_CST
6855       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6856       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6857       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6858       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6859     {
6860       REAL_VALUE_TYPE r, i;
6861
6862       r = TREE_REAL_CST (TREE_REALPART (arg));
6863       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6864
6865       real_arithmetic (&r, MULT_EXPR, &r, &r);
6866       real_arithmetic (&i, MULT_EXPR, &i, &i);
6867       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6868       if (real_sqrt (&r, TYPE_MODE (type), &r)
6869           || ! flag_trapping_math)
6870         return build_real (type, r);
6871     }
6872
6873   /* If either part is zero, cabs is fabs of the other.  */
6874   if (TREE_CODE (arg) == COMPLEX_EXPR
6875       && real_zerop (TREE_OPERAND (arg, 0)))
6876     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1));
6877   if (TREE_CODE (arg) == COMPLEX_EXPR
6878       && real_zerop (TREE_OPERAND (arg, 1)))
6879     return fold_build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0));
6880
6881   /* Don't do this when optimizing for size.  */
6882   if (flag_unsafe_math_optimizations
6883       && optimize && !optimize_size)
6884     {
6885       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6886
6887       if (sqrtfn != NULL_TREE)
6888         {
6889           tree rpart, ipart, result, arglist;
6890
6891           arg = builtin_save_expr (arg);
6892
6893           rpart = fold_build1 (REALPART_EXPR, type, arg);
6894           ipart = fold_build1 (IMAGPART_EXPR, type, arg);
6895
6896           rpart = builtin_save_expr (rpart);
6897           ipart = builtin_save_expr (ipart);
6898
6899           result = fold_build2 (PLUS_EXPR, type,
6900                                 fold_build2 (MULT_EXPR, type,
6901                                              rpart, rpart),
6902                                 fold_build2 (MULT_EXPR, type,
6903                                              ipart, ipart));
6904
6905           arglist = build_tree_list (NULL_TREE, result);
6906           return build_function_call_expr (sqrtfn, arglist);
6907         }
6908     }
6909
6910   return NULL_TREE;
6911 }
6912
6913 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6914    NULL_TREE if no simplification can be made.  */
6915
6916 static tree
6917 fold_builtin_sqrt (tree arglist, tree type)
6918 {
6919
6920   enum built_in_function fcode;
6921   tree arg = TREE_VALUE (arglist);
6922
6923   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6924     return NULL_TREE;
6925
6926   /* Optimize sqrt of constant value.  */
6927   if (TREE_CODE (arg) == REAL_CST
6928       && ! TREE_CONSTANT_OVERFLOW (arg))
6929     {
6930       REAL_VALUE_TYPE r, x;
6931
6932       x = TREE_REAL_CST (arg);
6933       if (real_sqrt (&r, TYPE_MODE (type), &x)
6934           || (!flag_trapping_math && !flag_errno_math))
6935         return build_real (type, r);
6936     }
6937
6938   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6939   fcode = builtin_mathfn_code (arg);
6940   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6941     {
6942       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6943       arg = fold_build2 (MULT_EXPR, type,
6944                          TREE_VALUE (TREE_OPERAND (arg, 1)),
6945                          build_real (type, dconsthalf));
6946       arglist = build_tree_list (NULL_TREE, arg);
6947       return build_function_call_expr (expfn, arglist);
6948     }
6949
6950   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6951   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6952     {
6953       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6954
6955       if (powfn)
6956         {
6957           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6958           tree tree_root;
6959           /* The inner root was either sqrt or cbrt.  */
6960           REAL_VALUE_TYPE dconstroot =
6961             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6962
6963           /* Adjust for the outer root.  */
6964           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6965           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6966           tree_root = build_real (type, dconstroot);
6967           arglist = tree_cons (NULL_TREE, arg0,
6968                                build_tree_list (NULL_TREE, tree_root));
6969           return build_function_call_expr (powfn, arglist);
6970         }
6971     }
6972
6973   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
6974   if (flag_unsafe_math_optimizations
6975       && (fcode == BUILT_IN_POW
6976           || fcode == BUILT_IN_POWF
6977           || fcode == BUILT_IN_POWL))
6978     {
6979       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6980       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6981       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6982       tree narg1;
6983       if (!tree_expr_nonnegative_p (arg0))
6984         arg0 = build1 (ABS_EXPR, type, arg0);
6985       narg1 = fold_build2 (MULT_EXPR, type, arg1,
6986                            build_real (type, dconsthalf));
6987       arglist = tree_cons (NULL_TREE, arg0,
6988                            build_tree_list (NULL_TREE, narg1));
6989       return build_function_call_expr (powfn, arglist);
6990     }
6991
6992   return NULL_TREE;
6993 }
6994
6995 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6996    NULL_TREE if no simplification can be made.  */
6997 static tree
6998 fold_builtin_cbrt (tree arglist, tree type)
6999 {
7000   tree arg = TREE_VALUE (arglist);
7001   const enum built_in_function fcode = builtin_mathfn_code (arg);
7002
7003   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7004     return NULL_TREE;
7005
7006   /* Optimize cbrt of constant value.  */
7007   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7008     return arg;
7009
7010   if (flag_unsafe_math_optimizations)
7011     {
7012       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7013       if (BUILTIN_EXPONENT_P (fcode))
7014         {
7015           tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7016           const REAL_VALUE_TYPE third_trunc =
7017             real_value_truncate (TYPE_MODE (type), dconstthird);
7018           arg = fold_build2 (MULT_EXPR, type,
7019                              TREE_VALUE (TREE_OPERAND (arg, 1)),
7020                              build_real (type, third_trunc));
7021           arglist = build_tree_list (NULL_TREE, arg);
7022           return build_function_call_expr (expfn, arglist);
7023         }
7024
7025       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7026       if (BUILTIN_SQRT_P (fcode))
7027         {
7028           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7029
7030           if (powfn)
7031             {
7032               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7033               tree tree_root;
7034               REAL_VALUE_TYPE dconstroot = dconstthird;
7035
7036               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7037               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7038               tree_root = build_real (type, dconstroot);
7039               arglist = tree_cons (NULL_TREE, arg0,
7040                                    build_tree_list (NULL_TREE, tree_root));
7041               return build_function_call_expr (powfn, arglist);
7042             }
7043         }
7044
7045       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
7046       if (BUILTIN_CBRT_P (fcode))
7047         {
7048           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7049           if (tree_expr_nonnegative_p (arg0))
7050             {
7051               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7052
7053               if (powfn)
7054                 {
7055                   tree tree_root;
7056                   REAL_VALUE_TYPE dconstroot;
7057               
7058                   real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
7059                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7060                   tree_root = build_real (type, dconstroot);
7061                   arglist = tree_cons (NULL_TREE, arg0,
7062                                        build_tree_list (NULL_TREE, tree_root));
7063                   return build_function_call_expr (powfn, arglist);
7064                 }
7065             }
7066         }
7067       
7068       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
7069       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7070           || fcode == BUILT_IN_POWL)
7071         {
7072           tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
7073           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7074           if (tree_expr_nonnegative_p (arg00))
7075             {
7076               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7077               const REAL_VALUE_TYPE dconstroot
7078                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7079               tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
7080                                          build_real (type, dconstroot));
7081               arglist = tree_cons (NULL_TREE, arg00,
7082                                    build_tree_list (NULL_TREE, narg01));
7083               return build_function_call_expr (powfn, arglist);
7084             }
7085         }
7086     }
7087   return NULL_TREE;
7088 }
7089
7090 /* Fold function call to builtin sin, sinf, or sinl.  Return
7091    NULL_TREE if no simplification can be made.  */
7092 static tree
7093 fold_builtin_sin (tree arglist)
7094 {
7095   tree arg = TREE_VALUE (arglist);
7096
7097   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7098     return NULL_TREE;
7099
7100   /* Optimize sin (0.0) = 0.0.  */
7101   if (real_zerop (arg))
7102     return arg;
7103
7104   return NULL_TREE;
7105 }
7106
7107 /* Fold function call to builtin cos, cosf, or cosl.  Return
7108    NULL_TREE if no simplification can be made.  */
7109 static tree
7110 fold_builtin_cos (tree arglist, tree type, tree fndecl)
7111 {
7112   tree arg = TREE_VALUE (arglist);
7113
7114   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7115     return NULL_TREE;
7116
7117   /* Optimize cos (0.0) = 1.0.  */
7118   if (real_zerop (arg))
7119     return build_real (type, dconst1);
7120
7121   /* Optimize cos(-x) into cos (x).  */
7122   if (TREE_CODE (arg) == NEGATE_EXPR)
7123     {
7124       tree args = build_tree_list (NULL_TREE,
7125                                    TREE_OPERAND (arg, 0));
7126       return build_function_call_expr (fndecl, args);
7127     }
7128
7129   return NULL_TREE;
7130 }
7131
7132 /* Fold function call to builtin tan, tanf, or tanl.  Return
7133    NULL_TREE if no simplification can be made.  */
7134 static tree
7135 fold_builtin_tan (tree arglist)
7136 {
7137   enum built_in_function fcode;
7138   tree arg = TREE_VALUE (arglist);
7139
7140   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7141     return NULL_TREE;
7142
7143   /* Optimize tan(0.0) = 0.0.  */
7144   if (real_zerop (arg))
7145     return arg;
7146
7147   /* Optimize tan(atan(x)) = x.  */
7148   fcode = builtin_mathfn_code (arg);
7149   if (flag_unsafe_math_optimizations
7150       && (fcode == BUILT_IN_ATAN
7151           || fcode == BUILT_IN_ATANF
7152           || fcode == BUILT_IN_ATANL))
7153     return TREE_VALUE (TREE_OPERAND (arg, 1));
7154
7155   return NULL_TREE;
7156 }
7157
7158 /* Fold function call to builtin atan, atanf, or atanl.  Return
7159    NULL_TREE if no simplification can be made.  */
7160
7161 static tree
7162 fold_builtin_atan (tree arglist, tree type)
7163 {
7164
7165   tree arg = TREE_VALUE (arglist);
7166
7167   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7168     return NULL_TREE;
7169
7170   /* Optimize atan(0.0) = 0.0.  */
7171   if (real_zerop (arg))
7172     return arg;
7173
7174   /* Optimize atan(1.0) = pi/4.  */
7175   if (real_onep (arg))
7176     {
7177       REAL_VALUE_TYPE cst;
7178
7179       real_convert (&cst, TYPE_MODE (type), &dconstpi);
7180       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
7181       return build_real (type, cst);
7182     }
7183
7184   return NULL_TREE;
7185 }
7186
7187 /* Fold function call to builtin trunc, truncf or truncl.  Return
7188    NULL_TREE if no simplification can be made.  */
7189
7190 static tree
7191 fold_builtin_trunc (tree fndecl, tree arglist)
7192 {
7193   tree arg;
7194
7195   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7196     return 0;
7197
7198   /* Optimize trunc of constant value.  */
7199   arg = TREE_VALUE (arglist);
7200   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7201     {
7202       REAL_VALUE_TYPE r, x;
7203       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7204
7205       x = TREE_REAL_CST (arg);
7206       real_trunc (&r, TYPE_MODE (type), &x);
7207       return build_real (type, r);
7208     }
7209
7210   return fold_trunc_transparent_mathfn (fndecl, arglist);
7211 }
7212
7213 /* Fold function call to builtin floor, floorf or floorl.  Return
7214    NULL_TREE if no simplification can be made.  */
7215
7216 static tree
7217 fold_builtin_floor (tree fndecl, tree arglist)
7218 {
7219   tree arg;
7220
7221   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7222     return 0;
7223
7224   /* Optimize floor of constant value.  */
7225   arg = TREE_VALUE (arglist);
7226   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7227     {
7228       REAL_VALUE_TYPE x;
7229
7230       x = TREE_REAL_CST (arg);
7231       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7232         {
7233           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7234           REAL_VALUE_TYPE r;
7235
7236           real_floor (&r, TYPE_MODE (type), &x);
7237           return build_real (type, r);
7238         }
7239     }
7240
7241   return fold_trunc_transparent_mathfn (fndecl, arglist);
7242 }
7243
7244 /* Fold function call to builtin ceil, ceilf or ceill.  Return
7245    NULL_TREE if no simplification can be made.  */
7246
7247 static tree
7248 fold_builtin_ceil (tree fndecl, tree arglist)
7249 {
7250   tree arg;
7251
7252   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7253     return 0;
7254
7255   /* Optimize ceil of constant value.  */
7256   arg = TREE_VALUE (arglist);
7257   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7258     {
7259       REAL_VALUE_TYPE x;
7260
7261       x = TREE_REAL_CST (arg);
7262       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7263         {
7264           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7265           REAL_VALUE_TYPE r;
7266
7267           real_ceil (&r, TYPE_MODE (type), &x);
7268           return build_real (type, r);
7269         }
7270     }
7271
7272   return fold_trunc_transparent_mathfn (fndecl, arglist);
7273 }
7274
7275 /* Fold function call to builtin round, roundf or roundl.  Return
7276    NULL_TREE if no simplification can be made.  */
7277
7278 static tree
7279 fold_builtin_round (tree fndecl, tree arglist)
7280 {
7281   tree arg;
7282
7283   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7284     return 0;
7285
7286   /* Optimize round of constant value.  */
7287   arg = TREE_VALUE (arglist);
7288   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7289     {
7290       REAL_VALUE_TYPE x;
7291
7292       x = TREE_REAL_CST (arg);
7293       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
7294         {
7295           tree type = TREE_TYPE (TREE_TYPE (fndecl));
7296           REAL_VALUE_TYPE r;
7297
7298           real_round (&r, TYPE_MODE (type), &x);
7299           return build_real (type, r);
7300         }
7301     }
7302
7303   return fold_trunc_transparent_mathfn (fndecl, arglist);
7304 }
7305
7306 /* Fold function call to builtin lround, lroundf or lroundl (or the
7307    corresponding long long versions) and other rounding functions.
7308    Return NULL_TREE if no simplification can be made.  */
7309
7310 static tree
7311 fold_builtin_int_roundingfn (tree fndecl, tree arglist)
7312 {
7313   tree arg;
7314
7315   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7316     return 0;
7317
7318   /* Optimize lround of constant value.  */
7319   arg = TREE_VALUE (arglist);
7320   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7321     {
7322       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
7323
7324       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
7325         {
7326           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
7327           tree ftype = TREE_TYPE (arg), result;
7328           HOST_WIDE_INT hi, lo;
7329           REAL_VALUE_TYPE r;
7330
7331           switch (DECL_FUNCTION_CODE (fndecl))
7332             {
7333             case BUILT_IN_LFLOOR:
7334             case BUILT_IN_LFLOORF:
7335             case BUILT_IN_LFLOORL:
7336             case BUILT_IN_LLFLOOR:
7337             case BUILT_IN_LLFLOORF:
7338             case BUILT_IN_LLFLOORL:
7339               real_floor (&r, TYPE_MODE (ftype), &x);
7340               break;
7341
7342             case BUILT_IN_LCEIL:
7343             case BUILT_IN_LCEILF:
7344             case BUILT_IN_LCEILL:
7345             case BUILT_IN_LLCEIL:
7346             case BUILT_IN_LLCEILF:
7347             case BUILT_IN_LLCEILL:
7348               real_ceil (&r, TYPE_MODE (ftype), &x);
7349               break;
7350
7351             case BUILT_IN_LROUND:
7352             case BUILT_IN_LROUNDF:
7353             case BUILT_IN_LROUNDL:
7354             case BUILT_IN_LLROUND:
7355             case BUILT_IN_LLROUNDF:
7356             case BUILT_IN_LLROUNDL:
7357               real_round (&r, TYPE_MODE (ftype), &x);
7358               break;
7359
7360             default:
7361               gcc_unreachable ();
7362             }
7363
7364           REAL_VALUE_TO_INT (&lo, &hi, r);
7365           result = build_int_cst_wide (NULL_TREE, lo, hi);
7366           if (int_fits_type_p (result, itype))
7367             return fold_convert (itype, result);
7368         }
7369     }
7370
7371   return fold_fixed_mathfn (fndecl, arglist);
7372 }
7373
7374 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
7375    and their long and long long variants (i.e. ffsl and ffsll).
7376    Return NULL_TREE if no simplification can be made.  */
7377
7378 static tree
7379 fold_builtin_bitop (tree fndecl, tree arglist)
7380 {
7381   tree arg;
7382
7383   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7384     return NULL_TREE;
7385
7386   /* Optimize for constant argument.  */
7387   arg = TREE_VALUE (arglist);
7388   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
7389     {
7390       HOST_WIDE_INT hi, width, result;
7391       unsigned HOST_WIDE_INT lo;
7392       tree type;
7393
7394       type = TREE_TYPE (arg);
7395       width = TYPE_PRECISION (type);
7396       lo = TREE_INT_CST_LOW (arg);
7397
7398       /* Clear all the bits that are beyond the type's precision.  */
7399       if (width > HOST_BITS_PER_WIDE_INT)
7400         {
7401           hi = TREE_INT_CST_HIGH (arg);
7402           if (width < 2 * HOST_BITS_PER_WIDE_INT)
7403             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
7404         }
7405       else
7406         {
7407           hi = 0;
7408           if (width < HOST_BITS_PER_WIDE_INT)
7409             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
7410         }
7411
7412       switch (DECL_FUNCTION_CODE (fndecl))
7413         {
7414         case BUILT_IN_FFS:
7415         case BUILT_IN_FFSL:
7416         case BUILT_IN_FFSLL:
7417           if (lo != 0)
7418             result = exact_log2 (lo & -lo) + 1;
7419           else if (hi != 0)
7420             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
7421           else
7422             result = 0;
7423           break;
7424
7425         case BUILT_IN_CLZ:
7426         case BUILT_IN_CLZL:
7427         case BUILT_IN_CLZLL:
7428           if (hi != 0)
7429             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
7430           else if (lo != 0)
7431             result = width - floor_log2 (lo) - 1;
7432           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7433             result = width;
7434           break;
7435
7436         case BUILT_IN_CTZ:
7437         case BUILT_IN_CTZL:
7438         case BUILT_IN_CTZLL:
7439           if (lo != 0)
7440             result = exact_log2 (lo & -lo);
7441           else if (hi != 0)
7442             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
7443           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
7444             result = width;
7445           break;
7446
7447         case BUILT_IN_POPCOUNT:
7448         case BUILT_IN_POPCOUNTL:
7449         case BUILT_IN_POPCOUNTLL:
7450           result = 0;
7451           while (lo)
7452             result++, lo &= lo - 1;
7453           while (hi)
7454             result++, hi &= hi - 1;
7455           break;
7456
7457         case BUILT_IN_PARITY:
7458         case BUILT_IN_PARITYL:
7459         case BUILT_IN_PARITYLL:
7460           result = 0;
7461           while (lo)
7462             result++, lo &= lo - 1;
7463           while (hi)
7464             result++, hi &= hi - 1;
7465           result &= 1;
7466           break;
7467
7468         default:
7469           gcc_unreachable ();
7470         }
7471
7472       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
7473     }
7474
7475   return NULL_TREE;
7476 }
7477
7478 /* Return true if EXPR is the real constant contained in VALUE.  */
7479
7480 static bool
7481 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
7482 {
7483   STRIP_NOPS (expr);
7484
7485   return ((TREE_CODE (expr) == REAL_CST
7486            && ! TREE_CONSTANT_OVERFLOW (expr)
7487            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
7488           || (TREE_CODE (expr) == COMPLEX_CST
7489               && real_dconstp (TREE_REALPART (expr), value)
7490               && real_zerop (TREE_IMAGPART (expr))));
7491 }
7492
7493 /* A subroutine of fold_builtin to fold the various logarithmic
7494    functions.  EXP is the CALL_EXPR of a call to a builtin logN
7495    function.  VALUE is the base of the logN function.  */
7496
7497 static tree
7498 fold_builtin_logarithm (tree fndecl, tree arglist,
7499                         const REAL_VALUE_TYPE *value)
7500 {
7501   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7502     {
7503       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7504       tree arg = TREE_VALUE (arglist);
7505       const enum built_in_function fcode = builtin_mathfn_code (arg);
7506
7507       /* Optimize logN(1.0) = 0.0.  */
7508       if (real_onep (arg))
7509         return build_real (type, dconst0);
7510
7511       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
7512          exactly, then only do this if flag_unsafe_math_optimizations.  */
7513       if (exact_real_truncate (TYPE_MODE (type), value)
7514           || flag_unsafe_math_optimizations)
7515         {
7516           const REAL_VALUE_TYPE value_truncate =
7517             real_value_truncate (TYPE_MODE (type), *value);
7518           if (real_dconstp (arg, &value_truncate))
7519             return build_real (type, dconst1);
7520         }
7521
7522       /* Special case, optimize logN(expN(x)) = x.  */
7523       if (flag_unsafe_math_optimizations
7524           && ((value == &dconste
7525                && (fcode == BUILT_IN_EXP
7526                    || fcode == BUILT_IN_EXPF
7527                    || fcode == BUILT_IN_EXPL))
7528               || (value == &dconst2
7529                   && (fcode == BUILT_IN_EXP2
7530                       || fcode == BUILT_IN_EXP2F
7531                       || fcode == BUILT_IN_EXP2L))
7532               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
7533         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7534
7535       /* Optimize logN(func()) for various exponential functions.  We
7536          want to determine the value "x" and the power "exponent" in
7537          order to transform logN(x**exponent) into exponent*logN(x).  */
7538       if (flag_unsafe_math_optimizations)
7539         {
7540           tree exponent = 0, x = 0;
7541
7542           switch (fcode)
7543           {
7544           case BUILT_IN_EXP:
7545           case BUILT_IN_EXPF:
7546           case BUILT_IN_EXPL:
7547             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
7548             x = build_real (type,
7549                             real_value_truncate (TYPE_MODE (type), dconste));
7550             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7551             break;
7552           case BUILT_IN_EXP2:
7553           case BUILT_IN_EXP2F:
7554           case BUILT_IN_EXP2L:
7555             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
7556             x = build_real (type, dconst2);
7557             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7558             break;
7559           case BUILT_IN_EXP10:
7560           case BUILT_IN_EXP10F:
7561           case BUILT_IN_EXP10L:
7562           case BUILT_IN_POW10:
7563           case BUILT_IN_POW10F:
7564           case BUILT_IN_POW10L:
7565             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
7566             x = build_real (type, dconst10);
7567             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
7568             break;
7569           case BUILT_IN_SQRT:
7570           case BUILT_IN_SQRTF:
7571           case BUILT_IN_SQRTL:
7572             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
7573             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7574             exponent = build_real (type, dconsthalf);
7575             break;
7576           case BUILT_IN_CBRT:
7577           case BUILT_IN_CBRTF:
7578           case BUILT_IN_CBRTL:
7579             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
7580             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7581             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
7582                                                               dconstthird));
7583             break;
7584           case BUILT_IN_POW:
7585           case BUILT_IN_POWF:
7586           case BUILT_IN_POWL:
7587             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
7588             x = TREE_VALUE (TREE_OPERAND (arg, 1));
7589             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7590             break;
7591           default:
7592             break;
7593           }
7594
7595           /* Now perform the optimization.  */
7596           if (x && exponent)
7597             {
7598               tree logfn;
7599               arglist = build_tree_list (NULL_TREE, x);
7600               logfn = build_function_call_expr (fndecl, arglist);
7601               return fold_build2 (MULT_EXPR, type, exponent, logfn);
7602             }
7603         }
7604     }
7605
7606   return 0;
7607 }
7608
7609 /* Fold a builtin function call to pow, powf, or powl.  Return
7610    NULL_TREE if no simplification can be made.  */
7611 static tree
7612 fold_builtin_pow (tree fndecl, tree arglist, tree type)
7613 {
7614   tree arg0 = TREE_VALUE (arglist);
7615   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7616
7617   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7618     return NULL_TREE;
7619
7620   /* Optimize pow(1.0,y) = 1.0.  */
7621   if (real_onep (arg0))
7622     return omit_one_operand (type, build_real (type, dconst1), arg1);
7623
7624   if (TREE_CODE (arg1) == REAL_CST
7625       && ! TREE_CONSTANT_OVERFLOW (arg1))
7626     {
7627       REAL_VALUE_TYPE cint;
7628       REAL_VALUE_TYPE c;
7629       HOST_WIDE_INT n;
7630
7631       c = TREE_REAL_CST (arg1);
7632
7633       /* Optimize pow(x,0.0) = 1.0.  */
7634       if (REAL_VALUES_EQUAL (c, dconst0))
7635         return omit_one_operand (type, build_real (type, dconst1),
7636                                  arg0);
7637
7638       /* Optimize pow(x,1.0) = x.  */
7639       if (REAL_VALUES_EQUAL (c, dconst1))
7640         return arg0;
7641
7642       /* Optimize pow(x,-1.0) = 1.0/x.  */
7643       if (REAL_VALUES_EQUAL (c, dconstm1))
7644         return fold_build2 (RDIV_EXPR, type,
7645                             build_real (type, dconst1), arg0);
7646
7647       /* Optimize pow(x,0.5) = sqrt(x).  */
7648       if (flag_unsafe_math_optimizations
7649           && REAL_VALUES_EQUAL (c, dconsthalf))
7650         {
7651           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
7652
7653           if (sqrtfn != NULL_TREE)
7654             {
7655               tree arglist = build_tree_list (NULL_TREE, arg0);
7656               return build_function_call_expr (sqrtfn, arglist);
7657             }
7658         }
7659
7660       /* Check for an integer exponent.  */
7661       n = real_to_integer (&c);
7662       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
7663       if (real_identical (&c, &cint))
7664         {
7665           /* Attempt to evaluate pow at compile-time.  */
7666           if (TREE_CODE (arg0) == REAL_CST
7667               && ! TREE_CONSTANT_OVERFLOW (arg0))
7668             {
7669               REAL_VALUE_TYPE x;
7670               bool inexact;
7671
7672               x = TREE_REAL_CST (arg0);
7673               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
7674               if (flag_unsafe_math_optimizations || !inexact)
7675                 return build_real (type, x);
7676             }
7677
7678           /* Strip sign ops from even integer powers.  */
7679           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
7680             {
7681               tree narg0 = fold_strip_sign_ops (arg0);
7682               if (narg0)
7683                 {
7684                   arglist = build_tree_list (NULL_TREE, arg1);
7685                   arglist = tree_cons (NULL_TREE, narg0, arglist);
7686                   return build_function_call_expr (fndecl, arglist);
7687                 }
7688             }
7689         }
7690     }
7691
7692   if (flag_unsafe_math_optimizations)
7693     {
7694       const enum built_in_function fcode = builtin_mathfn_code (arg0);
7695
7696       /* Optimize pow(expN(x),y) = expN(x*y).  */
7697       if (BUILTIN_EXPONENT_P (fcode))
7698         {
7699           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
7700           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7701           arg = fold_build2 (MULT_EXPR, type, arg, arg1);
7702           arglist = build_tree_list (NULL_TREE, arg);
7703           return build_function_call_expr (expfn, arglist);
7704         }
7705
7706       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
7707       if (BUILTIN_SQRT_P (fcode))
7708         {
7709           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7710           tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7711                                     build_real (type, dconsthalf));
7712
7713           arglist = tree_cons (NULL_TREE, narg0,
7714                                build_tree_list (NULL_TREE, narg1));
7715           return build_function_call_expr (fndecl, arglist);
7716         }
7717
7718       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7719       if (BUILTIN_CBRT_P (fcode))
7720         {
7721           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7722           if (tree_expr_nonnegative_p (arg))
7723             {
7724               const REAL_VALUE_TYPE dconstroot
7725                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7726               tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
7727                                         build_real (type, dconstroot));
7728               arglist = tree_cons (NULL_TREE, arg,
7729                                    build_tree_list (NULL_TREE, narg1));
7730               return build_function_call_expr (fndecl, arglist);
7731             }
7732         }
7733       
7734       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7735       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7736            || fcode == BUILT_IN_POWL)
7737         {
7738           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7739           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7740           tree narg1 = fold_build2 (MULT_EXPR, type, arg01, arg1);
7741           arglist = tree_cons (NULL_TREE, arg00,
7742                                build_tree_list (NULL_TREE, narg1));
7743           return build_function_call_expr (fndecl, arglist);
7744         }
7745     }
7746
7747   return NULL_TREE;
7748 }
7749
7750 /* Fold a builtin function call to powi, powif, or powil.  Return
7751    NULL_TREE if no simplification can be made.  */
7752 static tree
7753 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7754 {
7755   tree arg0 = TREE_VALUE (arglist);
7756   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7757
7758   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7759     return NULL_TREE;
7760
7761   /* Optimize pow(1.0,y) = 1.0.  */
7762   if (real_onep (arg0))
7763     return omit_one_operand (type, build_real (type, dconst1), arg1);
7764
7765   if (host_integerp (arg1, 0))
7766     {
7767       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7768
7769       /* Evaluate powi at compile-time.  */
7770       if (TREE_CODE (arg0) == REAL_CST
7771           && ! TREE_CONSTANT_OVERFLOW (arg0))
7772         {
7773           REAL_VALUE_TYPE x;
7774           x = TREE_REAL_CST (arg0);
7775           real_powi (&x, TYPE_MODE (type), &x, c);
7776           return build_real (type, x);
7777         }
7778
7779       /* Optimize pow(x,0) = 1.0.  */
7780       if (c == 0)
7781         return omit_one_operand (type, build_real (type, dconst1),
7782                                  arg0);
7783
7784       /* Optimize pow(x,1) = x.  */
7785       if (c == 1)
7786         return arg0;
7787
7788       /* Optimize pow(x,-1) = 1.0/x.  */
7789       if (c == -1)
7790         return fold_build2 (RDIV_EXPR, type,
7791                            build_real (type, dconst1), arg0);
7792     }
7793
7794   return NULL_TREE;
7795 }
7796
7797 /* A subroutine of fold_builtin to fold the various exponent
7798    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7799    VALUE is the value which will be raised to a power.  */
7800
7801 static tree
7802 fold_builtin_exponent (tree fndecl, tree arglist,
7803                        const REAL_VALUE_TYPE *value)
7804 {
7805   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7806     {
7807       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7808       tree arg = TREE_VALUE (arglist);
7809
7810       /* Optimize exp*(0.0) = 1.0.  */
7811       if (real_zerop (arg))
7812         return build_real (type, dconst1);
7813
7814       /* Optimize expN(1.0) = N.  */
7815       if (real_onep (arg))
7816         {
7817           REAL_VALUE_TYPE cst;
7818
7819           real_convert (&cst, TYPE_MODE (type), value);
7820           return build_real (type, cst);
7821         }
7822
7823       /* Attempt to evaluate expN(integer) at compile-time.  */
7824       if (flag_unsafe_math_optimizations
7825           && TREE_CODE (arg) == REAL_CST
7826           && ! TREE_CONSTANT_OVERFLOW (arg))
7827         {
7828           REAL_VALUE_TYPE cint;
7829           REAL_VALUE_TYPE c;
7830           HOST_WIDE_INT n;
7831
7832           c = TREE_REAL_CST (arg);
7833           n = real_to_integer (&c);
7834           real_from_integer (&cint, VOIDmode, n,
7835                              n < 0 ? -1 : 0, 0);
7836           if (real_identical (&c, &cint))
7837             {
7838               REAL_VALUE_TYPE x;
7839
7840               real_powi (&x, TYPE_MODE (type), value, n);
7841               return build_real (type, x);
7842             }
7843         }
7844
7845       /* Optimize expN(logN(x)) = x.  */
7846       if (flag_unsafe_math_optimizations)
7847         {
7848           const enum built_in_function fcode = builtin_mathfn_code (arg);
7849
7850           if ((value == &dconste
7851                && (fcode == BUILT_IN_LOG
7852                    || fcode == BUILT_IN_LOGF
7853                    || fcode == BUILT_IN_LOGL))
7854               || (value == &dconst2
7855                   && (fcode == BUILT_IN_LOG2
7856                       || fcode == BUILT_IN_LOG2F
7857                       || fcode == BUILT_IN_LOG2L))
7858               || (value == &dconst10
7859                   && (fcode == BUILT_IN_LOG10
7860                       || fcode == BUILT_IN_LOG10F
7861                       || fcode == BUILT_IN_LOG10L)))
7862             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7863         }
7864     }
7865
7866   return 0;
7867 }
7868
7869 /* Fold function call to builtin memcpy.  Return
7870    NULL_TREE if no simplification can be made.  */
7871
7872 static tree
7873 fold_builtin_memcpy (tree fndecl, tree arglist)
7874 {
7875   tree dest, src, len;
7876
7877   if (!validate_arglist (arglist,
7878                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7879     return 0;
7880
7881   dest = TREE_VALUE (arglist);
7882   src = TREE_VALUE (TREE_CHAIN (arglist));
7883   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7884
7885   /* If the LEN parameter is zero, return DEST.  */
7886   if (integer_zerop (len))
7887     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7888
7889   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7890   if (operand_equal_p (src, dest, 0))
7891     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7892
7893   return 0;
7894 }
7895
7896 /* Fold function call to builtin mempcpy.  Return
7897    NULL_TREE if no simplification can be made.  */
7898
7899 static tree
7900 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7901 {
7902   if (validate_arglist (arglist,
7903                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7904     {
7905       tree dest = TREE_VALUE (arglist);
7906       tree src = TREE_VALUE (TREE_CHAIN (arglist));
7907       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7908
7909       /* If the LEN parameter is zero, return DEST.  */
7910       if (integer_zerop (len))
7911         return omit_one_operand (type, dest, src);
7912
7913       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7914       if (operand_equal_p (src, dest, 0))
7915         {
7916           if (endp == 0)
7917             return omit_one_operand (type, dest, len);
7918
7919           if (endp == 2)
7920             len = fold_build2 (MINUS_EXPR, TREE_TYPE (len), len,
7921                                ssize_int (1));
7922       
7923           len = fold_convert (TREE_TYPE (dest), len);
7924           len = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
7925           return fold_convert (type, len);
7926         }
7927     }
7928   return 0;
7929 }
7930
7931 /* Fold function call to builtin memmove.  Return
7932    NULL_TREE if no simplification can be made.  */
7933
7934 static tree
7935 fold_builtin_memmove (tree arglist, tree type)
7936 {
7937   tree dest, src, len;
7938
7939   if (!validate_arglist (arglist,
7940                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7941     return 0;
7942
7943   dest = TREE_VALUE (arglist);
7944   src = TREE_VALUE (TREE_CHAIN (arglist));
7945   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7946
7947   /* If the LEN parameter is zero, return DEST.  */
7948   if (integer_zerop (len))
7949     return omit_one_operand (type, dest, src);
7950
7951   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7952   if (operand_equal_p (src, dest, 0))
7953     return omit_one_operand (type, dest, len);
7954
7955   return 0;
7956 }
7957
7958 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7959    the length of the string to be copied.  Return NULL_TREE if no
7960    simplification can be made.  */
7961
7962 tree
7963 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7964 {
7965   tree dest, src, fn;
7966
7967   if (!validate_arglist (arglist,
7968                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7969     return 0;
7970
7971   dest = TREE_VALUE (arglist);
7972   src = TREE_VALUE (TREE_CHAIN (arglist));
7973
7974   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7975   if (operand_equal_p (src, dest, 0))
7976     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7977
7978   if (optimize_size)
7979     return 0;
7980
7981   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7982   if (!fn)
7983     return 0;
7984
7985   if (!len)
7986     {
7987       len = c_strlen (src, 1);
7988       if (! len || TREE_SIDE_EFFECTS (len))
7989         return 0;
7990     }
7991
7992   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7993   arglist = build_tree_list (NULL_TREE, len);
7994   arglist = tree_cons (NULL_TREE, src, arglist);
7995   arglist = tree_cons (NULL_TREE, dest, arglist);
7996   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7997                        build_function_call_expr (fn, arglist));
7998 }
7999
8000 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
8001    the length of the source string.  Return NULL_TREE if no simplification
8002    can be made.  */
8003
8004 tree
8005 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
8006 {
8007   tree dest, src, len, fn;
8008
8009   if (!validate_arglist (arglist,
8010                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8011     return 0;
8012
8013   dest = TREE_VALUE (arglist);
8014   src = TREE_VALUE (TREE_CHAIN (arglist));
8015   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8016
8017   /* If the LEN parameter is zero, return DEST.  */
8018   if (integer_zerop (len))
8019     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
8020
8021   /* We can't compare slen with len as constants below if len is not a
8022      constant.  */
8023   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
8024     return 0;
8025
8026   if (!slen)
8027     slen = c_strlen (src, 1);
8028
8029   /* Now, we must be passed a constant src ptr parameter.  */
8030   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8031     return 0;
8032
8033   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8034
8035   /* We do not support simplification of this case, though we do
8036      support it when expanding trees into RTL.  */
8037   /* FIXME: generate a call to __builtin_memset.  */
8038   if (tree_int_cst_lt (slen, len))
8039     return 0;
8040
8041   /* OK transform into builtin memcpy.  */
8042   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8043   if (!fn)
8044     return 0;
8045   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
8046                        build_function_call_expr (fn, arglist));
8047 }
8048
8049 /* Fold function call to builtin memcmp.  Return
8050    NULL_TREE if no simplification can be made.  */
8051
8052 static tree
8053 fold_builtin_memcmp (tree arglist)
8054 {
8055   tree arg1, arg2, len;
8056   const char *p1, *p2;
8057
8058   if (!validate_arglist (arglist,
8059                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8060     return 0;
8061
8062   arg1 = TREE_VALUE (arglist);
8063   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8064   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8065
8066   /* If the LEN parameter is zero, return zero.  */
8067   if (integer_zerop (len))
8068     return omit_two_operands (integer_type_node, integer_zero_node,
8069                               arg1, arg2);
8070
8071   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8072   if (operand_equal_p (arg1, arg2, 0))
8073     return omit_one_operand (integer_type_node, integer_zero_node, len);
8074
8075   p1 = c_getstr (arg1);
8076   p2 = c_getstr (arg2);
8077
8078   /* If all arguments are constant, and the value of len is not greater
8079      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8080   if (host_integerp (len, 1) && p1 && p2
8081       && compare_tree_int (len, strlen (p1) + 1) <= 0
8082       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8083     {
8084       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8085
8086       if (r > 0)
8087         return integer_one_node;
8088       else if (r < 0)
8089         return integer_minus_one_node;
8090       else
8091         return integer_zero_node;
8092     }
8093
8094   /* If len parameter is one, return an expression corresponding to
8095      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8096   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8097     {
8098       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8099       tree cst_uchar_ptr_node
8100         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8101
8102       tree ind1 = fold_convert (integer_type_node,
8103                                 build1 (INDIRECT_REF, cst_uchar_node,
8104                                         fold_convert (cst_uchar_ptr_node,
8105                                                       arg1)));
8106       tree ind2 = fold_convert (integer_type_node,
8107                                 build1 (INDIRECT_REF, cst_uchar_node,
8108                                         fold_convert (cst_uchar_ptr_node,
8109                                                       arg2)));
8110       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8111     }
8112
8113   return 0;
8114 }
8115
8116 /* Fold function call to builtin strcmp.  Return
8117    NULL_TREE if no simplification can be made.  */
8118
8119 static tree
8120 fold_builtin_strcmp (tree arglist)
8121 {
8122   tree arg1, arg2;
8123   const char *p1, *p2;
8124
8125   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8126     return 0;
8127
8128   arg1 = TREE_VALUE (arglist);
8129   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8130
8131   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8132   if (operand_equal_p (arg1, arg2, 0))
8133     return integer_zero_node;
8134
8135   p1 = c_getstr (arg1);
8136   p2 = c_getstr (arg2);
8137
8138   if (p1 && p2)
8139     {
8140       const int i = strcmp (p1, p2);
8141       if (i < 0)
8142         return integer_minus_one_node;
8143       else if (i > 0)
8144         return integer_one_node;
8145       else
8146         return integer_zero_node;
8147     }
8148
8149   /* If the second arg is "", return *(const unsigned char*)arg1.  */
8150   if (p2 && *p2 == '\0')
8151     {
8152       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8153       tree cst_uchar_ptr_node
8154         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8155
8156       return fold_convert (integer_type_node,
8157                            build1 (INDIRECT_REF, cst_uchar_node,
8158                                    fold_convert (cst_uchar_ptr_node,
8159                                                  arg1)));
8160     }
8161
8162   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
8163   if (p1 && *p1 == '\0')
8164     {
8165       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8166       tree cst_uchar_ptr_node
8167         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8168
8169       tree temp = fold_convert (integer_type_node,
8170                                 build1 (INDIRECT_REF, cst_uchar_node,
8171                                         fold_convert (cst_uchar_ptr_node,
8172                                                       arg2)));
8173       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8174     }
8175
8176   return 0;
8177 }
8178
8179 /* Fold function call to builtin strncmp.  Return
8180    NULL_TREE if no simplification can be made.  */
8181
8182 static tree
8183 fold_builtin_strncmp (tree arglist)
8184 {
8185   tree arg1, arg2, len;
8186   const char *p1, *p2;
8187
8188   if (!validate_arglist (arglist,
8189                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8190     return 0;
8191
8192   arg1 = TREE_VALUE (arglist);
8193   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8194   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8195
8196   /* If the LEN parameter is zero, return zero.  */
8197   if (integer_zerop (len))
8198     return omit_two_operands (integer_type_node, integer_zero_node,
8199                               arg1, arg2);
8200
8201   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
8202   if (operand_equal_p (arg1, arg2, 0))
8203     return omit_one_operand (integer_type_node, integer_zero_node, len);
8204
8205   p1 = c_getstr (arg1);
8206   p2 = c_getstr (arg2);
8207
8208   if (host_integerp (len, 1) && p1 && p2)
8209     {
8210       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
8211       if (i > 0)
8212         return integer_one_node;
8213       else if (i < 0)
8214         return integer_minus_one_node;
8215       else
8216         return integer_zero_node;
8217     }
8218
8219   /* If the second arg is "", and the length is greater than zero,
8220      return *(const unsigned char*)arg1.  */
8221   if (p2 && *p2 == '\0'
8222       && TREE_CODE (len) == INTEGER_CST
8223       && tree_int_cst_sgn (len) == 1)
8224     {
8225       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8226       tree cst_uchar_ptr_node
8227         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8228
8229       return fold_convert (integer_type_node,
8230                            build1 (INDIRECT_REF, cst_uchar_node,
8231                                    fold_convert (cst_uchar_ptr_node,
8232                                                  arg1)));
8233     }
8234
8235   /* If the first arg is "", and the length is greater than zero,
8236      return -*(const unsigned char*)arg2.  */
8237   if (p1 && *p1 == '\0'
8238       && TREE_CODE (len) == INTEGER_CST
8239       && tree_int_cst_sgn (len) == 1)
8240     {
8241       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8242       tree cst_uchar_ptr_node
8243         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8244
8245       tree temp = fold_convert (integer_type_node,
8246                                 build1 (INDIRECT_REF, cst_uchar_node,
8247                                         fold_convert (cst_uchar_ptr_node,
8248                                                       arg2)));
8249       return fold_build1 (NEGATE_EXPR, integer_type_node, temp);
8250     }
8251
8252   /* If len parameter is one, return an expression corresponding to
8253      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8254   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8255     {
8256       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8257       tree cst_uchar_ptr_node
8258         = build_pointer_type_for_mode (cst_uchar_node, ptr_mode, true);
8259
8260       tree ind1 = fold_convert (integer_type_node,
8261                                 build1 (INDIRECT_REF, cst_uchar_node,
8262                                         fold_convert (cst_uchar_ptr_node,
8263                                                       arg1)));
8264       tree ind2 = fold_convert (integer_type_node,
8265                                 build1 (INDIRECT_REF, cst_uchar_node,
8266                                         fold_convert (cst_uchar_ptr_node,
8267                                                       arg2)));
8268       return fold_build2 (MINUS_EXPR, integer_type_node, ind1, ind2);
8269     }
8270
8271   return 0;
8272 }
8273
8274 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
8275    NULL_TREE if no simplification can be made.  */
8276
8277 static tree
8278 fold_builtin_signbit (tree fndecl, tree arglist)
8279 {
8280   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8281   tree arg, temp;
8282
8283   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8284     return NULL_TREE;
8285
8286   arg = TREE_VALUE (arglist);
8287
8288   /* If ARG is a compile-time constant, determine the result.  */
8289   if (TREE_CODE (arg) == REAL_CST
8290       && !TREE_CONSTANT_OVERFLOW (arg))
8291     {
8292       REAL_VALUE_TYPE c;
8293
8294       c = TREE_REAL_CST (arg);
8295       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
8296       return fold_convert (type, temp);
8297     }
8298
8299   /* If ARG is non-negative, the result is always zero.  */
8300   if (tree_expr_nonnegative_p (arg))
8301     return omit_one_operand (type, integer_zero_node, arg);
8302
8303   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
8304   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
8305     return fold_build2 (LT_EXPR, type, arg,
8306                         build_real (TREE_TYPE (arg), dconst0));
8307
8308   return NULL_TREE;
8309 }
8310
8311 /* Fold function call to builtin copysign, copysignf or copysignl.
8312    Return NULL_TREE if no simplification can be made.  */
8313
8314 static tree
8315 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
8316 {
8317   tree arg1, arg2, tem;
8318
8319   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8320     return NULL_TREE;
8321
8322   arg1 = TREE_VALUE (arglist);
8323   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8324
8325   /* copysign(X,X) is X.  */
8326   if (operand_equal_p (arg1, arg2, 0))
8327     return fold_convert (type, arg1);
8328
8329   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
8330   if (TREE_CODE (arg1) == REAL_CST
8331       && TREE_CODE (arg2) == REAL_CST
8332       && !TREE_CONSTANT_OVERFLOW (arg1)
8333       && !TREE_CONSTANT_OVERFLOW (arg2))
8334     {
8335       REAL_VALUE_TYPE c1, c2;
8336
8337       c1 = TREE_REAL_CST (arg1);
8338       c2 = TREE_REAL_CST (arg2);
8339       real_copysign (&c1, &c2);
8340       return build_real (type, c1);
8341       c1.sign = c2.sign;
8342     }
8343
8344   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
8345      Remember to evaluate Y for side-effects.  */
8346   if (tree_expr_nonnegative_p (arg2))
8347     return omit_one_operand (type,
8348                              fold_build1 (ABS_EXPR, type, arg1),
8349                              arg2);
8350
8351   /* Strip sign changing operations for the first argument.  */
8352   tem = fold_strip_sign_ops (arg1);
8353   if (tem)
8354     {
8355       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
8356       return build_function_call_expr (fndecl, arglist);
8357     }
8358
8359   return NULL_TREE;
8360 }
8361
8362 /* Fold a call to builtin isascii.  */
8363
8364 static tree
8365 fold_builtin_isascii (tree arglist)
8366 {
8367   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8368     return 0;
8369   else
8370     {
8371       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
8372       tree arg = TREE_VALUE (arglist);
8373
8374       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
8375                     build_int_cst (NULL_TREE,
8376                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
8377       arg = fold_build2 (EQ_EXPR, integer_type_node,
8378                          arg, integer_zero_node);
8379
8380       if (in_gimple_form && !TREE_CONSTANT (arg))
8381         return NULL_TREE;
8382       else
8383         return arg;
8384     }
8385 }
8386
8387 /* Fold a call to builtin toascii.  */
8388
8389 static tree
8390 fold_builtin_toascii (tree arglist)
8391 {
8392   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8393     return 0;
8394   else
8395     {
8396       /* Transform toascii(c) -> (c & 0x7f).  */
8397       tree arg = TREE_VALUE (arglist);
8398
8399       return fold_build2 (BIT_AND_EXPR, integer_type_node, arg,
8400                           build_int_cst (NULL_TREE, 0x7f));
8401     }
8402 }
8403
8404 /* Fold a call to builtin isdigit.  */
8405
8406 static tree
8407 fold_builtin_isdigit (tree arglist)
8408 {
8409   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8410     return 0;
8411   else
8412     {
8413       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
8414       /* According to the C standard, isdigit is unaffected by locale.
8415          However, it definitely is affected by the target character set.  */
8416       tree arg;
8417       unsigned HOST_WIDE_INT target_digit0
8418         = lang_hooks.to_target_charset ('0');
8419
8420       if (target_digit0 == 0)
8421         return NULL_TREE;
8422
8423       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
8424       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
8425                     build_int_cst (unsigned_type_node, target_digit0));
8426       arg = fold_build2 (LE_EXPR, integer_type_node, arg,
8427                          build_int_cst (unsigned_type_node, 9));
8428       if (in_gimple_form && !TREE_CONSTANT (arg))
8429         return NULL_TREE;
8430       else
8431         return arg;
8432     }
8433 }
8434
8435 /* Fold a call to fabs, fabsf or fabsl.  */
8436
8437 static tree
8438 fold_builtin_fabs (tree arglist, tree type)
8439 {
8440   tree arg;
8441
8442   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8443     return 0;
8444
8445   arg = TREE_VALUE (arglist);
8446   arg = fold_convert (type, arg);
8447   if (TREE_CODE (arg) == REAL_CST)
8448     return fold_abs_const (arg, type);
8449   return fold_build1 (ABS_EXPR, type, arg);
8450 }
8451
8452 /* Fold a call to abs, labs, llabs or imaxabs.  */
8453
8454 static tree
8455 fold_builtin_abs (tree arglist, tree type)
8456 {
8457   tree arg;
8458
8459   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
8460     return 0;
8461
8462   arg = TREE_VALUE (arglist);
8463   arg = fold_convert (type, arg);
8464   if (TREE_CODE (arg) == INTEGER_CST)
8465     return fold_abs_const (arg, type);
8466   return fold_build1 (ABS_EXPR, type, arg);
8467 }
8468
8469 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
8470    EXP is the CALL_EXPR for the call.  */
8471
8472 static tree
8473 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
8474 {
8475   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8476   tree arg;
8477   REAL_VALUE_TYPE r;
8478
8479   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8480     {
8481       /* Check that we have exactly one argument.  */
8482       if (arglist == 0)
8483         {
8484           error ("too few arguments to function %qs",
8485                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8486           return error_mark_node;
8487         }
8488       else if (TREE_CHAIN (arglist) != 0)
8489         {
8490           error ("too many arguments to function %qs",
8491                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8492           return error_mark_node;
8493         }
8494       else
8495         {
8496           error ("non-floating-point argument to function %qs",
8497                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8498           return error_mark_node;
8499         }
8500     }
8501
8502   arg = TREE_VALUE (arglist);
8503   switch (builtin_index)
8504     {
8505     case BUILT_IN_ISINF:
8506       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8507         return omit_one_operand (type, integer_zero_node, arg);
8508
8509       if (TREE_CODE (arg) == REAL_CST)
8510         {
8511           r = TREE_REAL_CST (arg);
8512           if (real_isinf (&r))
8513             return real_compare (GT_EXPR, &r, &dconst0)
8514                    ? integer_one_node : integer_minus_one_node;
8515           else
8516             return integer_zero_node;
8517         }
8518
8519       return NULL_TREE;
8520
8521     case BUILT_IN_FINITE:
8522       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
8523           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
8524         return omit_one_operand (type, integer_zero_node, arg);
8525
8526       if (TREE_CODE (arg) == REAL_CST)
8527         {
8528           r = TREE_REAL_CST (arg);
8529           return real_isinf (&r) || real_isnan (&r)
8530                  ? integer_zero_node : integer_one_node;
8531         }
8532
8533       return NULL_TREE;
8534
8535     case BUILT_IN_ISNAN:
8536       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
8537         return omit_one_operand (type, integer_zero_node, arg);
8538
8539       if (TREE_CODE (arg) == REAL_CST)
8540         {
8541           r = TREE_REAL_CST (arg);
8542           return real_isnan (&r) ? integer_one_node : integer_zero_node;
8543         }
8544
8545       arg = builtin_save_expr (arg);
8546       return fold_build2 (UNORDERED_EXPR, type, arg, arg);
8547
8548     default:
8549       gcc_unreachable ();
8550     }
8551 }
8552
8553 /* Fold a call to an unordered comparison function such as
8554    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
8555    being called and ARGLIST is the argument list for the call.
8556    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
8557    the opposite of the desired result.  UNORDERED_CODE is used
8558    for modes that can hold NaNs and ORDERED_CODE is used for
8559    the rest.  */
8560
8561 static tree
8562 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
8563                             enum tree_code unordered_code,
8564                             enum tree_code ordered_code)
8565 {
8566   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8567   enum tree_code code;
8568   tree arg0, arg1;
8569   tree type0, type1;
8570   enum tree_code code0, code1;
8571   tree cmp_type = NULL_TREE;
8572
8573   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8574     {
8575       /* Check that we have exactly two arguments.  */
8576       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
8577         {
8578           error ("too few arguments to function %qs",
8579                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8580           return error_mark_node;
8581         }
8582       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
8583         {
8584           error ("too many arguments to function %qs",
8585                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8586           return error_mark_node;
8587         }
8588     }
8589
8590   arg0 = TREE_VALUE (arglist);
8591   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8592   
8593   type0 = TREE_TYPE (arg0);
8594   type1 = TREE_TYPE (arg1);
8595   
8596   code0 = TREE_CODE (type0);
8597   code1 = TREE_CODE (type1);
8598   
8599   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
8600     /* Choose the wider of two real types.  */
8601     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
8602       ? type0 : type1;
8603   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
8604     cmp_type = type0;
8605   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
8606     cmp_type = type1;
8607   else
8608     {
8609       error ("non-floating-point argument to function %qs",
8610                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
8611       return error_mark_node;
8612     }
8613   
8614   arg0 = fold_convert (cmp_type, arg0);
8615   arg1 = fold_convert (cmp_type, arg1);
8616
8617   if (unordered_code == UNORDERED_EXPR)
8618     {
8619       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
8620         return omit_two_operands (type, integer_zero_node, arg0, arg1);
8621       return fold_build2 (UNORDERED_EXPR, type, arg0, arg1);
8622     }
8623
8624   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
8625                                                       : ordered_code;
8626   return fold_build1 (TRUTH_NOT_EXPR, type,
8627                       fold_build2 (code, type, arg0, arg1));
8628 }
8629
8630 /* Used by constant folding to simplify calls to builtin functions.  EXP is
8631    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
8632    result of the function call is ignored.  This function returns NULL_TREE
8633    if no simplification was possible.  */
8634
8635 static tree
8636 fold_builtin_1 (tree fndecl, tree arglist, bool ignore)
8637 {
8638   tree type = TREE_TYPE (TREE_TYPE (fndecl));
8639   enum built_in_function fcode;
8640
8641   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
8642     return targetm.fold_builtin (fndecl, arglist, ignore);
8643
8644   fcode = DECL_FUNCTION_CODE (fndecl);
8645   switch (fcode)
8646     {
8647     case BUILT_IN_FPUTS:
8648       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8649
8650     case BUILT_IN_FPUTS_UNLOCKED:
8651       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8652
8653     case BUILT_IN_STRSTR:
8654       return fold_builtin_strstr (arglist, type);
8655
8656     case BUILT_IN_STRCAT:
8657       return fold_builtin_strcat (arglist);
8658
8659     case BUILT_IN_STRNCAT:
8660       return fold_builtin_strncat (arglist);
8661
8662     case BUILT_IN_STRSPN:
8663       return fold_builtin_strspn (arglist);
8664
8665     case BUILT_IN_STRCSPN:
8666       return fold_builtin_strcspn (arglist);
8667
8668     case BUILT_IN_STRCHR:
8669     case BUILT_IN_INDEX:
8670       return fold_builtin_strchr (arglist, type);
8671
8672     case BUILT_IN_STRRCHR:
8673     case BUILT_IN_RINDEX:
8674       return fold_builtin_strrchr (arglist, type);
8675
8676     case BUILT_IN_STRCPY:
8677       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8678
8679     case BUILT_IN_STRNCPY:
8680       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8681
8682     case BUILT_IN_STRCMP:
8683       return fold_builtin_strcmp (arglist);
8684
8685     case BUILT_IN_STRNCMP:
8686       return fold_builtin_strncmp (arglist);
8687
8688     case BUILT_IN_STRPBRK:
8689       return fold_builtin_strpbrk (arglist, type);
8690
8691     case BUILT_IN_BCMP:
8692     case BUILT_IN_MEMCMP:
8693       return fold_builtin_memcmp (arglist);
8694
8695     case BUILT_IN_SPRINTF:
8696       return fold_builtin_sprintf (arglist, ignore);
8697
8698     case BUILT_IN_CONSTANT_P:
8699       {
8700         tree val;
8701
8702         val = fold_builtin_constant_p (arglist);
8703         /* Gimplification will pull the CALL_EXPR for the builtin out of
8704            an if condition.  When not optimizing, we'll not CSE it back.
8705            To avoid link error types of regressions, return false now.  */
8706         if (!val && !optimize)
8707           val = integer_zero_node;
8708
8709         return val;
8710       }
8711
8712     case BUILT_IN_EXPECT:
8713       return fold_builtin_expect (arglist);
8714
8715     case BUILT_IN_CLASSIFY_TYPE:
8716       return fold_builtin_classify_type (arglist);
8717
8718     case BUILT_IN_STRLEN:
8719       return fold_builtin_strlen (arglist);
8720
8721     case BUILT_IN_FABS:
8722     case BUILT_IN_FABSF:
8723     case BUILT_IN_FABSL:
8724       return fold_builtin_fabs (arglist, type);
8725
8726     case BUILT_IN_ABS:
8727     case BUILT_IN_LABS:
8728     case BUILT_IN_LLABS:
8729     case BUILT_IN_IMAXABS:
8730       return fold_builtin_abs (arglist, type);
8731
8732     case BUILT_IN_CONJ:
8733     case BUILT_IN_CONJF:
8734     case BUILT_IN_CONJL:
8735       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8736         return fold_build1 (CONJ_EXPR, type, TREE_VALUE (arglist));
8737       break;
8738
8739     case BUILT_IN_CREAL:
8740     case BUILT_IN_CREALF:
8741     case BUILT_IN_CREALL:
8742       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8743         return non_lvalue (fold_build1 (REALPART_EXPR, type,
8744                                         TREE_VALUE (arglist)));
8745       break;
8746
8747     case BUILT_IN_CIMAG:
8748     case BUILT_IN_CIMAGF:
8749     case BUILT_IN_CIMAGL:
8750       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8751         return non_lvalue (fold_build1 (IMAGPART_EXPR, type,
8752                                         TREE_VALUE (arglist)));
8753       break;
8754
8755     case BUILT_IN_CABS:
8756     case BUILT_IN_CABSF:
8757     case BUILT_IN_CABSL:
8758       return fold_builtin_cabs (arglist, type);
8759
8760     case BUILT_IN_SQRT:
8761     case BUILT_IN_SQRTF:
8762     case BUILT_IN_SQRTL:
8763       return fold_builtin_sqrt (arglist, type);
8764
8765     case BUILT_IN_CBRT:
8766     case BUILT_IN_CBRTF:
8767     case BUILT_IN_CBRTL:
8768       return fold_builtin_cbrt (arglist, type);
8769
8770     case BUILT_IN_SIN:
8771     case BUILT_IN_SINF:
8772     case BUILT_IN_SINL:
8773       return fold_builtin_sin (arglist);
8774
8775     case BUILT_IN_COS:
8776     case BUILT_IN_COSF:
8777     case BUILT_IN_COSL:
8778       return fold_builtin_cos (arglist, type, fndecl);
8779
8780     case BUILT_IN_EXP:
8781     case BUILT_IN_EXPF:
8782     case BUILT_IN_EXPL:
8783       return fold_builtin_exponent (fndecl, arglist, &dconste);
8784
8785     case BUILT_IN_EXP2:
8786     case BUILT_IN_EXP2F:
8787     case BUILT_IN_EXP2L:
8788       return fold_builtin_exponent (fndecl, arglist, &dconst2);
8789
8790     case BUILT_IN_EXP10:
8791     case BUILT_IN_EXP10F:
8792     case BUILT_IN_EXP10L:
8793     case BUILT_IN_POW10:
8794     case BUILT_IN_POW10F:
8795     case BUILT_IN_POW10L:
8796       return fold_builtin_exponent (fndecl, arglist, &dconst10);
8797
8798     case BUILT_IN_LOG:
8799     case BUILT_IN_LOGF:
8800     case BUILT_IN_LOGL:
8801       return fold_builtin_logarithm (fndecl, arglist, &dconste);
8802
8803     case BUILT_IN_LOG2:
8804     case BUILT_IN_LOG2F:
8805     case BUILT_IN_LOG2L:
8806       return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8807
8808     case BUILT_IN_LOG10:
8809     case BUILT_IN_LOG10F:
8810     case BUILT_IN_LOG10L:
8811       return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8812
8813     case BUILT_IN_TAN:
8814     case BUILT_IN_TANF:
8815     case BUILT_IN_TANL:
8816       return fold_builtin_tan (arglist);
8817
8818     case BUILT_IN_ATAN:
8819     case BUILT_IN_ATANF:
8820     case BUILT_IN_ATANL:
8821       return fold_builtin_atan (arglist, type);
8822
8823     case BUILT_IN_POW:
8824     case BUILT_IN_POWF:
8825     case BUILT_IN_POWL:
8826       return fold_builtin_pow (fndecl, arglist, type);
8827
8828     case BUILT_IN_POWI:
8829     case BUILT_IN_POWIF:
8830     case BUILT_IN_POWIL:
8831       return fold_builtin_powi (fndecl, arglist, type);
8832
8833     case BUILT_IN_INF:
8834     case BUILT_IN_INFF:
8835     case BUILT_IN_INFL:
8836       return fold_builtin_inf (type, true);
8837
8838     case BUILT_IN_HUGE_VAL:
8839     case BUILT_IN_HUGE_VALF:
8840     case BUILT_IN_HUGE_VALL:
8841       return fold_builtin_inf (type, false);
8842
8843     case BUILT_IN_NAN:
8844     case BUILT_IN_NANF:
8845     case BUILT_IN_NANL:
8846       return fold_builtin_nan (arglist, type, true);
8847
8848     case BUILT_IN_NANS:
8849     case BUILT_IN_NANSF:
8850     case BUILT_IN_NANSL:
8851       return fold_builtin_nan (arglist, type, false);
8852
8853     case BUILT_IN_FLOOR:
8854     case BUILT_IN_FLOORF:
8855     case BUILT_IN_FLOORL:
8856       return fold_builtin_floor (fndecl, arglist);
8857
8858     case BUILT_IN_CEIL:
8859     case BUILT_IN_CEILF:
8860     case BUILT_IN_CEILL:
8861       return fold_builtin_ceil (fndecl, arglist);
8862
8863     case BUILT_IN_TRUNC:
8864     case BUILT_IN_TRUNCF:
8865     case BUILT_IN_TRUNCL:
8866       return fold_builtin_trunc (fndecl, arglist);
8867
8868     case BUILT_IN_ROUND:
8869     case BUILT_IN_ROUNDF:
8870     case BUILT_IN_ROUNDL:
8871       return fold_builtin_round (fndecl, arglist);
8872
8873     case BUILT_IN_NEARBYINT:
8874     case BUILT_IN_NEARBYINTF:
8875     case BUILT_IN_NEARBYINTL:
8876     case BUILT_IN_RINT:
8877     case BUILT_IN_RINTF:
8878     case BUILT_IN_RINTL:
8879       return fold_trunc_transparent_mathfn (fndecl, arglist);
8880
8881     case BUILT_IN_LCEIL:
8882     case BUILT_IN_LCEILF:
8883     case BUILT_IN_LCEILL:
8884     case BUILT_IN_LLCEIL:
8885     case BUILT_IN_LLCEILF:
8886     case BUILT_IN_LLCEILL:
8887     case BUILT_IN_LFLOOR:
8888     case BUILT_IN_LFLOORF:
8889     case BUILT_IN_LFLOORL:
8890     case BUILT_IN_LLFLOOR:
8891     case BUILT_IN_LLFLOORF:
8892     case BUILT_IN_LLFLOORL:
8893     case BUILT_IN_LROUND:
8894     case BUILT_IN_LROUNDF:
8895     case BUILT_IN_LROUNDL:
8896     case BUILT_IN_LLROUND:
8897     case BUILT_IN_LLROUNDF:
8898     case BUILT_IN_LLROUNDL:
8899       return fold_builtin_int_roundingfn (fndecl, arglist);
8900
8901     case BUILT_IN_LRINT:
8902     case BUILT_IN_LRINTF:
8903     case BUILT_IN_LRINTL:
8904     case BUILT_IN_LLRINT:
8905     case BUILT_IN_LLRINTF:
8906     case BUILT_IN_LLRINTL:
8907       return fold_fixed_mathfn (fndecl, arglist);
8908
8909     case BUILT_IN_FFS:
8910     case BUILT_IN_FFSL:
8911     case BUILT_IN_FFSLL:
8912     case BUILT_IN_CLZ:
8913     case BUILT_IN_CLZL:
8914     case BUILT_IN_CLZLL:
8915     case BUILT_IN_CTZ:
8916     case BUILT_IN_CTZL:
8917     case BUILT_IN_CTZLL:
8918     case BUILT_IN_POPCOUNT:
8919     case BUILT_IN_POPCOUNTL:
8920     case BUILT_IN_POPCOUNTLL:
8921     case BUILT_IN_PARITY:
8922     case BUILT_IN_PARITYL:
8923     case BUILT_IN_PARITYLL:
8924       return fold_builtin_bitop (fndecl, arglist);
8925
8926     case BUILT_IN_MEMCPY:
8927       return fold_builtin_memcpy (fndecl, arglist);
8928
8929     case BUILT_IN_MEMPCPY:
8930       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8931
8932     case BUILT_IN_MEMMOVE:
8933       return fold_builtin_memmove (arglist, type);
8934
8935     case BUILT_IN_SIGNBIT:
8936     case BUILT_IN_SIGNBITF:
8937     case BUILT_IN_SIGNBITL:
8938       return fold_builtin_signbit (fndecl, arglist);
8939
8940     case BUILT_IN_ISASCII:
8941       return fold_builtin_isascii (arglist);
8942
8943     case BUILT_IN_TOASCII:
8944       return fold_builtin_toascii (arglist);
8945
8946     case BUILT_IN_ISDIGIT:
8947       return fold_builtin_isdigit (arglist);
8948
8949     case BUILT_IN_COPYSIGN:
8950     case BUILT_IN_COPYSIGNF:
8951     case BUILT_IN_COPYSIGNL:
8952       return fold_builtin_copysign (fndecl, arglist, type);
8953
8954     case BUILT_IN_FINITE:
8955     case BUILT_IN_FINITEF:
8956     case BUILT_IN_FINITEL:
8957       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8958
8959     case BUILT_IN_ISINF:
8960     case BUILT_IN_ISINFF:
8961     case BUILT_IN_ISINFL:
8962       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8963
8964     case BUILT_IN_ISNAN:
8965     case BUILT_IN_ISNANF:
8966     case BUILT_IN_ISNANL:
8967       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8968
8969     case BUILT_IN_ISGREATER:
8970       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8971     case BUILT_IN_ISGREATEREQUAL:
8972       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8973     case BUILT_IN_ISLESS:
8974       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8975     case BUILT_IN_ISLESSEQUAL:
8976       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8977     case BUILT_IN_ISLESSGREATER:
8978       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8979     case BUILT_IN_ISUNORDERED:
8980       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8981                                          NOP_EXPR);
8982
8983       /* We do the folding for va_start in the expander.  */
8984     case BUILT_IN_VA_START:
8985       break;
8986
8987     case BUILT_IN_OBJECT_SIZE:
8988       return fold_builtin_object_size (arglist);
8989     case BUILT_IN_MEMCPY_CHK:
8990     case BUILT_IN_MEMPCPY_CHK:
8991     case BUILT_IN_MEMMOVE_CHK:
8992     case BUILT_IN_MEMSET_CHK:
8993       return fold_builtin_memory_chk (fndecl, arglist, NULL_TREE, ignore,
8994                                       DECL_FUNCTION_CODE (fndecl));
8995     case BUILT_IN_STRCPY_CHK:
8996     case BUILT_IN_STPCPY_CHK:
8997       return fold_builtin_stxcpy_chk (fndecl, arglist, NULL_TREE, ignore,
8998                                       DECL_FUNCTION_CODE (fndecl));
8999     case BUILT_IN_STRNCPY_CHK:
9000       return fold_builtin_strncpy_chk (arglist, NULL_TREE);
9001     case BUILT_IN_STRCAT_CHK:
9002       return fold_builtin_strcat_chk (fndecl, arglist);
9003     case BUILT_IN_STRNCAT_CHK:
9004       return fold_builtin_strncat_chk (fndecl, arglist);
9005     case BUILT_IN_SPRINTF_CHK:
9006     case BUILT_IN_VSPRINTF_CHK:
9007       return fold_builtin_sprintf_chk (arglist, DECL_FUNCTION_CODE (fndecl));
9008     case BUILT_IN_SNPRINTF_CHK:
9009     case BUILT_IN_VSNPRINTF_CHK:
9010       return fold_builtin_snprintf_chk (arglist, NULL_TREE,
9011                                         DECL_FUNCTION_CODE (fndecl));
9012
9013     case BUILT_IN_PRINTF:
9014     case BUILT_IN_PRINTF_UNLOCKED:
9015     case BUILT_IN_VPRINTF:
9016     case BUILT_IN_PRINTF_CHK:
9017     case BUILT_IN_VPRINTF_CHK:
9018       return fold_builtin_printf (fndecl, arglist, ignore,
9019                                   DECL_FUNCTION_CODE (fndecl));
9020
9021     case BUILT_IN_FPRINTF:
9022     case BUILT_IN_FPRINTF_UNLOCKED:
9023     case BUILT_IN_VFPRINTF:
9024     case BUILT_IN_FPRINTF_CHK:
9025     case BUILT_IN_VFPRINTF_CHK:
9026       return fold_builtin_fprintf (fndecl, arglist, ignore,
9027                                    DECL_FUNCTION_CODE (fndecl));
9028
9029     default:
9030       break;
9031     }
9032
9033   return 0;
9034 }
9035
9036 /* A wrapper function for builtin folding that prevents warnings for
9037    "statement without effect" and the like, caused by removing the
9038    call node earlier than the warning is generated.  */
9039
9040 tree
9041 fold_builtin (tree fndecl, tree arglist, bool ignore)
9042 {
9043   tree exp = fold_builtin_1 (fndecl, arglist, ignore);
9044   if (exp)
9045     {
9046       exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
9047       TREE_NO_WARNING (exp) = 1;
9048     }
9049
9050   return exp;
9051 }
9052
9053 /* Conveniently construct a function call expression.  */
9054
9055 tree
9056 build_function_call_expr (tree fn, tree arglist)
9057 {
9058   tree call_expr;
9059
9060   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
9061   return fold_build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
9062                       call_expr, arglist, NULL_TREE);
9063 }
9064
9065 /* This function validates the types of a function call argument list
9066    represented as a tree chain of parameters against a specified list
9067    of tree_codes.  If the last specifier is a 0, that represents an
9068    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
9069
9070 static int
9071 validate_arglist (tree arglist, ...)
9072 {
9073   enum tree_code code;
9074   int res = 0;
9075   va_list ap;
9076
9077   va_start (ap, arglist);
9078
9079   do
9080     {
9081       code = va_arg (ap, enum tree_code);
9082       switch (code)
9083         {
9084         case 0:
9085           /* This signifies an ellipses, any further arguments are all ok.  */
9086           res = 1;
9087           goto end;
9088         case VOID_TYPE:
9089           /* This signifies an endlink, if no arguments remain, return
9090              true, otherwise return false.  */
9091           res = arglist == 0;
9092           goto end;
9093         default:
9094           /* If no parameters remain or the parameter's code does not
9095              match the specified code, return false.  Otherwise continue
9096              checking any remaining arguments.  */
9097           if (arglist == 0)
9098             goto end;
9099           if (code == POINTER_TYPE)
9100             {
9101               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
9102                 goto end;
9103             }
9104           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
9105             goto end;
9106           break;
9107         }
9108       arglist = TREE_CHAIN (arglist);
9109     }
9110   while (1);
9111
9112   /* We need gotos here since we can only have one VA_CLOSE in a
9113      function.  */
9114  end: ;
9115   va_end (ap);
9116
9117   return res;
9118 }
9119
9120 /* Default target-specific builtin expander that does nothing.  */
9121
9122 rtx
9123 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
9124                         rtx target ATTRIBUTE_UNUSED,
9125                         rtx subtarget ATTRIBUTE_UNUSED,
9126                         enum machine_mode mode ATTRIBUTE_UNUSED,
9127                         int ignore ATTRIBUTE_UNUSED)
9128 {
9129   return NULL_RTX;
9130 }
9131
9132 /* Returns true is EXP represents data that would potentially reside
9133    in a readonly section.  */
9134
9135 static bool
9136 readonly_data_expr (tree exp)
9137 {
9138   STRIP_NOPS (exp);
9139
9140   if (TREE_CODE (exp) != ADDR_EXPR)
9141     return false;
9142
9143   exp = get_base_address (TREE_OPERAND (exp, 0));
9144   if (!exp)
9145     return false;
9146
9147   /* Make sure we call decl_readonly_section only for trees it
9148      can handle (since it returns true for everything it doesn't
9149      understand).  */
9150   if (TREE_CODE (exp) == STRING_CST
9151       || TREE_CODE (exp) == CONSTRUCTOR
9152       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
9153     return decl_readonly_section (exp, 0);
9154   else
9155     return false;
9156 }
9157
9158 /* Simplify a call to the strstr builtin.
9159
9160    Return 0 if no simplification was possible, otherwise return the
9161    simplified form of the call as a tree.
9162
9163    The simplified form may be a constant or other expression which
9164    computes the same value, but in a more efficient manner (including
9165    calls to other builtin functions).
9166
9167    The call may contain arguments which need to be evaluated, but
9168    which are not useful to determine the result of the call.  In
9169    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9170    COMPOUND_EXPR will be an argument which must be evaluated.
9171    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9172    COMPOUND_EXPR in the chain will contain the tree for the simplified
9173    form of the builtin function call.  */
9174
9175 static tree
9176 fold_builtin_strstr (tree arglist, tree type)
9177 {
9178   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9179     return 0;
9180   else
9181     {
9182       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9183       tree fn;
9184       const char *p1, *p2;
9185
9186       p2 = c_getstr (s2);
9187       if (p2 == NULL)
9188         return 0;
9189
9190       p1 = c_getstr (s1);
9191       if (p1 != NULL)
9192         {
9193           const char *r = strstr (p1, p2);
9194           tree tem;
9195
9196           if (r == NULL)
9197             return build_int_cst (TREE_TYPE (s1), 0);
9198
9199           /* Return an offset into the constant string argument.  */
9200           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9201                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9202           return fold_convert (type, tem);
9203         }
9204
9205       /* The argument is const char *, and the result is char *, so we need
9206          a type conversion here to avoid a warning.  */
9207       if (p2[0] == '\0')
9208         return fold_convert (type, s1);
9209
9210       if (p2[1] != '\0')
9211         return 0;
9212
9213       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9214       if (!fn)
9215         return 0;
9216
9217       /* New argument list transforming strstr(s1, s2) to
9218          strchr(s1, s2[0]).  */
9219       arglist = build_tree_list (NULL_TREE,
9220                                  build_int_cst (NULL_TREE, p2[0]));
9221       arglist = tree_cons (NULL_TREE, s1, arglist);
9222       return build_function_call_expr (fn, arglist);
9223     }
9224 }
9225
9226 /* Simplify a call to the strchr builtin.
9227
9228    Return 0 if no simplification was possible, otherwise return the
9229    simplified form of the call as a tree.
9230
9231    The simplified form may be a constant or other expression which
9232    computes the same value, but in a more efficient manner (including
9233    calls to other builtin functions).
9234
9235    The call may contain arguments which need to be evaluated, but
9236    which are not useful to determine the result of the call.  In
9237    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9238    COMPOUND_EXPR will be an argument which must be evaluated.
9239    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9240    COMPOUND_EXPR in the chain will contain the tree for the simplified
9241    form of the builtin function call.  */
9242
9243 static tree
9244 fold_builtin_strchr (tree arglist, tree type)
9245 {
9246   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9247     return 0;
9248   else
9249     {
9250       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9251       const char *p1;
9252
9253       if (TREE_CODE (s2) != INTEGER_CST)
9254         return 0;
9255
9256       p1 = c_getstr (s1);
9257       if (p1 != NULL)
9258         {
9259           char c;
9260           const char *r;
9261           tree tem;
9262
9263           if (target_char_cast (s2, &c))
9264             return 0;
9265
9266           r = strchr (p1, c);
9267
9268           if (r == NULL)
9269             return build_int_cst (TREE_TYPE (s1), 0);
9270
9271           /* Return an offset into the constant string argument.  */
9272           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9273                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9274           return fold_convert (type, tem);
9275         }
9276       return 0;
9277     }
9278 }
9279
9280 /* Simplify a call to the strrchr builtin.
9281
9282    Return 0 if no simplification was possible, otherwise return the
9283    simplified form of the call as a tree.
9284
9285    The simplified form may be a constant or other expression which
9286    computes the same value, but in a more efficient manner (including
9287    calls to other builtin functions).
9288
9289    The call may contain arguments which need to be evaluated, but
9290    which are not useful to determine the result of the call.  In
9291    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9292    COMPOUND_EXPR will be an argument which must be evaluated.
9293    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9294    COMPOUND_EXPR in the chain will contain the tree for the simplified
9295    form of the builtin function call.  */
9296
9297 static tree
9298 fold_builtin_strrchr (tree arglist, tree type)
9299 {
9300   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9301     return 0;
9302   else
9303     {
9304       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9305       tree fn;
9306       const char *p1;
9307
9308       if (TREE_CODE (s2) != INTEGER_CST)
9309         return 0;
9310
9311       p1 = c_getstr (s1);
9312       if (p1 != NULL)
9313         {
9314           char c;
9315           const char *r;
9316           tree tem;
9317
9318           if (target_char_cast (s2, &c))
9319             return 0;
9320
9321           r = strrchr (p1, c);
9322
9323           if (r == NULL)
9324             return build_int_cst (TREE_TYPE (s1), 0);
9325
9326           /* Return an offset into the constant string argument.  */
9327           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9328                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9329           return fold_convert (type, tem);
9330         }
9331
9332       if (! integer_zerop (s2))
9333         return 0;
9334
9335       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9336       if (!fn)
9337         return 0;
9338
9339       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
9340       return build_function_call_expr (fn, arglist);
9341     }
9342 }
9343
9344 /* Simplify a call to the strpbrk builtin.
9345
9346    Return 0 if no simplification was possible, otherwise return the
9347    simplified form of the call as a tree.
9348
9349    The simplified form may be a constant or other expression which
9350    computes the same value, but in a more efficient manner (including
9351    calls to other builtin functions).
9352
9353    The call may contain arguments which need to be evaluated, but
9354    which are not useful to determine the result of the call.  In
9355    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9356    COMPOUND_EXPR will be an argument which must be evaluated.
9357    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9358    COMPOUND_EXPR in the chain will contain the tree for the simplified
9359    form of the builtin function call.  */
9360
9361 static tree
9362 fold_builtin_strpbrk (tree arglist, tree type)
9363 {
9364   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9365     return 0;
9366   else
9367     {
9368       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9369       tree fn;
9370       const char *p1, *p2;
9371
9372       p2 = c_getstr (s2);
9373       if (p2 == NULL)
9374         return 0;
9375
9376       p1 = c_getstr (s1);
9377       if (p1 != NULL)
9378         {
9379           const char *r = strpbrk (p1, p2);
9380           tree tem;
9381
9382           if (r == NULL)
9383             return build_int_cst (TREE_TYPE (s1), 0);
9384
9385           /* Return an offset into the constant string argument.  */
9386           tem = fold_build2 (PLUS_EXPR, TREE_TYPE (s1),
9387                              s1, build_int_cst (TREE_TYPE (s1), r - p1));
9388           return fold_convert (type, tem);
9389         }
9390
9391       if (p2[0] == '\0')
9392         /* strpbrk(x, "") == NULL.
9393            Evaluate and ignore s1 in case it had side-effects.  */
9394         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
9395
9396       if (p2[1] != '\0')
9397         return 0;  /* Really call strpbrk.  */
9398
9399       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
9400       if (!fn)
9401         return 0;
9402
9403       /* New argument list transforming strpbrk(s1, s2) to
9404          strchr(s1, s2[0]).  */
9405       arglist = build_tree_list (NULL_TREE,
9406                                  build_int_cst (NULL_TREE, p2[0]));
9407       arglist = tree_cons (NULL_TREE, s1, arglist);
9408       return build_function_call_expr (fn, arglist);
9409     }
9410 }
9411
9412 /* Simplify a call to the strcat builtin.
9413
9414    Return 0 if no simplification was possible, otherwise return the
9415    simplified form of the call as a tree.
9416
9417    The simplified form may be a constant or other expression which
9418    computes the same value, but in a more efficient manner (including
9419    calls to other builtin functions).
9420
9421    The call may contain arguments which need to be evaluated, but
9422    which are not useful to determine the result of the call.  In
9423    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9424    COMPOUND_EXPR will be an argument which must be evaluated.
9425    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9426    COMPOUND_EXPR in the chain will contain the tree for the simplified
9427    form of the builtin function call.  */
9428
9429 static tree
9430 fold_builtin_strcat (tree arglist)
9431 {
9432   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9433     return 0;
9434   else
9435     {
9436       tree dst = TREE_VALUE (arglist),
9437         src = TREE_VALUE (TREE_CHAIN (arglist));
9438       const char *p = c_getstr (src);
9439
9440       /* If the string length is zero, return the dst parameter.  */
9441       if (p && *p == '\0')
9442         return dst;
9443
9444       return 0;
9445     }
9446 }
9447
9448 /* Simplify a call to the strncat builtin.
9449
9450    Return 0 if no simplification was possible, otherwise return the
9451    simplified form of the call as a tree.
9452
9453    The simplified form may be a constant or other expression which
9454    computes the same value, but in a more efficient manner (including
9455    calls to other builtin functions).
9456
9457    The call may contain arguments which need to be evaluated, but
9458    which are not useful to determine the result of the call.  In
9459    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9460    COMPOUND_EXPR will be an argument which must be evaluated.
9461    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9462    COMPOUND_EXPR in the chain will contain the tree for the simplified
9463    form of the builtin function call.  */
9464
9465 static tree
9466 fold_builtin_strncat (tree arglist)
9467 {
9468   if (!validate_arglist (arglist,
9469                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9470     return 0;
9471   else
9472     {
9473       tree dst = TREE_VALUE (arglist);
9474       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9475       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9476       const char *p = c_getstr (src);
9477
9478       /* If the requested length is zero, or the src parameter string
9479          length is zero, return the dst parameter.  */
9480       if (integer_zerop (len) || (p && *p == '\0'))
9481         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9482
9483       /* If the requested len is greater than or equal to the string
9484          length, call strcat.  */
9485       if (TREE_CODE (len) == INTEGER_CST && p
9486           && compare_tree_int (len, strlen (p)) >= 0)
9487         {
9488           tree newarglist
9489             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9490           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9491
9492           /* If the replacement _DECL isn't initialized, don't do the
9493              transformation.  */
9494           if (!fn)
9495             return 0;
9496
9497           return build_function_call_expr (fn, newarglist);
9498         }
9499       return 0;
9500     }
9501 }
9502
9503 /* Simplify a call to the strspn builtin.
9504
9505    Return 0 if no simplification was possible, otherwise return the
9506    simplified form of the call as a tree.
9507
9508    The simplified form may be a constant or other expression which
9509    computes the same value, but in a more efficient manner (including
9510    calls to other builtin functions).
9511
9512    The call may contain arguments which need to be evaluated, but
9513    which are not useful to determine the result of the call.  In
9514    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9515    COMPOUND_EXPR will be an argument which must be evaluated.
9516    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9517    COMPOUND_EXPR in the chain will contain the tree for the simplified
9518    form of the builtin function call.  */
9519
9520 static tree
9521 fold_builtin_strspn (tree arglist)
9522 {
9523   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9524     return 0;
9525   else
9526     {
9527       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9528       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9529
9530       /* If both arguments are constants, evaluate at compile-time.  */
9531       if (p1 && p2)
9532         {
9533           const size_t r = strspn (p1, p2);
9534           return size_int (r);
9535         }
9536
9537       /* If either argument is "", return 0.  */
9538       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9539         /* Evaluate and ignore both arguments in case either one has
9540            side-effects.  */
9541         return omit_two_operands (integer_type_node, integer_zero_node,
9542                                   s1, s2);
9543       return 0;
9544     }
9545 }
9546
9547 /* Simplify a call to the strcspn builtin.
9548
9549    Return 0 if no simplification was possible, otherwise return the
9550    simplified form of the call as a tree.
9551
9552    The simplified form may be a constant or other expression which
9553    computes the same value, but in a more efficient manner (including
9554    calls to other builtin functions).
9555
9556    The call may contain arguments which need to be evaluated, but
9557    which are not useful to determine the result of the call.  In
9558    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9559    COMPOUND_EXPR will be an argument which must be evaluated.
9560    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9561    COMPOUND_EXPR in the chain will contain the tree for the simplified
9562    form of the builtin function call.  */
9563
9564 static tree
9565 fold_builtin_strcspn (tree arglist)
9566 {
9567   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9568     return 0;
9569   else
9570     {
9571       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9572       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9573
9574       /* If both arguments are constants, evaluate at compile-time.  */
9575       if (p1 && p2)
9576         {
9577           const size_t r = strcspn (p1, p2);
9578           return size_int (r);
9579         }
9580
9581       /* If the first argument is "", return 0.  */
9582       if (p1 && *p1 == '\0')
9583         {
9584           /* Evaluate and ignore argument s2 in case it has
9585              side-effects.  */
9586           return omit_one_operand (integer_type_node,
9587                                    integer_zero_node, s2);
9588         }
9589
9590       /* If the second argument is "", return __builtin_strlen(s1).  */
9591       if (p2 && *p2 == '\0')
9592         {
9593           tree newarglist = build_tree_list (NULL_TREE, s1),
9594             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9595
9596           /* If the replacement _DECL isn't initialized, don't do the
9597              transformation.  */
9598           if (!fn)
9599             return 0;
9600
9601           return build_function_call_expr (fn, newarglist);
9602         }
9603       return 0;
9604     }
9605 }
9606
9607 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9608    by the builtin will be ignored.  UNLOCKED is true is true if this
9609    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9610    the known length of the string.  Return NULL_TREE if no simplification
9611    was possible.  */
9612
9613 tree
9614 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9615 {
9616   tree fn;
9617   /* If we're using an unlocked function, assume the other unlocked
9618      functions exist explicitly.  */
9619   tree const fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9620     : implicit_built_in_decls[BUILT_IN_FPUTC];
9621   tree const fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9622     : implicit_built_in_decls[BUILT_IN_FWRITE];
9623
9624   /* If the return value is used, or the replacement _DECL isn't
9625      initialized, don't do the transformation.  */
9626   if (!ignore || !fn_fputc || !fn_fwrite)
9627     return 0;
9628
9629   /* Verify the arguments in the original call.  */
9630   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9631     return 0;
9632
9633   if (! len)
9634     len = c_strlen (TREE_VALUE (arglist), 0);
9635
9636   /* Get the length of the string passed to fputs.  If the length
9637      can't be determined, punt.  */
9638   if (!len
9639       || TREE_CODE (len) != INTEGER_CST)
9640     return 0;
9641
9642   switch (compare_tree_int (len, 1))
9643     {
9644     case -1: /* length is 0, delete the call entirely .  */
9645       return omit_one_operand (integer_type_node, integer_zero_node,
9646                                TREE_VALUE (TREE_CHAIN (arglist)));
9647
9648     case 0: /* length is 1, call fputc.  */
9649       {
9650         const char *p = c_getstr (TREE_VALUE (arglist));
9651
9652         if (p != NULL)
9653           {
9654             /* New argument list transforming fputs(string, stream) to
9655                fputc(string[0], stream).  */
9656             arglist = build_tree_list (NULL_TREE,
9657                                        TREE_VALUE (TREE_CHAIN (arglist)));
9658             arglist = tree_cons (NULL_TREE,
9659                                  build_int_cst (NULL_TREE, p[0]),
9660                                  arglist);
9661             fn = fn_fputc;
9662             break;
9663           }
9664       }
9665       /* FALLTHROUGH */
9666     case 1: /* length is greater than 1, call fwrite.  */
9667       {
9668         tree string_arg;
9669
9670         /* If optimizing for size keep fputs.  */
9671         if (optimize_size)
9672           return 0;
9673         string_arg = TREE_VALUE (arglist);
9674         /* New argument list transforming fputs(string, stream) to
9675            fwrite(string, 1, len, stream).  */
9676         arglist = build_tree_list (NULL_TREE,
9677                                    TREE_VALUE (TREE_CHAIN (arglist)));
9678         arglist = tree_cons (NULL_TREE, len, arglist);
9679         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9680         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9681         fn = fn_fwrite;
9682         break;
9683       }
9684     default:
9685       gcc_unreachable ();
9686     }
9687
9688   /* These optimizations are only performed when the result is ignored,
9689      hence there's no need to cast the result to integer_type_node.  */
9690   return build_function_call_expr (fn, arglist);
9691 }
9692
9693 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
9694    produced.  False otherwise.  This is done so that we don't output the error
9695    or warning twice or three times.  */
9696 bool
9697 fold_builtin_next_arg (tree arglist)
9698 {
9699   tree fntype = TREE_TYPE (current_function_decl);
9700
9701   if (TYPE_ARG_TYPES (fntype) == 0
9702       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9703           == void_type_node))
9704     {
9705       error ("%<va_start%> used in function with fixed args");
9706       return true;
9707     }
9708   else if (!arglist)
9709     {
9710       /* Evidently an out of date version of <stdarg.h>; can't validate
9711          va_start's second argument, but can still work as intended.  */
9712       warning (0, "%<__builtin_next_arg%> called without an argument");
9713       return true;
9714     }
9715   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
9716      when we checked the arguments and if needed issued a warning.  */
9717   else if (!TREE_CHAIN (arglist)
9718            || !integer_zerop (TREE_VALUE (arglist))
9719            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
9720            || TREE_CHAIN (TREE_CHAIN (arglist)))
9721     {
9722       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9723       tree arg = TREE_VALUE (arglist);
9724
9725       if (TREE_CHAIN (arglist))
9726         {
9727           error ("%<va_start%> used with too many arguments");
9728           return true;
9729         }
9730
9731       /* Strip off all nops for the sake of the comparison.  This
9732          is not quite the same as STRIP_NOPS.  It does more.
9733          We must also strip off INDIRECT_EXPR for C++ reference
9734          parameters.  */
9735       while (TREE_CODE (arg) == NOP_EXPR
9736              || TREE_CODE (arg) == CONVERT_EXPR
9737              || TREE_CODE (arg) == NON_LVALUE_EXPR
9738              || TREE_CODE (arg) == INDIRECT_REF)
9739         arg = TREE_OPERAND (arg, 0);
9740       if (arg != last_parm)
9741         {
9742           /* FIXME: Sometimes with the tree optimizers we can get the
9743              not the last argument even though the user used the last
9744              argument.  We just warn and set the arg to be the last
9745              argument so that we will get wrong-code because of
9746              it.  */
9747           warning (0, "second parameter of %<va_start%> not last named argument");
9748         }
9749       /* We want to verify the second parameter just once before the tree
9750          optimizers are run and then avoid keeping it in the tree,
9751          as otherwise we could warn even for correct code like:
9752          void foo (int i, ...)
9753          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9754       TREE_VALUE (arglist) = integer_zero_node;
9755       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9756     }
9757   return false;
9758 }
9759
9760
9761 /* Simplify a call to the sprintf builtin.
9762
9763    Return 0 if no simplification was possible, otherwise return the
9764    simplified form of the call as a tree.  If IGNORED is true, it means that
9765    the caller does not use the returned value of the function.  */
9766
9767 static tree
9768 fold_builtin_sprintf (tree arglist, int ignored)
9769 {
9770   tree call, retval, dest, fmt;
9771   const char *fmt_str = NULL;
9772
9773   /* Verify the required arguments in the original call.  We deal with two
9774      types of sprintf() calls: 'sprintf (str, fmt)' and
9775      'sprintf (dest, "%s", orig)'.  */
9776   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9777       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9778                             VOID_TYPE))
9779     return NULL_TREE;
9780
9781   /* Get the destination string and the format specifier.  */
9782   dest = TREE_VALUE (arglist);
9783   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9784
9785   /* Check whether the format is a literal string constant.  */
9786   fmt_str = c_getstr (fmt);
9787   if (fmt_str == NULL)
9788     return NULL_TREE;
9789
9790   call = NULL_TREE;
9791   retval = NULL_TREE;
9792
9793   /* If the format doesn't contain % args or %%, use strcpy.  */
9794   if (strchr (fmt_str, '%') == NULL)
9795     {
9796       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9797
9798       if (!fn)
9799         return NULL_TREE;
9800
9801       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9802          'format' is known to contain no % formats.  */
9803       arglist = build_tree_list (NULL_TREE, fmt);
9804       arglist = tree_cons (NULL_TREE, dest, arglist);
9805       call = build_function_call_expr (fn, arglist);
9806       if (!ignored)
9807         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9808     }
9809
9810   /* If the format is "%s", use strcpy if the result isn't used.  */
9811   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9812     {
9813       tree fn, orig;
9814       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9815
9816       if (!fn)
9817         return NULL_TREE;
9818
9819       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9820       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9821       arglist = build_tree_list (NULL_TREE, orig);
9822       arglist = tree_cons (NULL_TREE, dest, arglist);
9823       if (!ignored)
9824         {
9825           retval = c_strlen (orig, 1);
9826           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9827             return NULL_TREE;
9828         }
9829       call = build_function_call_expr (fn, arglist);
9830     }
9831
9832   if (call && retval)
9833     {
9834       retval = convert
9835         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9836          retval);
9837       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9838     }
9839   else
9840     return call;
9841 }
9842
9843 /* Expand a call to __builtin_object_size.  */
9844
9845 rtx
9846 expand_builtin_object_size (tree exp)
9847 {
9848   tree ost;
9849   int object_size_type;
9850   tree fndecl = get_callee_fndecl (exp);
9851   tree arglist = TREE_OPERAND (exp, 1);
9852   location_t locus = EXPR_LOCATION (exp);
9853
9854   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9855     {
9856       error ("%Hfirst argument of %D must be a pointer, second integer constant",
9857              &locus, fndecl);
9858       expand_builtin_trap ();
9859       return const0_rtx;
9860     }
9861
9862   ost = TREE_VALUE (TREE_CHAIN (arglist));
9863   STRIP_NOPS (ost);
9864
9865   if (TREE_CODE (ost) != INTEGER_CST
9866       || tree_int_cst_sgn (ost) < 0
9867       || compare_tree_int (ost, 3) > 0)
9868     {
9869       error ("%Hlast argument of %D is not integer constant between 0 and 3",
9870              &locus, fndecl);
9871       expand_builtin_trap ();
9872       return const0_rtx;
9873     }
9874
9875   object_size_type = tree_low_cst (ost, 0);
9876
9877   return object_size_type < 2 ? constm1_rtx : const0_rtx;
9878 }
9879
9880 /* Expand EXP, a call to the __mem{cpy,pcpy,move,set}_chk builtin.
9881    FCODE is the BUILT_IN_* to use.
9882    Return 0 if we failed; the caller should emit a normal call,
9883    otherwise try to get the result in TARGET, if convenient (and in
9884    mode MODE if that's convenient).  */
9885
9886 static rtx
9887 expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
9888                            enum built_in_function fcode)
9889 {
9890   tree arglist = TREE_OPERAND (exp, 1);
9891   tree dest, src, len, size;
9892
9893   if (!validate_arglist (arglist,
9894                          POINTER_TYPE,
9895                          fcode == BUILT_IN_MEMSET_CHK
9896                          ? INTEGER_TYPE : POINTER_TYPE,
9897                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
9898     return 0;
9899
9900   dest = TREE_VALUE (arglist);
9901   src = TREE_VALUE (TREE_CHAIN (arglist));
9902   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9903   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
9904
9905   if (! host_integerp (size, 1))
9906     return 0;
9907
9908   if (host_integerp (len, 1) || integer_all_onesp (size))
9909     {
9910       tree fn;
9911
9912       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
9913         {
9914           location_t locus = EXPR_LOCATION (exp);
9915           warning (0, "%Hcall to %D will always overflow destination buffer",
9916                    &locus, get_callee_fndecl (exp));
9917           return 0;
9918         }
9919
9920       arglist = build_tree_list (NULL_TREE, len);
9921       arglist = tree_cons (NULL_TREE, src, arglist);
9922       arglist = tree_cons (NULL_TREE, dest, arglist);
9923
9924       fn = NULL_TREE;
9925       /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
9926          mem{cpy,pcpy,move,set} is available.  */
9927       switch (fcode)
9928         {
9929         case BUILT_IN_MEMCPY_CHK:
9930           fn = built_in_decls[BUILT_IN_MEMCPY];
9931           break;
9932         case BUILT_IN_MEMPCPY_CHK:
9933           fn = built_in_decls[BUILT_IN_MEMPCPY];
9934           break;
9935         case BUILT_IN_MEMMOVE_CHK:
9936           fn = built_in_decls[BUILT_IN_MEMMOVE];
9937           break;
9938         case BUILT_IN_MEMSET_CHK:
9939           fn = built_in_decls[BUILT_IN_MEMSET];
9940           break;
9941         default:
9942           break;
9943         }
9944
9945       if (! fn)
9946         return 0;
9947
9948       fn = build_function_call_expr (fn, arglist);
9949       if (TREE_CODE (fn) == CALL_EXPR)
9950         CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
9951       return expand_expr (fn, target, mode, EXPAND_NORMAL);
9952     }
9953   else if (fcode == BUILT_IN_MEMSET_CHK)
9954     return 0;
9955   else
9956     {
9957       unsigned int dest_align
9958         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
9959
9960       /* If DEST is not a pointer type, call the normal function.  */
9961       if (dest_align == 0)
9962         return 0;
9963
9964       /* If SRC and DEST are the same (and not volatile), do nothing.  */
9965       if (operand_equal_p (src, dest, 0))
9966         {
9967           tree expr;
9968
9969           if (fcode != BUILT_IN_MEMPCPY_CHK)
9970             {
9971               /* Evaluate and ignore LEN in case it has side-effects.  */
9972               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
9973               return expand_expr (dest, target, mode, EXPAND_NORMAL);
9974             }
9975
9976           len = fold_convert (TREE_TYPE (dest), len);
9977           expr = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len);
9978           return expand_expr (expr, target, mode, EXPAND_NORMAL);
9979         }
9980
9981       /* __memmove_chk special case.  */
9982       if (fcode == BUILT_IN_MEMMOVE_CHK)
9983         {
9984           unsigned int src_align
9985             = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
9986
9987           if (src_align == 0)
9988             return 0;
9989
9990           /* If src is categorized for a readonly section we can use
9991              normal __memcpy_chk.  */
9992           if (readonly_data_expr (src))
9993             {
9994               tree fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
9995               if (!fn)
9996                 return 0;
9997               fn = build_function_call_expr (fn, arglist);
9998               if (TREE_CODE (fn) == CALL_EXPR)
9999                 CALL_EXPR_TAILCALL (fn) = CALL_EXPR_TAILCALL (exp);
10000               return expand_expr (fn, target, mode, EXPAND_NORMAL);
10001             }
10002         }
10003       return 0;
10004     }
10005 }
10006
10007 /* Emit warning if a buffer overflow is detected at compile time.  */
10008
10009 static void
10010 maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
10011 {
10012   int arg_mask, is_strlen = 0;
10013   tree arglist = TREE_OPERAND (exp, 1), a;
10014   tree len, size;
10015   location_t locus;
10016
10017   switch (fcode)
10018     {
10019     case BUILT_IN_STRCPY_CHK:
10020     case BUILT_IN_STPCPY_CHK:
10021     /* For __strcat_chk the warning will be emitted only if overflowing
10022        by at least strlen (dest) + 1 bytes.  */
10023     case BUILT_IN_STRCAT_CHK:
10024       arg_mask = 6;
10025       is_strlen = 1;
10026       break;
10027     case BUILT_IN_STRNCPY_CHK:
10028       arg_mask = 12;
10029       break;
10030     case BUILT_IN_SNPRINTF_CHK:
10031     case BUILT_IN_VSNPRINTF_CHK:
10032       arg_mask = 10;
10033       break;
10034     default:
10035       gcc_unreachable ();
10036     }
10037
10038   len = NULL_TREE;
10039   size = NULL_TREE;
10040   for (a = arglist; a && arg_mask; a = TREE_CHAIN (a), arg_mask >>= 1)
10041     if (arg_mask & 1)
10042       {
10043         if (len)
10044           size = a;
10045         else
10046           len = a;
10047       }
10048
10049   if (!len || !size)
10050     return;
10051
10052   len = TREE_VALUE (len);
10053   size = TREE_VALUE (size);
10054
10055   if (! host_integerp (size, 1) || integer_all_onesp (size))
10056     return;
10057
10058   if (is_strlen)
10059     {
10060       len = c_strlen (len, 1);
10061       if (! len || ! host_integerp (len, 1) || tree_int_cst_lt (len, size))
10062         return;
10063     }
10064   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
10065     return;
10066
10067   locus = EXPR_LOCATION (exp);
10068   warning (0, "%Hcall to %D will always overflow destination buffer",
10069            &locus, get_callee_fndecl (exp));
10070 }
10071
10072 /* Emit warning if a buffer overflow is detected at compile time
10073    in __sprintf_chk/__vsprintf_chk calls.  */
10074
10075 static void
10076 maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
10077 {
10078   tree arglist = TREE_OPERAND (exp, 1);
10079   tree dest, size, len, fmt, flag;
10080   const char *fmt_str;
10081
10082   /* Verify the required arguments in the original call.  */
10083   if (! arglist)
10084     return;
10085   dest = TREE_VALUE (arglist);
10086   arglist = TREE_CHAIN (arglist);
10087   if (! arglist)
10088     return;
10089   flag = TREE_VALUE (arglist);
10090   arglist = TREE_CHAIN (arglist);
10091   if (! arglist)
10092     return;
10093   size = TREE_VALUE (arglist);
10094   arglist = TREE_CHAIN (arglist);
10095   if (! arglist)
10096     return;
10097   fmt = TREE_VALUE (arglist);
10098   arglist = TREE_CHAIN (arglist);
10099
10100   if (! host_integerp (size, 1) || integer_all_onesp (size))
10101     return;
10102
10103   /* Check whether the format is a literal string constant.  */
10104   fmt_str = c_getstr (fmt);
10105   if (fmt_str == NULL)
10106     return;
10107
10108   /* If the format doesn't contain % args or %%, we know its size.  */
10109   if (strchr (fmt_str, '%') == 0)
10110     len = build_int_cstu (size_type_node, strlen (fmt_str));
10111   /* If the format is "%s" and first ... argument is a string literal,
10112      we know it too.  */
10113   else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10114     {
10115       tree arg;
10116
10117       if (! arglist)
10118         return;
10119       arg = TREE_VALUE (arglist);
10120       if (! POINTER_TYPE_P (TREE_TYPE (arg)))
10121         return;
10122
10123       len = c_strlen (arg, 1);
10124       if (!len || ! host_integerp (len, 1))
10125         return;
10126     }
10127   else
10128     return;
10129
10130   if (! tree_int_cst_lt (len, size))
10131     {
10132       location_t locus = EXPR_LOCATION (exp);
10133       warning (0, "%Hcall to %D will always overflow destination buffer",
10134                &locus, get_callee_fndecl (exp));
10135     }
10136 }
10137
10138 /* Fold a call to __builtin_object_size, if possible.  */
10139
10140 tree
10141 fold_builtin_object_size (tree arglist)
10142 {
10143   tree ptr, ost, ret = 0;
10144   int object_size_type;
10145
10146   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
10147     return 0;
10148
10149   ptr = TREE_VALUE (arglist);
10150   ost = TREE_VALUE (TREE_CHAIN (arglist));
10151   STRIP_NOPS (ost);
10152
10153   if (TREE_CODE (ost) != INTEGER_CST
10154       || tree_int_cst_sgn (ost) < 0
10155       || compare_tree_int (ost, 3) > 0)
10156     return 0;
10157
10158   object_size_type = tree_low_cst (ost, 0);
10159
10160   /* __builtin_object_size doesn't evaluate side-effects in its arguments;
10161      if there are any side-effects, it returns (size_t) -1 for types 0 and 1
10162      and (size_t) 0 for types 2 and 3.  */
10163   if (TREE_SIDE_EFFECTS (ptr))
10164     return fold_convert (size_type_node,
10165                          object_size_type < 2
10166                          ? integer_minus_one_node : integer_zero_node);
10167
10168   if (TREE_CODE (ptr) == ADDR_EXPR)
10169     ret = build_int_cstu (size_type_node,
10170                         compute_builtin_object_size (ptr, object_size_type));
10171
10172   else if (TREE_CODE (ptr) == SSA_NAME)
10173     {
10174       unsigned HOST_WIDE_INT bytes;
10175
10176       /* If object size is not known yet, delay folding until
10177        later.  Maybe subsequent passes will help determining
10178        it.  */
10179       bytes = compute_builtin_object_size (ptr, object_size_type);
10180       if (bytes != (unsigned HOST_WIDE_INT) (object_size_type < 2
10181                                              ? -1 : 0))
10182         ret = build_int_cstu (size_type_node, bytes);
10183     }
10184
10185   if (ret)
10186     {
10187       ret = force_fit_type (ret, -1, false, false);
10188       if (TREE_CONSTANT_OVERFLOW (ret))
10189         ret = 0;
10190     }
10191
10192   return ret;
10193 }
10194
10195 /* Fold a call to the __mem{cpy,pcpy,move,set}_chk builtin.
10196    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10197    code of the builtin.  If MAXLEN is not NULL, it is maximum length
10198    passed as third argument.  */
10199
10200 tree
10201 fold_builtin_memory_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10202                          enum built_in_function fcode)
10203 {
10204   tree dest, src, len, size, fn;
10205
10206   if (!validate_arglist (arglist,
10207                          POINTER_TYPE,
10208                          fcode == BUILT_IN_MEMSET_CHK
10209                          ? INTEGER_TYPE : POINTER_TYPE,
10210                          INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
10211     return 0;
10212
10213   dest = TREE_VALUE (arglist);
10214   /* Actually val for __memset_chk, but it doesn't matter.  */
10215   src = TREE_VALUE (TREE_CHAIN (arglist));
10216   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10217   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10218
10219   /* If SRC and DEST are the same (and not volatile), return DEST
10220      (resp. DEST+LEN for __mempcpy_chk).  */
10221   if (fcode != BUILT_IN_MEMSET_CHK && operand_equal_p (src, dest, 0))
10222     {
10223       if (fcode != BUILT_IN_MEMPCPY_CHK)
10224         return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10225       else
10226         {
10227           tree temp = fold_convert (TREE_TYPE (dest), len);
10228           temp = fold_build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp);
10229           return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), temp);
10230         }
10231     }
10232
10233   if (! host_integerp (size, 1))
10234     return 0;
10235
10236   if (! integer_all_onesp (size))
10237     {
10238       if (! host_integerp (len, 1))
10239         {
10240           /* If LEN is not constant, try MAXLEN too.
10241              For MAXLEN only allow optimizing into non-_ocs function
10242              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10243           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10244             {
10245               if (fcode == BUILT_IN_MEMPCPY_CHK && ignore)
10246                 {
10247                   /* (void) __mempcpy_chk () can be optimized into
10248                      (void) __memcpy_chk ().  */
10249                   fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10250                   if (!fn)
10251                     return 0;
10252
10253                   return build_function_call_expr (fn, arglist);
10254                 }
10255               return 0;
10256             }
10257         }
10258       else
10259         maxlen = len;
10260
10261       if (tree_int_cst_lt (size, maxlen))
10262         return 0;
10263     }
10264
10265   arglist = build_tree_list (NULL_TREE, len);
10266   arglist = tree_cons (NULL_TREE, src, arglist);
10267   arglist = tree_cons (NULL_TREE, dest, arglist);
10268
10269   fn = NULL_TREE;
10270   /* If __builtin_mem{cpy,pcpy,move,set}_chk is used, assume
10271      mem{cpy,pcpy,move,set} is available.  */
10272   switch (fcode)
10273     {
10274     case BUILT_IN_MEMCPY_CHK:
10275       fn = built_in_decls[BUILT_IN_MEMCPY];
10276       break;
10277     case BUILT_IN_MEMPCPY_CHK:
10278       fn = built_in_decls[BUILT_IN_MEMPCPY];
10279       break;
10280     case BUILT_IN_MEMMOVE_CHK:
10281       fn = built_in_decls[BUILT_IN_MEMMOVE];
10282       break;
10283     case BUILT_IN_MEMSET_CHK:
10284       fn = built_in_decls[BUILT_IN_MEMSET];
10285       break;
10286     default:
10287       break;
10288     }
10289
10290   if (!fn)
10291     return 0;
10292
10293   return build_function_call_expr (fn, arglist);
10294 }
10295
10296 /* Fold a call to the __st[rp]cpy_chk builtin.
10297    IGNORE is true, if return value can be ignored.  FCODE is the BUILT_IN_*
10298    code of the builtin.  If MAXLEN is not NULL, it is maximum length of
10299    strings passed as second argument.  */
10300
10301 tree
10302 fold_builtin_stxcpy_chk (tree fndecl, tree arglist, tree maxlen, bool ignore,
10303                          enum built_in_function fcode)
10304 {
10305   tree dest, src, size, len, fn;
10306
10307   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10308                          VOID_TYPE))
10309     return 0;
10310
10311   dest = TREE_VALUE (arglist);
10312   src = TREE_VALUE (TREE_CHAIN (arglist));
10313   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10314
10315   /* If SRC and DEST are the same (and not volatile), return DEST.  */
10316   if (fcode == BUILT_IN_STRCPY_CHK && operand_equal_p (src, dest, 0))
10317     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
10318  
10319   if (! host_integerp (size, 1))
10320     return 0;
10321
10322   if (! integer_all_onesp (size))
10323     {
10324       len = c_strlen (src, 1);
10325       if (! len || ! host_integerp (len, 1))
10326         {
10327           /* If LEN is not constant, try MAXLEN too.
10328              For MAXLEN only allow optimizing into non-_ocs function
10329              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10330           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10331             {
10332               if (fcode == BUILT_IN_STPCPY_CHK)
10333                 {
10334                   if (! ignore)
10335                     return 0;
10336
10337                   /* If return value of __stpcpy_chk is ignored,
10338                      optimize into __strcpy_chk.  */
10339                   fn = built_in_decls[BUILT_IN_STRCPY_CHK];
10340                   if (!fn)
10341                     return 0;
10342
10343                   return build_function_call_expr (fn, arglist);
10344                 }
10345
10346               if (! len || TREE_SIDE_EFFECTS (len))
10347                 return 0;
10348
10349               /* If c_strlen returned something, but not a constant,
10350                  transform __strcpy_chk into __memcpy_chk.  */
10351               fn = built_in_decls[BUILT_IN_MEMCPY_CHK];
10352               if (!fn)
10353                 return 0;
10354
10355               len = size_binop (PLUS_EXPR, len, ssize_int (1));
10356               arglist = build_tree_list (NULL_TREE, size);
10357               arglist = tree_cons (NULL_TREE, len, arglist);
10358               arglist = tree_cons (NULL_TREE, src, arglist);
10359               arglist = tree_cons (NULL_TREE, dest, arglist);
10360               return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
10361                                    build_function_call_expr (fn, arglist));
10362             }
10363         }
10364       else
10365         maxlen = len;
10366
10367       if (! tree_int_cst_lt (maxlen, size))
10368         return 0;
10369     }
10370
10371   arglist = build_tree_list (NULL_TREE, src);
10372   arglist = tree_cons (NULL_TREE, dest, arglist);
10373
10374   /* If __builtin_st{r,p}cpy_chk is used, assume st{r,p}cpy is available.  */
10375   fn = built_in_decls[fcode == BUILT_IN_STPCPY_CHK
10376                       ? BUILT_IN_STPCPY : BUILT_IN_STRCPY];
10377   if (!fn)
10378     return 0;
10379
10380   return build_function_call_expr (fn, arglist);
10381 }
10382
10383 /* Fold a call to the __strncpy_chk builtin.
10384    If MAXLEN is not NULL, it is maximum length passed as third argument.  */
10385
10386 tree
10387 fold_builtin_strncpy_chk (tree arglist, tree maxlen)
10388 {
10389   tree dest, src, size, len, fn;
10390
10391   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10392                          INTEGER_TYPE, VOID_TYPE))
10393     return 0;
10394
10395   dest = TREE_VALUE (arglist);
10396   src = TREE_VALUE (TREE_CHAIN (arglist));
10397   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10398   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10399
10400   if (! host_integerp (size, 1))
10401     return 0;
10402
10403   if (! integer_all_onesp (size))
10404     {
10405       if (! host_integerp (len, 1))
10406         {
10407           /* If LEN is not constant, try MAXLEN too.
10408              For MAXLEN only allow optimizing into non-_ocs function
10409              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10410           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10411             return 0;
10412         }
10413       else
10414         maxlen = len;
10415
10416       if (tree_int_cst_lt (size, maxlen))
10417         return 0;
10418     }
10419
10420   arglist = build_tree_list (NULL_TREE, len);
10421   arglist = tree_cons (NULL_TREE, src, arglist);
10422   arglist = tree_cons (NULL_TREE, dest, arglist);
10423
10424   /* If __builtin_strncpy_chk is used, assume strncpy is available.  */
10425   fn = built_in_decls[BUILT_IN_STRNCPY];
10426   if (!fn)
10427     return 0;
10428
10429   return build_function_call_expr (fn, arglist);
10430 }
10431
10432 /* Fold a call to the __strcat_chk builtin FNDECL with ARGLIST.  */
10433
10434 static tree
10435 fold_builtin_strcat_chk (tree fndecl, tree arglist)
10436 {
10437   tree dest, src, size, fn;
10438   const char *p;
10439
10440   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10441                          VOID_TYPE))
10442     return 0;
10443
10444   dest = TREE_VALUE (arglist);
10445   src = TREE_VALUE (TREE_CHAIN (arglist));
10446   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10447
10448   p = c_getstr (src);
10449   /* If the SRC parameter is "", return DEST.  */
10450   if (p && *p == '\0')
10451     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10452
10453   if (! host_integerp (size, 1) || ! integer_all_onesp (size))
10454     return 0;
10455
10456   arglist = build_tree_list (NULL_TREE, src);
10457   arglist = tree_cons (NULL_TREE, dest, arglist);
10458
10459   /* If __builtin_strcat_chk is used, assume strcat is available.  */
10460   fn = built_in_decls[BUILT_IN_STRCAT];
10461   if (!fn)
10462     return 0;
10463
10464   return build_function_call_expr (fn, arglist);
10465 }
10466
10467 /* Fold a call to the __strncat_chk builtin EXP.  */
10468
10469 static tree
10470 fold_builtin_strncat_chk (tree fndecl, tree arglist)
10471 {
10472   tree dest, src, size, len, fn;
10473   const char *p;
10474
10475   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE,
10476                          INTEGER_TYPE, VOID_TYPE))
10477     return 0;
10478
10479   dest = TREE_VALUE (arglist);
10480   src = TREE_VALUE (TREE_CHAIN (arglist));
10481   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
10482   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
10483
10484   p = c_getstr (src);
10485   /* If the SRC parameter is "" or if LEN is 0, return DEST.  */
10486   if (p && *p == '\0')
10487     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
10488   else if (integer_zerop (len))
10489     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
10490
10491   if (! host_integerp (size, 1))
10492     return 0;
10493
10494   if (! integer_all_onesp (size))
10495     {
10496       tree src_len = c_strlen (src, 1);
10497       if (src_len
10498           && host_integerp (src_len, 1)
10499           && host_integerp (len, 1)
10500           && ! tree_int_cst_lt (len, src_len))
10501         {
10502           /* If LEN >= strlen (SRC), optimize into __strcat_chk.  */
10503           fn = built_in_decls[BUILT_IN_STRCAT_CHK];
10504           if (!fn)
10505             return 0;
10506
10507           arglist = build_tree_list (NULL_TREE, size);
10508           arglist = tree_cons (NULL_TREE, src, arglist);
10509           arglist = tree_cons (NULL_TREE, dest, arglist);
10510           return build_function_call_expr (fn, arglist);
10511         }
10512       return 0;
10513     }
10514
10515   arglist = build_tree_list (NULL_TREE, len);
10516   arglist = tree_cons (NULL_TREE, src, arglist);
10517   arglist = tree_cons (NULL_TREE, dest, arglist);
10518
10519   /* If __builtin_strncat_chk is used, assume strncat is available.  */
10520   fn = built_in_decls[BUILT_IN_STRNCAT];
10521   if (!fn)
10522     return 0;
10523
10524   return build_function_call_expr (fn, arglist);
10525 }
10526
10527 /* Fold a call to __{,v}sprintf_chk with argument list ARGLIST.  Return 0 if
10528    a normal call should be emitted rather than expanding the function
10529    inline.  FCODE is either BUILT_IN_SPRINTF_CHK or BUILT_IN_VSPRINTF_CHK.  */
10530
10531 static tree
10532 fold_builtin_sprintf_chk (tree arglist, enum built_in_function fcode)
10533 {
10534   tree dest, size, len, fn, fmt, flag;
10535   const char *fmt_str;
10536
10537   /* Verify the required arguments in the original call.  */
10538   if (! arglist)
10539     return 0;
10540   dest = TREE_VALUE (arglist);
10541   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10542     return 0;
10543   arglist = TREE_CHAIN (arglist);
10544   if (! arglist)
10545     return 0;
10546   flag = TREE_VALUE (arglist);
10547   if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE)
10548     return 0;
10549   arglist = TREE_CHAIN (arglist);
10550   if (! arglist)
10551     return 0;
10552   size = TREE_VALUE (arglist);
10553   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10554     return 0;
10555   arglist = TREE_CHAIN (arglist);
10556   if (! arglist)
10557     return 0;
10558   fmt = TREE_VALUE (arglist);
10559   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10560     return 0;
10561   arglist = TREE_CHAIN (arglist);
10562
10563   if (! host_integerp (size, 1))
10564     return 0;
10565
10566   len = NULL_TREE;
10567
10568   /* Check whether the format is a literal string constant.  */
10569   fmt_str = c_getstr (fmt);
10570   if (fmt_str != NULL)
10571     {
10572       /* If the format doesn't contain % args or %%, we know the size.  */
10573       if (strchr (fmt_str, '%') == 0)
10574         {
10575           if (fcode != BUILT_IN_SPRINTF_CHK || arglist == NULL_TREE)
10576             len = build_int_cstu (size_type_node, strlen (fmt_str));
10577         }
10578       /* If the format is "%s" and first ... argument is a string literal,
10579          we know the size too.  */
10580       else if (fcode == BUILT_IN_SPRINTF_CHK && strcmp (fmt_str, "%s") == 0)
10581         {
10582           tree arg;
10583
10584           if (arglist && !TREE_CHAIN (arglist))
10585             {
10586               arg = TREE_VALUE (arglist);
10587               if (POINTER_TYPE_P (TREE_TYPE (arg)))
10588                 {
10589                   len = c_strlen (arg, 1);
10590                   if (! len || ! host_integerp (len, 1))
10591                     len = NULL_TREE;
10592                 }
10593             }
10594         }
10595     }
10596
10597   if (! integer_all_onesp (size))
10598     {
10599       if (! len || ! tree_int_cst_lt (len, size))
10600         return 0;
10601     }
10602
10603   /* Only convert __{,v}sprintf_chk to {,v}sprintf if flag is 0
10604      or if format doesn't contain % chars or is "%s".  */
10605   if (! integer_zerop (flag))
10606     {
10607       if (fmt_str == NULL)
10608         return 0;
10609       if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10610         return 0;
10611     }
10612
10613   arglist = tree_cons (NULL_TREE, fmt, arglist);
10614   arglist = tree_cons (NULL_TREE, dest, arglist);
10615
10616   /* If __builtin_{,v}sprintf_chk is used, assume {,v}sprintf is available.  */
10617   fn = built_in_decls[fcode == BUILT_IN_VSPRINTF_CHK
10618                       ? BUILT_IN_VSPRINTF : BUILT_IN_SPRINTF];
10619   if (!fn)
10620     return 0;
10621
10622   return build_function_call_expr (fn, arglist);
10623 }
10624
10625 /* Fold a call to {,v}snprintf with argument list ARGLIST.  Return 0 if
10626    a normal call should be emitted rather than expanding the function
10627    inline.  FCODE is either BUILT_IN_SNPRINTF_CHK or
10628    BUILT_IN_VSNPRINTF_CHK.  If MAXLEN is not NULL, it is maximum length
10629    passed as second argument.  */
10630
10631 tree
10632 fold_builtin_snprintf_chk (tree arglist, tree maxlen,
10633                            enum built_in_function fcode)
10634 {
10635   tree dest, size, len, fn, fmt, flag;
10636   const char *fmt_str;
10637
10638   /* Verify the required arguments in the original call.  */
10639   if (! arglist)
10640     return 0;
10641   dest = TREE_VALUE (arglist);
10642   if (! POINTER_TYPE_P (TREE_TYPE (dest)))
10643     return 0;
10644   arglist = TREE_CHAIN (arglist);
10645   if (! arglist)
10646     return 0;
10647   len = TREE_VALUE (arglist);
10648   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10649     return 0;
10650   arglist = TREE_CHAIN (arglist);
10651   if (! arglist)
10652     return 0;
10653   flag = TREE_VALUE (arglist);
10654   if (TREE_CODE (TREE_TYPE (len)) != INTEGER_TYPE)
10655     return 0;
10656   arglist = TREE_CHAIN (arglist);
10657   if (! arglist)
10658     return 0;
10659   size = TREE_VALUE (arglist);
10660   if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE)
10661     return 0;
10662   arglist = TREE_CHAIN (arglist);
10663   if (! arglist)
10664     return 0;
10665   fmt = TREE_VALUE (arglist);
10666   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10667     return 0;
10668   arglist = TREE_CHAIN (arglist);
10669
10670   if (! host_integerp (size, 1))
10671     return 0;
10672
10673   if (! integer_all_onesp (size))
10674     {
10675       if (! host_integerp (len, 1))
10676         {
10677           /* If LEN is not constant, try MAXLEN too.
10678              For MAXLEN only allow optimizing into non-_ocs function
10679              if SIZE is >= MAXLEN, never convert to __ocs_fail ().  */
10680           if (maxlen == NULL_TREE || ! host_integerp (maxlen, 1))
10681             return 0;
10682         }
10683       else
10684         maxlen = len;
10685
10686       if (tree_int_cst_lt (size, maxlen))
10687         return 0;
10688     }
10689
10690   /* Only convert __{,v}snprintf_chk to {,v}snprintf if flag is 0
10691      or if format doesn't contain % chars or is "%s".  */
10692   if (! integer_zerop (flag))
10693     {
10694       fmt_str = c_getstr (fmt);
10695       if (fmt_str == NULL)
10696         return 0;
10697       if (strchr (fmt_str, '%') != NULL && strcmp (fmt_str, "%s"))
10698         return 0;
10699     }
10700
10701   arglist = tree_cons (NULL_TREE, fmt, arglist);
10702   arglist = tree_cons (NULL_TREE, len, arglist);
10703   arglist = tree_cons (NULL_TREE, dest, arglist);
10704
10705   /* If __builtin_{,v}snprintf_chk is used, assume {,v}snprintf is
10706      available.  */
10707   fn = built_in_decls[fcode == BUILT_IN_VSNPRINTF_CHK
10708                       ? BUILT_IN_VSNPRINTF : BUILT_IN_SNPRINTF];
10709   if (!fn)
10710     return 0;
10711
10712   return build_function_call_expr (fn, arglist);
10713 }
10714
10715 /* Fold a call to the {,v}printf{,_unlocked} and __{,v}printf_chk builtins.
10716
10717    Return 0 if no simplification was possible, otherwise return the
10718    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10719    code of the function to be simplified.  */
10720
10721 static tree
10722 fold_builtin_printf (tree fndecl, tree arglist, bool ignore,
10723                      enum built_in_function fcode)
10724 {
10725   tree fmt, fn = NULL_TREE, fn_putchar, fn_puts, arg, call;
10726   const char *fmt_str = NULL;
10727
10728   /* If the return value is used, don't do the transformation.  */
10729   if (! ignore)
10730     return 0;
10731
10732   /* Verify the required arguments in the original call.  */
10733   if (fcode == BUILT_IN_PRINTF_CHK || fcode == BUILT_IN_VPRINTF_CHK)
10734     {
10735       tree flag;
10736
10737       if (! arglist)
10738         return 0;
10739       flag = TREE_VALUE (arglist);
10740       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10741           || TREE_SIDE_EFFECTS (flag))
10742         return 0;
10743       arglist = TREE_CHAIN (arglist);
10744     }
10745
10746   if (! arglist)
10747     return 0;
10748   fmt = TREE_VALUE (arglist);
10749   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10750     return 0;
10751   arglist = TREE_CHAIN (arglist);
10752
10753   /* Check whether the format is a literal string constant.  */
10754   fmt_str = c_getstr (fmt);
10755   if (fmt_str == NULL)
10756     return NULL_TREE;
10757
10758   if (fcode == BUILT_IN_PRINTF_UNLOCKED)
10759     {
10760       /* If we're using an unlocked function, assume the other
10761          unlocked functions exist explicitly.  */
10762       fn_putchar = built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED];
10763       fn_puts = built_in_decls[BUILT_IN_PUTS_UNLOCKED];
10764     }
10765   else
10766     {
10767       fn_putchar = implicit_built_in_decls[BUILT_IN_PUTCHAR];
10768       fn_puts = implicit_built_in_decls[BUILT_IN_PUTS];
10769     }
10770
10771   if (strcmp (fmt_str, "%s") == 0 || strchr (fmt_str, '%') == NULL)
10772     {
10773       const char *str;
10774
10775       if (strcmp (fmt_str, "%s") == 0)
10776         {
10777           if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10778             return 0;
10779
10780           if (! arglist
10781               || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10782               || TREE_CHAIN (arglist))
10783             return 0;
10784
10785           str = c_getstr (TREE_VALUE (arglist));
10786           if (str == NULL)
10787             return 0;
10788         }
10789       else
10790         {
10791           /* The format specifier doesn't contain any '%' characters.  */
10792           if (fcode != BUILT_IN_VPRINTF && fcode != BUILT_IN_VPRINTF_CHK
10793               && arglist)
10794             return 0;
10795           str = fmt_str;
10796         }
10797
10798       /* If the string was "", printf does nothing.  */
10799       if (str[0] == '\0')
10800         return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10801
10802       /* If the string has length of 1, call putchar.  */
10803       if (str[1] == '\0')
10804         {
10805           /* Given printf("c"), (where c is any one character,)
10806              convert "c"[0] to an int and pass that to the replacement
10807              function.  */
10808           arg = build_int_cst (NULL_TREE, str[0]);
10809           arglist = build_tree_list (NULL_TREE, arg);
10810           fn = fn_putchar;
10811         }
10812       else
10813         {
10814           /* If the string was "string\n", call puts("string").  */
10815           size_t len = strlen (str);
10816           if (str[len - 1] == '\n')
10817             {
10818               /* Create a NUL-terminated string that's one char shorter
10819                  than the original, stripping off the trailing '\n'.  */
10820               char *newstr = alloca (len);
10821               memcpy (newstr, str, len - 1);
10822               newstr[len - 1] = 0;
10823
10824               arg = build_string_literal (len, newstr);
10825               arglist = build_tree_list (NULL_TREE, arg);
10826               fn = fn_puts;
10827             }
10828           else
10829             /* We'd like to arrange to call fputs(string,stdout) here,
10830                but we need stdout and don't have a way to get it yet.  */
10831             return 0;
10832         }
10833     }
10834
10835   /* The other optimizations can be done only on the non-va_list variants.  */
10836   else if (fcode == BUILT_IN_VPRINTF || fcode == BUILT_IN_VPRINTF_CHK)
10837     return 0;
10838
10839   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
10840   else if (strcmp (fmt_str, "%s\n") == 0)
10841     {
10842       if (! arglist
10843           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10844           || TREE_CHAIN (arglist))
10845         return 0;
10846       fn = fn_puts;
10847     }
10848
10849   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
10850   else if (strcmp (fmt_str, "%c") == 0)
10851     {
10852       if (! arglist
10853           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10854           || TREE_CHAIN (arglist))
10855         return 0;
10856       fn = fn_putchar;
10857     }
10858
10859   if (!fn)
10860     return 0;
10861
10862   call = build_function_call_expr (fn, arglist);
10863   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10864 }
10865
10866 /* Fold a call to the {,v}fprintf{,_unlocked} and __{,v}printf_chk builtins.
10867
10868    Return 0 if no simplification was possible, otherwise return the
10869    simplified form of the call as a tree.  FCODE is the BUILT_IN_*
10870    code of the function to be simplified.  */
10871
10872 static tree
10873 fold_builtin_fprintf (tree fndecl, tree arglist, bool ignore,
10874                       enum built_in_function fcode)
10875 {
10876   tree fp, fmt, fn = NULL_TREE, fn_fputc, fn_fputs, arg, call;
10877   const char *fmt_str = NULL;
10878
10879   /* If the return value is used, don't do the transformation.  */
10880   if (! ignore)
10881     return 0;
10882
10883   /* Verify the required arguments in the original call.  */
10884   if (! arglist)
10885     return 0;
10886   fp = TREE_VALUE (arglist);
10887   if (! POINTER_TYPE_P (TREE_TYPE (fp)))
10888     return 0;
10889   arglist = TREE_CHAIN (arglist);
10890
10891   if (fcode == BUILT_IN_FPRINTF_CHK || fcode == BUILT_IN_VFPRINTF_CHK)
10892     {
10893       tree flag;
10894
10895       if (! arglist)
10896         return 0;
10897       flag = TREE_VALUE (arglist);
10898       if (TREE_CODE (TREE_TYPE (flag)) != INTEGER_TYPE
10899           || TREE_SIDE_EFFECTS (flag))
10900         return 0;
10901       arglist = TREE_CHAIN (arglist);
10902     }
10903
10904   if (! arglist)
10905     return 0;
10906   fmt = TREE_VALUE (arglist);
10907   if (! POINTER_TYPE_P (TREE_TYPE (fmt)))
10908     return 0;
10909   arglist = TREE_CHAIN (arglist);
10910
10911   /* Check whether the format is a literal string constant.  */
10912   fmt_str = c_getstr (fmt);
10913   if (fmt_str == NULL)
10914     return NULL_TREE;
10915
10916   if (fcode == BUILT_IN_FPRINTF_UNLOCKED)
10917     {
10918       /* If we're using an unlocked function, assume the other
10919          unlocked functions exist explicitly.  */
10920       fn_fputc = built_in_decls[BUILT_IN_FPUTC_UNLOCKED];
10921       fn_fputs = built_in_decls[BUILT_IN_FPUTS_UNLOCKED];
10922     }
10923   else
10924     {
10925       fn_fputc = implicit_built_in_decls[BUILT_IN_FPUTC];
10926       fn_fputs = implicit_built_in_decls[BUILT_IN_FPUTS];
10927     }
10928
10929   /* If the format doesn't contain % args or %%, use strcpy.  */
10930   if (strchr (fmt_str, '%') == NULL)
10931     {
10932       if (fcode != BUILT_IN_VFPRINTF && fcode != BUILT_IN_VFPRINTF_CHK
10933           && arglist)
10934         return 0;
10935
10936       /* If the format specifier was "", fprintf does nothing.  */
10937       if (fmt_str[0] == '\0')
10938         {
10939           /* If FP has side-effects, just wait until gimplification is
10940              done.  */
10941           if (TREE_SIDE_EFFECTS (fp))
10942             return 0;
10943
10944           return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), 0);
10945         }
10946
10947       /* When "string" doesn't contain %, replace all cases of
10948          fprintf (fp, string) with fputs (string, fp).  The fputs
10949          builtin will take care of special cases like length == 1.  */
10950       arglist = build_tree_list (NULL_TREE, fp);
10951       arglist = tree_cons (NULL_TREE, fmt, arglist);
10952       fn = fn_fputs;
10953     }
10954
10955   /* The other optimizations can be done only on the non-va_list variants.  */
10956   else if (fcode == BUILT_IN_VFPRINTF || fcode == BUILT_IN_VFPRINTF_CHK)
10957     return 0;
10958
10959   /* If the format specifier was "%s", call __builtin_fputs (arg, fp).  */
10960   else if (strcmp (fmt_str, "%s") == 0)
10961     {
10962       if (! arglist
10963           || ! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist)))
10964           || TREE_CHAIN (arglist))
10965         return 0;
10966       arg = TREE_VALUE (arglist);
10967       arglist = build_tree_list (NULL_TREE, fp);
10968       arglist = tree_cons (NULL_TREE, arg, arglist);
10969       fn = fn_fputs;
10970     }
10971
10972   /* If the format specifier was "%c", call __builtin_fputc (arg, fp).  */
10973   else if (strcmp (fmt_str, "%c") == 0)
10974     {
10975       if (! arglist
10976           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
10977           || TREE_CHAIN (arglist))
10978         return 0;
10979       arg = TREE_VALUE (arglist);
10980       arglist = build_tree_list (NULL_TREE, fp);
10981       arglist = tree_cons (NULL_TREE, arg, arglist);
10982       fn = fn_fputc;
10983     }
10984
10985   if (!fn)
10986     return 0;
10987
10988   call = build_function_call_expr (fn, arglist);
10989   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), call);
10990 }