OSDN Git Service

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