OSDN Git Service

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