OSDN Git Service

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