OSDN Git Service

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