OSDN Git Service

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