OSDN Git Service

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