OSDN Git Service

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