OSDN Git Service

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