OSDN Git Service

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