OSDN Git Service

* builtins.c (fold_builtin_signbit): Take decomposed arguments
[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, 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, 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;
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   target = expand_call (exp, target, target == const0_rtx);
2109
2110   return target;
2111 }
2112
2113 /* To evaluate powi(x,n), the floating point value x raised to the
2114    constant integer exponent n, we use a hybrid algorithm that
2115    combines the "window method" with look-up tables.  For an
2116    introduction to exponentiation algorithms and "addition chains",
2117    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2118    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2119    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2120    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2121
2122 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2123    multiplications to inline before calling the system library's pow
2124    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2125    so this default never requires calling pow, powf or powl.  */
2126
2127 #ifndef POWI_MAX_MULTS
2128 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2129 #endif
2130
2131 /* The size of the "optimal power tree" lookup table.  All
2132    exponents less than this value are simply looked up in the
2133    powi_table below.  This threshold is also used to size the
2134    cache of pseudo registers that hold intermediate results.  */
2135 #define POWI_TABLE_SIZE 256
2136
2137 /* The size, in bits of the window, used in the "window method"
2138    exponentiation algorithm.  This is equivalent to a radix of
2139    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2140 #define POWI_WINDOW_SIZE 3
2141
2142 /* The following table is an efficient representation of an
2143    "optimal power tree".  For each value, i, the corresponding
2144    value, j, in the table states than an optimal evaluation
2145    sequence for calculating pow(x,i) can be found by evaluating
2146    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2147    100 integers is given in Knuth's "Seminumerical algorithms".  */
2148
2149 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2150   {
2151       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2152       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2153       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2154      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2155      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2156      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2157      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2158      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2159      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2160      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2161      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2162      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2163      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2164      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2165      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2166      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2167      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2168      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2169      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2170      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2171      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2172      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2173      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2174      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2175      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2176     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2177     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2178     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2179     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2180     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2181     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2182     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2183   };
2184
2185
2186 /* Return the number of multiplications required to calculate
2187    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2188    subroutine of powi_cost.  CACHE is an array indicating
2189    which exponents have already been calculated.  */
2190
2191 static int
2192 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2193 {
2194   /* If we've already calculated this exponent, then this evaluation
2195      doesn't require any additional multiplications.  */
2196   if (cache[n])
2197     return 0;
2198
2199   cache[n] = true;
2200   return powi_lookup_cost (n - powi_table[n], cache)
2201          + powi_lookup_cost (powi_table[n], cache) + 1;
2202 }
2203
2204 /* Return the number of multiplications required to calculate
2205    powi(x,n) for an arbitrary x, given the exponent N.  This
2206    function needs to be kept in sync with expand_powi below.  */
2207
2208 static int
2209 powi_cost (HOST_WIDE_INT n)
2210 {
2211   bool cache[POWI_TABLE_SIZE];
2212   unsigned HOST_WIDE_INT digit;
2213   unsigned HOST_WIDE_INT val;
2214   int result;
2215
2216   if (n == 0)
2217     return 0;
2218
2219   /* Ignore the reciprocal when calculating the cost.  */
2220   val = (n < 0) ? -n : n;
2221
2222   /* Initialize the exponent cache.  */
2223   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2224   cache[1] = true;
2225
2226   result = 0;
2227
2228   while (val >= POWI_TABLE_SIZE)
2229     {
2230       if (val & 1)
2231         {
2232           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2233           result += powi_lookup_cost (digit, cache)
2234                     + POWI_WINDOW_SIZE + 1;
2235           val >>= POWI_WINDOW_SIZE;
2236         }
2237       else
2238         {
2239           val >>= 1;
2240           result++;
2241         }
2242     }
2243
2244   return result + powi_lookup_cost (val, cache);
2245 }
2246
2247 /* Recursive subroutine of expand_powi.  This function takes the array,
2248    CACHE, of already calculated exponents and an exponent N and returns
2249    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2250
2251 static rtx
2252 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2253 {
2254   unsigned HOST_WIDE_INT digit;
2255   rtx target, result;
2256   rtx op0, op1;
2257
2258   if (n < POWI_TABLE_SIZE)
2259     {
2260       if (cache[n])
2261         return cache[n];
2262
2263       target = gen_reg_rtx (mode);
2264       cache[n] = target;
2265
2266       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2267       op1 = expand_powi_1 (mode, powi_table[n], cache);
2268     }
2269   else if (n & 1)
2270     {
2271       target = gen_reg_rtx (mode);
2272       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2273       op0 = expand_powi_1 (mode, n - digit, cache);
2274       op1 = expand_powi_1 (mode, digit, cache);
2275     }
2276   else
2277     {
2278       target = gen_reg_rtx (mode);
2279       op0 = expand_powi_1 (mode, n >> 1, cache);
2280       op1 = op0;
2281     }
2282
2283   result = expand_mult (mode, op0, op1, target, 0);
2284   if (result != target)
2285     emit_move_insn (target, result);
2286   return target;
2287 }
2288
2289 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2290    floating point operand in mode MODE, and N is the exponent.  This
2291    function needs to be kept in sync with powi_cost above.  */
2292
2293 static rtx
2294 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2295 {
2296   unsigned HOST_WIDE_INT val;
2297   rtx cache[POWI_TABLE_SIZE];
2298   rtx result;
2299
2300   if (n == 0)
2301     return CONST1_RTX (mode);
2302
2303   val = (n < 0) ? -n : n;
2304
2305   memset (cache, 0, sizeof (cache));
2306   cache[1] = x;
2307
2308   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2309
2310   /* If the original exponent was negative, reciprocate the result.  */
2311   if (n < 0)
2312     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2313                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2314
2315   return result;
2316 }
2317
2318 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2319    a normal call should be emitted rather than expanding the function
2320    in-line.  EXP is the expression that is a call to the builtin
2321    function; if convenient, the result should be placed in TARGET.  */
2322
2323 static rtx
2324 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2325 {
2326   tree arglist = TREE_OPERAND (exp, 1);
2327   tree arg0, arg1;
2328
2329   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2330     return 0;
2331
2332   arg0 = TREE_VALUE (arglist);
2333   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2334
2335   if (TREE_CODE (arg1) == REAL_CST
2336       && ! TREE_CONSTANT_OVERFLOW (arg1))
2337     {
2338       REAL_VALUE_TYPE cint;
2339       REAL_VALUE_TYPE c;
2340       HOST_WIDE_INT n;
2341
2342       c = TREE_REAL_CST (arg1);
2343       n = real_to_integer (&c);
2344       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2345       if (real_identical (&c, &cint))
2346         {
2347           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2348              Otherwise, check the number of multiplications required.
2349              Note that pow never sets errno for an integer exponent.  */
2350           if ((n >= -1 && n <= 2)
2351               || (flag_unsafe_math_optimizations
2352                   && ! optimize_size
2353                   && powi_cost (n) <= POWI_MAX_MULTS))
2354             {
2355               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2356               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2357               op = force_reg (mode, op);
2358               return expand_powi (op, mode, n);
2359             }
2360         }
2361     }
2362
2363   if (! flag_unsafe_math_optimizations)
2364     return NULL_RTX;
2365   return expand_builtin_mathfn_2 (exp, target, subtarget);
2366 }
2367
2368 /* Expand a call to the powi built-in mathematical function.  Return 0 if
2369    a normal call should be emitted rather than expanding the function
2370    in-line.  EXP is the expression that is a call to the builtin
2371    function; if convenient, the result should be placed in TARGET.  */
2372
2373 static rtx
2374 expand_builtin_powi (tree exp, rtx target, rtx subtarget)
2375 {
2376   tree arglist = TREE_OPERAND (exp, 1);
2377   tree arg0, arg1;
2378   rtx op0, op1;
2379   enum machine_mode mode;
2380
2381   if (! validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
2382     return 0;
2383
2384   arg0 = TREE_VALUE (arglist);
2385   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2386   mode = TYPE_MODE (TREE_TYPE (exp));
2387
2388   /* Handle constant power.  */
2389
2390   if (TREE_CODE (arg1) == INTEGER_CST
2391       && ! TREE_CONSTANT_OVERFLOW (arg1))
2392     {
2393       HOST_WIDE_INT n = TREE_INT_CST_LOW (arg1);
2394
2395       /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2396          Otherwise, check the number of multiplications required.  */
2397       if ((TREE_INT_CST_HIGH (arg1) == 0
2398            || TREE_INT_CST_HIGH (arg1) == -1)
2399           && ((n >= -1 && n <= 2)
2400               || (! optimize_size
2401                   && powi_cost (n) <= POWI_MAX_MULTS)))
2402         {
2403           op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
2404           op0 = force_reg (mode, op0);
2405           return expand_powi (op0, mode, n);
2406         }
2407     }
2408
2409   /* Emit a libcall to libgcc.  */
2410
2411   if (target == NULL_RTX)
2412     target = gen_reg_rtx (mode);
2413
2414   op0 = expand_expr (arg0, subtarget, mode, 0);
2415   if (GET_MODE (op0) != mode)
2416     op0 = convert_to_mode (mode, op0, 0);
2417   op1 = expand_expr (arg1, 0, word_mode, 0);
2418   if (GET_MODE (op1) != word_mode)
2419     op1 = convert_to_mode (word_mode, op1, 0);
2420
2421   target = emit_library_call_value (powi_optab->handlers[(int) mode].libfunc,
2422                                     target, LCT_CONST_MAKE_BLOCK, mode, 2,
2423                                     op0, mode, op1, word_mode);
2424
2425   return target;
2426 }
2427
2428 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2429    if we failed the caller should emit a normal call, otherwise
2430    try to get the result in TARGET, if convenient.  */
2431
2432 static rtx
2433 expand_builtin_strlen (tree arglist, rtx target,
2434                        enum machine_mode target_mode)
2435 {
2436   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2437     return 0;
2438   else
2439     {
2440       rtx pat;
2441       tree len, src = TREE_VALUE (arglist);
2442       rtx result, src_reg, char_rtx, before_strlen;
2443       enum machine_mode insn_mode = target_mode, char_mode;
2444       enum insn_code icode = CODE_FOR_nothing;
2445       int align;
2446
2447       /* If the length can be computed at compile-time, return it.  */
2448       len = c_strlen (src, 0);
2449       if (len)
2450         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2451
2452       /* If the length can be computed at compile-time and is constant
2453          integer, but there are side-effects in src, evaluate
2454          src for side-effects, then return len.
2455          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2456          can be optimized into: i++; x = 3;  */
2457       len = c_strlen (src, 1);
2458       if (len && TREE_CODE (len) == INTEGER_CST)
2459         {
2460           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2461           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2462         }
2463
2464       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2465
2466       /* If SRC is not a pointer type, don't do this operation inline.  */
2467       if (align == 0)
2468         return 0;
2469
2470       /* Bail out if we can't compute strlen in the right mode.  */
2471       while (insn_mode != VOIDmode)
2472         {
2473           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2474           if (icode != CODE_FOR_nothing)
2475             break;
2476
2477           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2478         }
2479       if (insn_mode == VOIDmode)
2480         return 0;
2481
2482       /* Make a place to write the result of the instruction.  */
2483       result = target;
2484       if (! (result != 0
2485              && REG_P (result)
2486              && GET_MODE (result) == insn_mode
2487              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2488         result = gen_reg_rtx (insn_mode);
2489
2490       /* Make a place to hold the source address.  We will not expand
2491          the actual source until we are sure that the expansion will
2492          not fail -- there are trees that cannot be expanded twice.  */
2493       src_reg = gen_reg_rtx (Pmode);
2494
2495       /* Mark the beginning of the strlen sequence so we can emit the
2496          source operand later.  */
2497       before_strlen = get_last_insn ();
2498
2499       char_rtx = const0_rtx;
2500       char_mode = insn_data[(int) icode].operand[2].mode;
2501       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2502                                                             char_mode))
2503         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2504
2505       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2506                              char_rtx, GEN_INT (align));
2507       if (! pat)
2508         return 0;
2509       emit_insn (pat);
2510
2511       /* Now that we are assured of success, expand the source.  */
2512       start_sequence ();
2513       pat = expand_expr (src, src_reg, ptr_mode, EXPAND_NORMAL);
2514       if (pat != src_reg)
2515         emit_move_insn (src_reg, pat);
2516       pat = get_insns ();
2517       end_sequence ();
2518
2519       if (before_strlen)
2520         emit_insn_after (pat, before_strlen);
2521       else
2522         emit_insn_before (pat, get_insns ());
2523
2524       /* Return the value in the proper mode for this function.  */
2525       if (GET_MODE (result) == target_mode)
2526         target = result;
2527       else if (target != 0)
2528         convert_move (target, result, 0);
2529       else
2530         target = convert_to_mode (target_mode, result, 0);
2531
2532       return target;
2533     }
2534 }
2535
2536 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2537    caller should emit a normal call, otherwise try to get the result
2538    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2539
2540 static rtx
2541 expand_builtin_strstr (tree arglist, tree type, rtx target, enum machine_mode mode)
2542 {
2543   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2544     {
2545       tree result = fold_builtin_strstr (arglist, type);
2546       if (result)
2547         return expand_expr (result, target, mode, EXPAND_NORMAL);
2548     }
2549   return 0;
2550 }
2551
2552 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2553    caller should emit a normal call, otherwise try to get the result
2554    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2555
2556 static rtx
2557 expand_builtin_strchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2558 {
2559   if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2560     {
2561       tree result = fold_builtin_strchr (arglist, type);
2562       if (result)
2563         return expand_expr (result, target, mode, EXPAND_NORMAL);
2564
2565       /* FIXME: Should use strchrM optab so that ports can optimize this.  */
2566     }
2567   return 0;
2568 }
2569
2570 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2571    caller should emit a normal call, otherwise try to get the result
2572    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2573
2574 static rtx
2575 expand_builtin_strrchr (tree arglist, tree type, rtx target, enum machine_mode mode)
2576 {
2577   if (validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2578     {
2579       tree result = fold_builtin_strrchr (arglist, type);
2580       if (result)
2581         return expand_expr (result, target, mode, EXPAND_NORMAL);
2582     }
2583   return 0;
2584 }
2585
2586 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2587    caller should emit a normal call, otherwise try to get the result
2588    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2589
2590 static rtx
2591 expand_builtin_strpbrk (tree arglist, tree type, rtx target, enum machine_mode mode)
2592 {
2593   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2594     {
2595       tree result = fold_builtin_strpbrk (arglist, type);
2596       if (result)
2597         return expand_expr (result, target, mode, EXPAND_NORMAL);
2598     }
2599   return 0;
2600 }
2601
2602 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2603    bytes from constant string DATA + OFFSET and return it as target
2604    constant.  */
2605
2606 static rtx
2607 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2608                          enum machine_mode mode)
2609 {
2610   const char *str = (const char *) data;
2611
2612   gcc_assert (offset >= 0
2613               && ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2614                   <= strlen (str) + 1));
2615
2616   return c_readstr (str + offset, mode);
2617 }
2618
2619 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2620    Return 0 if we failed, the caller should emit a normal call,
2621    otherwise try to get the result in TARGET, if convenient (and in
2622    mode MODE if that's convenient).  */
2623 static rtx
2624 expand_builtin_memcpy (tree exp, rtx target, enum machine_mode mode)
2625 {
2626   tree arglist = TREE_OPERAND (exp, 1);
2627   if (!validate_arglist (arglist,
2628                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2629     return 0;
2630   else
2631     {
2632       tree dest = TREE_VALUE (arglist);
2633       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2634       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2635       const char *src_str;
2636       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2637       unsigned int dest_align
2638         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2639       rtx dest_mem, src_mem, dest_addr, len_rtx;
2640       tree result = fold_builtin_memcpy (exp);
2641
2642       if (result)
2643         return expand_expr (result, target, mode, EXPAND_NORMAL);
2644
2645       /* If DEST is not a pointer type, call the normal function.  */
2646       if (dest_align == 0)
2647         return 0;
2648
2649       /* If either SRC is not a pointer type, don't do this
2650          operation in-line.  */
2651       if (src_align == 0)
2652         return 0;
2653
2654       dest_mem = get_memory_rtx (dest);
2655       set_mem_align (dest_mem, dest_align);
2656       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2657       src_str = c_getstr (src);
2658
2659       /* If SRC is a string constant and block move would be done
2660          by pieces, we can avoid loading the string from memory
2661          and only stored the computed constants.  */
2662       if (src_str
2663           && GET_CODE (len_rtx) == CONST_INT
2664           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2665           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2666                                   (void *) src_str, dest_align))
2667         {
2668           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2669                                       builtin_memcpy_read_str,
2670                                       (void *) src_str, dest_align, 0);
2671           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2672           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2673           return dest_mem;
2674         }
2675
2676       src_mem = get_memory_rtx (src);
2677       set_mem_align (src_mem, src_align);
2678
2679       /* Copy word part most expediently.  */
2680       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2681                                    BLOCK_OP_NORMAL);
2682
2683       if (dest_addr == 0)
2684         {
2685           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2686           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2687         }
2688       return dest_addr;
2689     }
2690 }
2691
2692 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2693    Return 0 if we failed the caller should emit a normal call,
2694    otherwise try to get the result in TARGET, if convenient (and in
2695    mode MODE if that's convenient).  If ENDP is 0 return the
2696    destination pointer, if ENDP is 1 return the end pointer ala
2697    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2698    stpcpy.  */
2699
2700 static rtx
2701 expand_builtin_mempcpy (tree arglist, tree type, rtx target, enum machine_mode mode,
2702                         int endp)
2703 {
2704   if (!validate_arglist (arglist,
2705                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2706     return 0;
2707   /* If return value is ignored, transform mempcpy into memcpy.  */
2708   else if (target == const0_rtx)
2709     {
2710       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2711
2712       if (!fn)
2713         return 0;
2714
2715       return expand_expr (build_function_call_expr (fn, arglist),
2716                           target, mode, EXPAND_NORMAL);
2717     }
2718   else
2719     {
2720       tree dest = TREE_VALUE (arglist);
2721       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2722       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2723       const char *src_str;
2724       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2725       unsigned int dest_align
2726         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2727       rtx dest_mem, src_mem, len_rtx;
2728       tree result = fold_builtin_mempcpy (arglist, type, endp);
2729
2730       if (result)
2731         return expand_expr (result, target, mode, EXPAND_NORMAL);
2732       
2733       /* If either SRC or DEST is not a pointer type, don't do this
2734          operation in-line.  */
2735       if (dest_align == 0 || src_align == 0)
2736         return 0;
2737
2738       /* If LEN is not constant, call the normal function.  */
2739       if (! host_integerp (len, 1))
2740         return 0;
2741
2742       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2743       src_str = c_getstr (src);
2744
2745       /* If SRC is a string constant and block move would be done
2746          by pieces, we can avoid loading the string from memory
2747          and only stored the computed constants.  */
2748       if (src_str
2749           && GET_CODE (len_rtx) == CONST_INT
2750           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2751           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2752                                   (void *) src_str, dest_align))
2753         {
2754           dest_mem = get_memory_rtx (dest);
2755           set_mem_align (dest_mem, dest_align);
2756           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2757                                       builtin_memcpy_read_str,
2758                                       (void *) src_str, dest_align, endp);
2759           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2760           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2761           return dest_mem;
2762         }
2763
2764       if (GET_CODE (len_rtx) == CONST_INT
2765           && can_move_by_pieces (INTVAL (len_rtx),
2766                                  MIN (dest_align, src_align)))
2767         {
2768           dest_mem = get_memory_rtx (dest);
2769           set_mem_align (dest_mem, dest_align);
2770           src_mem = get_memory_rtx (src);
2771           set_mem_align (src_mem, src_align);
2772           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2773                                      MIN (dest_align, src_align), endp);
2774           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2775           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2776           return dest_mem;
2777         }
2778
2779       return 0;
2780     }
2781 }
2782
2783 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2784    if we failed the caller should emit a normal call.  */
2785
2786 static rtx
2787 expand_builtin_memmove (tree arglist, tree type, rtx target,
2788                         enum machine_mode mode)
2789 {
2790   if (!validate_arglist (arglist,
2791                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2792     return 0;
2793   else
2794     {
2795       tree dest = TREE_VALUE (arglist);
2796       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2797       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2798
2799       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2800       unsigned int dest_align
2801         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2802       tree result = fold_builtin_memmove (arglist, type);
2803
2804       if (result)
2805         return expand_expr (result, target, mode, EXPAND_NORMAL);
2806
2807       /* If DEST is not a pointer type, call the normal function.  */
2808       if (dest_align == 0)
2809         return 0;
2810
2811       /* If either SRC is not a pointer type, don't do this
2812          operation in-line.  */
2813       if (src_align == 0)
2814         return 0;
2815
2816       /* If src is categorized for a readonly section we can use
2817          normal memcpy.  */
2818       if (readonly_data_expr (src))
2819         {
2820           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2821           if (!fn)
2822             return 0;
2823           return expand_expr (build_function_call_expr (fn, arglist),
2824                               target, mode, EXPAND_NORMAL);
2825         }
2826
2827       /* If length is 1 and we can expand memcpy call inline,
2828          it is ok to use memcpy as well.  */
2829       if (integer_onep (len))
2830         {
2831           rtx ret = expand_builtin_mempcpy (arglist, type, target, mode,
2832                                             /*endp=*/0);
2833           if (ret)
2834             return ret;
2835         }
2836
2837       /* Otherwise, call the normal function.  */
2838       return 0;
2839    }
2840 }
2841
2842 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2843    if we failed the caller should emit a normal call.  */
2844
2845 static rtx
2846 expand_builtin_bcopy (tree arglist, tree type)
2847 {
2848   tree src, dest, size, newarglist;
2849
2850   if (!validate_arglist (arglist,
2851                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2852     return NULL_RTX;
2853
2854   src = TREE_VALUE (arglist);
2855   dest = TREE_VALUE (TREE_CHAIN (arglist));
2856   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2857
2858   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2859      memmove(ptr y, ptr x, size_t z).   This is done this way
2860      so that if it isn't expanded inline, we fallback to
2861      calling bcopy instead of memmove.  */
2862
2863   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2864   newarglist = tree_cons (NULL_TREE, src, newarglist);
2865   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2866
2867   return expand_builtin_memmove (newarglist, type, const0_rtx, VOIDmode);
2868 }
2869
2870 #ifndef HAVE_movstr
2871 # define HAVE_movstr 0
2872 # define CODE_FOR_movstr CODE_FOR_nothing
2873 #endif
2874
2875 /* Expand into a movstr instruction, if one is available.  Return 0 if
2876    we failed, the caller should emit a normal call, otherwise try to
2877    get the result in TARGET, if convenient.  If ENDP is 0 return the
2878    destination pointer, if ENDP is 1 return the end pointer ala
2879    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2880    stpcpy.  */
2881
2882 static rtx
2883 expand_movstr (tree dest, tree src, rtx target, int endp)
2884 {
2885   rtx end;
2886   rtx dest_mem;
2887   rtx src_mem;
2888   rtx insn;
2889   const struct insn_data * data;
2890
2891   if (!HAVE_movstr)
2892     return 0;
2893
2894   dest_mem = get_memory_rtx (dest);
2895   src_mem = get_memory_rtx (src);
2896   if (!endp)
2897     {
2898       target = force_reg (Pmode, XEXP (dest_mem, 0));
2899       dest_mem = replace_equiv_address (dest_mem, target);
2900       end = gen_reg_rtx (Pmode);
2901     }
2902   else
2903     {
2904       if (target == 0 || target == const0_rtx)
2905         {
2906           end = gen_reg_rtx (Pmode);
2907           if (target == 0)
2908             target = end;
2909         }
2910       else
2911         end = target;
2912     }
2913
2914   data = insn_data + CODE_FOR_movstr;
2915
2916   if (data->operand[0].mode != VOIDmode)
2917     end = gen_lowpart (data->operand[0].mode, end);
2918
2919   insn = data->genfun (end, dest_mem, src_mem);
2920
2921   gcc_assert (insn);
2922
2923   emit_insn (insn);
2924
2925   /* movstr is supposed to set end to the address of the NUL
2926      terminator.  If the caller requested a mempcpy-like return value,
2927      adjust it.  */
2928   if (endp == 1 && target != const0_rtx)
2929     {
2930       rtx tem = plus_constant (gen_lowpart (GET_MODE (target), end), 1);
2931       emit_move_insn (target, force_operand (tem, NULL_RTX));
2932     }
2933
2934   return target;
2935 }
2936
2937 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2938    if we failed the caller should emit a normal call, otherwise try to get
2939    the result in TARGET, if convenient (and in mode MODE if that's
2940    convenient).  */
2941
2942 static rtx
2943 expand_builtin_strcpy (tree exp, rtx target, enum machine_mode mode)
2944 {
2945   tree fndecl = get_callee_fndecl (exp);
2946   tree arglist = TREE_OPERAND (exp, 1);
2947   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2948     {
2949       tree result = fold_builtin_strcpy (fndecl, arglist, 0);
2950       if (result)
2951         return expand_expr (result, target, mode, EXPAND_NORMAL);
2952
2953       return expand_movstr (TREE_VALUE (arglist),
2954                             TREE_VALUE (TREE_CHAIN (arglist)),
2955                             target, /*endp=*/0);
2956     }
2957   return 0;
2958 }
2959
2960 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2961    Return 0 if we failed the caller should emit a normal call,
2962    otherwise try to get the result in TARGET, if convenient (and in
2963    mode MODE if that's convenient).  */
2964
2965 static rtx
2966 expand_builtin_stpcpy (tree exp, rtx target, enum machine_mode mode)
2967 {
2968   tree arglist = TREE_OPERAND (exp, 1);
2969   /* If return value is ignored, transform stpcpy into strcpy.  */
2970   if (target == const0_rtx)
2971     {
2972       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2973       if (!fn)
2974         return 0;
2975
2976       return expand_expr (build_function_call_expr (fn, arglist),
2977                           target, mode, EXPAND_NORMAL);
2978     }
2979
2980   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2981     return 0;
2982   else
2983     {
2984       tree dst, src, len, lenp1;
2985       tree narglist;
2986       rtx ret;
2987
2988       /* Ensure we get an actual string whose length can be evaluated at
2989          compile-time, not an expression containing a string.  This is
2990          because the latter will potentially produce pessimized code
2991          when used to produce the return value.  */
2992       src = TREE_VALUE (TREE_CHAIN (arglist));
2993       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2994         return expand_movstr (TREE_VALUE (arglist),
2995                               TREE_VALUE (TREE_CHAIN (arglist)),
2996                               target, /*endp=*/2);
2997
2998       dst = TREE_VALUE (arglist);
2999       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3000       narglist = build_tree_list (NULL_TREE, lenp1);
3001       narglist = tree_cons (NULL_TREE, src, narglist);
3002       narglist = tree_cons (NULL_TREE, dst, narglist);
3003       ret = expand_builtin_mempcpy (narglist, TREE_TYPE (exp),
3004                                     target, mode, /*endp=*/2);
3005
3006       if (ret)
3007         return ret;
3008
3009       if (TREE_CODE (len) == INTEGER_CST)
3010         {
3011           rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3012
3013           if (GET_CODE (len_rtx) == CONST_INT)
3014             {
3015               ret = expand_builtin_strcpy (exp, target, mode);
3016
3017               if (ret)
3018                 {
3019                   if (! target)
3020                     {
3021                       if (mode != VOIDmode)
3022                         target = gen_reg_rtx (mode);
3023                       else
3024                         target = gen_reg_rtx (GET_MODE (ret));
3025                     }
3026                   if (GET_MODE (target) != GET_MODE (ret))
3027                     ret = gen_lowpart (GET_MODE (target), ret);
3028
3029                   ret = plus_constant (ret, INTVAL (len_rtx));
3030                   ret = emit_move_insn (target, force_operand (ret, NULL_RTX));
3031                   gcc_assert (ret);
3032
3033                   return target;
3034                 }
3035             }
3036         }
3037
3038       return expand_movstr (TREE_VALUE (arglist),
3039                             TREE_VALUE (TREE_CHAIN (arglist)),
3040                             target, /*endp=*/2);
3041     }
3042 }
3043
3044 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3045    bytes from constant string DATA + OFFSET and return it as target
3046    constant.  */
3047
3048 static rtx
3049 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3050                           enum machine_mode mode)
3051 {
3052   const char *str = (const char *) data;
3053
3054   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3055     return const0_rtx;
3056
3057   return c_readstr (str + offset, mode);
3058 }
3059
3060 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3061    if we failed the caller should emit a normal call.  */
3062
3063 static rtx
3064 expand_builtin_strncpy (tree exp, rtx target, enum machine_mode mode)
3065 {
3066   tree fndecl = get_callee_fndecl (exp);
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 (fndecl, arglist, 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 word, 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   bitpos = fmt->signbit_ro;
4975   if (bitpos < 0)
4976   {
4977     /* But we can't do this if the format supports signed zero.  */
4978     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4979       return 0;
4980
4981     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
4982                         build_real (TREE_TYPE (arg), dconst0)));
4983     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4984   }
4985
4986   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4987   if (GET_MODE_SIZE (fmode) <= UNITS_PER_WORD)
4988     {
4989       imode = int_mode_for_mode (fmode);
4990       if (imode == BLKmode)
4991         return 0;
4992       temp = gen_lowpart (imode, temp);
4993     }
4994   else
4995     {
4996       imode = word_mode;
4997       /* Handle targets with different FP word orders.  */
4998       if (FLOAT_WORDS_BIG_ENDIAN)
4999         word = (GET_MODE_BITSIZE (fmode) - bitpos) / BITS_PER_WORD;
5000       else
5001         word = bitpos / BITS_PER_WORD;
5002       temp = operand_subword_force (temp, word, fmode);
5003       bitpos = bitpos % BITS_PER_WORD;
5004     }
5005
5006   /* Force the intermediate word_mode (or narrower) result into a
5007      register.  This avoids attempting to create paradoxical SUBREGs
5008      of floating point modes below.  */
5009   temp = force_reg (imode, temp);
5010
5011   /* If the bitpos is within the "result mode" lowpart, the operation
5012      can be implement with a single bitwise AND.  Otherwise, we need
5013      a right shift and an AND.  */
5014
5015   if (bitpos < GET_MODE_BITSIZE (rmode))
5016     {
5017       if (bitpos < HOST_BITS_PER_WIDE_INT)
5018         {
5019           hi = 0;
5020           lo = (HOST_WIDE_INT) 1 << bitpos;
5021         }
5022       else
5023         {
5024           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5025           lo = 0;
5026         }
5027
5028       if (imode != rmode)
5029         temp = gen_lowpart (rmode, temp);
5030       temp = expand_binop (rmode, and_optab, temp,
5031                            immed_double_const (lo, hi, rmode),
5032                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5033     }
5034   else
5035     {
5036       /* Perform a logical right shift to place the signbit in the least
5037          significant bit, then truncate the result to the desired mode
5038          and mask just this bit.  */
5039       temp = expand_shift (RSHIFT_EXPR, imode, temp,
5040                            build_int_cst (NULL_TREE, bitpos), NULL_RTX, 1);
5041       temp = gen_lowpart (rmode, temp);
5042       temp = expand_binop (rmode, and_optab, temp, const1_rtx,
5043                            NULL_RTX, 1, OPTAB_LIB_WIDEN);
5044     }
5045
5046   return temp;
5047 }
5048
5049 /* Expand fork or exec calls.  TARGET is the desired target of the
5050    call.  ARGLIST is the list of arguments of the call.  FN is the
5051    identificator of the actual function.  IGNORE is nonzero if the
5052    value is to be ignored.  */
5053
5054 static rtx
5055 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5056 {
5057   tree id, decl;
5058   tree call;
5059
5060   /* If we are not profiling, just call the function.  */
5061   if (!profile_arc_flag)
5062     return NULL_RTX;
5063
5064   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5065      compiler, so the code does not diverge, and the wrapper may run the
5066      code necessary for keeping the profiling sane.  */
5067
5068   switch (DECL_FUNCTION_CODE (fn))
5069     {
5070     case BUILT_IN_FORK:
5071       id = get_identifier ("__gcov_fork");
5072       break;
5073
5074     case BUILT_IN_EXECL:
5075       id = get_identifier ("__gcov_execl");
5076       break;
5077
5078     case BUILT_IN_EXECV:
5079       id = get_identifier ("__gcov_execv");
5080       break;
5081
5082     case BUILT_IN_EXECLP:
5083       id = get_identifier ("__gcov_execlp");
5084       break;
5085
5086     case BUILT_IN_EXECLE:
5087       id = get_identifier ("__gcov_execle");
5088       break;
5089
5090     case BUILT_IN_EXECVP:
5091       id = get_identifier ("__gcov_execvp");
5092       break;
5093
5094     case BUILT_IN_EXECVE:
5095       id = get_identifier ("__gcov_execve");
5096       break;
5097
5098     default:
5099       gcc_unreachable ();
5100     }
5101
5102   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5103   DECL_EXTERNAL (decl) = 1;
5104   TREE_PUBLIC (decl) = 1;
5105   DECL_ARTIFICIAL (decl) = 1;
5106   TREE_NOTHROW (decl) = 1;
5107   call = build_function_call_expr (decl, arglist);
5108
5109   return expand_call (call, target, ignore);
5110 }
5111 \f
5112 /* Expand an expression EXP that calls a built-in function,
5113    with result going to TARGET if that's convenient
5114    (and in mode MODE if that's convenient).
5115    SUBTARGET may be used as the target for computing one of EXP's operands.
5116    IGNORE is nonzero if the value is to be ignored.  */
5117
5118 rtx
5119 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5120                 int ignore)
5121 {
5122   tree fndecl = get_callee_fndecl (exp);
5123   tree arglist = TREE_OPERAND (exp, 1);
5124   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5125   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5126
5127   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5128     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5129
5130   /* When not optimizing, generate calls to library functions for a certain
5131      set of builtins.  */
5132   if (!optimize
5133       && !CALLED_AS_BUILT_IN (fndecl)
5134       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5135       && fcode != BUILT_IN_ALLOCA)
5136     return expand_call (exp, target, ignore);
5137
5138   /* The built-in function expanders test for target == const0_rtx
5139      to determine whether the function's result will be ignored.  */
5140   if (ignore)
5141     target = const0_rtx;
5142
5143   /* If the result of a pure or const built-in function is ignored, and
5144      none of its arguments are volatile, we can avoid expanding the
5145      built-in call and just evaluate the arguments for side-effects.  */
5146   if (target == const0_rtx
5147       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5148     {
5149       bool volatilep = false;
5150       tree arg;
5151
5152       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5153         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5154           {
5155             volatilep = true;
5156             break;
5157           }
5158
5159       if (! volatilep)
5160         {
5161           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5162             expand_expr (TREE_VALUE (arg), const0_rtx,
5163                          VOIDmode, EXPAND_NORMAL);
5164           return const0_rtx;
5165         }
5166     }
5167
5168   switch (fcode)
5169     {
5170     case BUILT_IN_FABS:
5171     case BUILT_IN_FABSF:
5172     case BUILT_IN_FABSL:
5173       target = expand_builtin_fabs (arglist, target, subtarget);
5174       if (target)
5175         return target;
5176       break;
5177
5178     case BUILT_IN_COPYSIGN:
5179     case BUILT_IN_COPYSIGNF:
5180     case BUILT_IN_COPYSIGNL:
5181       target = expand_builtin_copysign (arglist, target, subtarget);
5182       if (target)
5183         return target;
5184       break;
5185
5186       /* Just do a normal library call if we were unable to fold
5187          the values.  */
5188     case BUILT_IN_CABS:
5189     case BUILT_IN_CABSF:
5190     case BUILT_IN_CABSL:
5191       break;
5192
5193     case BUILT_IN_EXP:
5194     case BUILT_IN_EXPF:
5195     case BUILT_IN_EXPL:
5196     case BUILT_IN_EXP10:
5197     case BUILT_IN_EXP10F:
5198     case BUILT_IN_EXP10L:
5199     case BUILT_IN_POW10:
5200     case BUILT_IN_POW10F:
5201     case BUILT_IN_POW10L:
5202     case BUILT_IN_EXP2:
5203     case BUILT_IN_EXP2F:
5204     case BUILT_IN_EXP2L:
5205     case BUILT_IN_EXPM1:
5206     case BUILT_IN_EXPM1F:
5207     case BUILT_IN_EXPM1L:
5208     case BUILT_IN_LOGB:
5209     case BUILT_IN_LOGBF:
5210     case BUILT_IN_LOGBL:
5211     case BUILT_IN_ILOGB:
5212     case BUILT_IN_ILOGBF:
5213     case BUILT_IN_ILOGBL:
5214     case BUILT_IN_LOG:
5215     case BUILT_IN_LOGF:
5216     case BUILT_IN_LOGL:
5217     case BUILT_IN_LOG10:
5218     case BUILT_IN_LOG10F:
5219     case BUILT_IN_LOG10L:
5220     case BUILT_IN_LOG2:
5221     case BUILT_IN_LOG2F:
5222     case BUILT_IN_LOG2L:
5223     case BUILT_IN_LOG1P:
5224     case BUILT_IN_LOG1PF:
5225     case BUILT_IN_LOG1PL:
5226     case BUILT_IN_TAN:
5227     case BUILT_IN_TANF:
5228     case BUILT_IN_TANL:
5229     case BUILT_IN_ASIN:
5230     case BUILT_IN_ASINF:
5231     case BUILT_IN_ASINL:
5232     case BUILT_IN_ACOS:
5233     case BUILT_IN_ACOSF:
5234     case BUILT_IN_ACOSL:
5235     case BUILT_IN_ATAN:
5236     case BUILT_IN_ATANF:
5237     case BUILT_IN_ATANL:
5238       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5239          because of possible accuracy problems.  */
5240       if (! flag_unsafe_math_optimizations)
5241         break;
5242     case BUILT_IN_SQRT:
5243     case BUILT_IN_SQRTF:
5244     case BUILT_IN_SQRTL:
5245     case BUILT_IN_FLOOR:
5246     case BUILT_IN_FLOORF:
5247     case BUILT_IN_FLOORL:
5248     case BUILT_IN_CEIL:
5249     case BUILT_IN_CEILF:
5250     case BUILT_IN_CEILL:
5251     case BUILT_IN_TRUNC:
5252     case BUILT_IN_TRUNCF:
5253     case BUILT_IN_TRUNCL:
5254     case BUILT_IN_ROUND:
5255     case BUILT_IN_ROUNDF:
5256     case BUILT_IN_ROUNDL:
5257     case BUILT_IN_NEARBYINT:
5258     case BUILT_IN_NEARBYINTF:
5259     case BUILT_IN_NEARBYINTL:
5260     case BUILT_IN_RINT:
5261     case BUILT_IN_RINTF:
5262     case BUILT_IN_RINTL:
5263       target = expand_builtin_mathfn (exp, target, subtarget);
5264       if (target)
5265         return target;
5266       break;
5267
5268     case BUILT_IN_POW:
5269     case BUILT_IN_POWF:
5270     case BUILT_IN_POWL:
5271       target = expand_builtin_pow (exp, target, subtarget);
5272       if (target)
5273         return target;
5274       break;
5275
5276     case BUILT_IN_POWI:
5277     case BUILT_IN_POWIF:
5278     case BUILT_IN_POWIL:
5279       target = expand_builtin_powi (exp, target, subtarget);
5280       if (target)
5281         return target;
5282       break;
5283
5284     case BUILT_IN_ATAN2:
5285     case BUILT_IN_ATAN2F:
5286     case BUILT_IN_ATAN2L:
5287     case BUILT_IN_LDEXP:
5288     case BUILT_IN_LDEXPF:
5289     case BUILT_IN_LDEXPL:
5290     case BUILT_IN_FMOD:
5291     case BUILT_IN_FMODF:
5292     case BUILT_IN_FMODL:
5293     case BUILT_IN_DREM:
5294     case BUILT_IN_DREMF:
5295     case BUILT_IN_DREML:
5296       if (! flag_unsafe_math_optimizations)
5297         break;
5298       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5299       if (target)
5300         return target;
5301       break;
5302
5303     case BUILT_IN_SIN:
5304     case BUILT_IN_SINF:
5305     case BUILT_IN_SINL:
5306     case BUILT_IN_COS:
5307     case BUILT_IN_COSF:
5308     case BUILT_IN_COSL:
5309       if (! flag_unsafe_math_optimizations)
5310         break;
5311       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5312       if (target)
5313         return target;
5314       break;
5315
5316     case BUILT_IN_APPLY_ARGS:
5317       return expand_builtin_apply_args ();
5318
5319       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5320          FUNCTION with a copy of the parameters described by
5321          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5322          allocated on the stack into which is stored all the registers
5323          that might possibly be used for returning the result of a
5324          function.  ARGUMENTS is the value returned by
5325          __builtin_apply_args.  ARGSIZE is the number of bytes of
5326          arguments that must be copied.  ??? How should this value be
5327          computed?  We'll also need a safe worst case value for varargs
5328          functions.  */
5329     case BUILT_IN_APPLY:
5330       if (!validate_arglist (arglist, POINTER_TYPE,
5331                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5332           && !validate_arglist (arglist, REFERENCE_TYPE,
5333                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5334         return const0_rtx;
5335       else
5336         {
5337           int i;
5338           tree t;
5339           rtx ops[3];
5340
5341           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5342             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5343
5344           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5345         }
5346
5347       /* __builtin_return (RESULT) causes the function to return the
5348          value described by RESULT.  RESULT is address of the block of
5349          memory returned by __builtin_apply.  */
5350     case BUILT_IN_RETURN:
5351       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5352         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5353                                             NULL_RTX, VOIDmode, 0));
5354       return const0_rtx;
5355
5356     case BUILT_IN_SAVEREGS:
5357       return expand_builtin_saveregs ();
5358
5359     case BUILT_IN_ARGS_INFO:
5360       return expand_builtin_args_info (arglist);
5361
5362       /* Return the address of the first anonymous stack arg.  */
5363     case BUILT_IN_NEXT_ARG:
5364       if (fold_builtin_next_arg (arglist))
5365         return const0_rtx;
5366       return expand_builtin_next_arg ();
5367
5368     case BUILT_IN_CLASSIFY_TYPE:
5369       return expand_builtin_classify_type (arglist);
5370
5371     case BUILT_IN_CONSTANT_P:
5372       return const0_rtx;
5373
5374     case BUILT_IN_FRAME_ADDRESS:
5375     case BUILT_IN_RETURN_ADDRESS:
5376       return expand_builtin_frame_address (fndecl, arglist);
5377
5378     /* Returns the address of the area where the structure is returned.
5379        0 otherwise.  */
5380     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5381       if (arglist != 0
5382           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5383           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5384         return const0_rtx;
5385       else
5386         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5387
5388     case BUILT_IN_ALLOCA:
5389       target = expand_builtin_alloca (arglist, target);
5390       if (target)
5391         return target;
5392       break;
5393
5394     case BUILT_IN_STACK_SAVE:
5395       return expand_stack_save ();
5396
5397     case BUILT_IN_STACK_RESTORE:
5398       expand_stack_restore (TREE_VALUE (arglist));
5399       return const0_rtx;
5400
5401     case BUILT_IN_FFS:
5402     case BUILT_IN_FFSL:
5403     case BUILT_IN_FFSLL:
5404     case BUILT_IN_FFSIMAX:
5405       target = expand_builtin_unop (target_mode, arglist, target,
5406                                     subtarget, ffs_optab);
5407       if (target)
5408         return target;
5409       break;
5410
5411     case BUILT_IN_CLZ:
5412     case BUILT_IN_CLZL:
5413     case BUILT_IN_CLZLL:
5414     case BUILT_IN_CLZIMAX:
5415       target = expand_builtin_unop (target_mode, arglist, target,
5416                                     subtarget, clz_optab);
5417       if (target)
5418         return target;
5419       break;
5420
5421     case BUILT_IN_CTZ:
5422     case BUILT_IN_CTZL:
5423     case BUILT_IN_CTZLL:
5424     case BUILT_IN_CTZIMAX:
5425       target = expand_builtin_unop (target_mode, arglist, target,
5426                                     subtarget, ctz_optab);
5427       if (target)
5428         return target;
5429       break;
5430
5431     case BUILT_IN_POPCOUNT:
5432     case BUILT_IN_POPCOUNTL:
5433     case BUILT_IN_POPCOUNTLL:
5434     case BUILT_IN_POPCOUNTIMAX:
5435       target = expand_builtin_unop (target_mode, arglist, target,
5436                                     subtarget, popcount_optab);
5437       if (target)
5438         return target;
5439       break;
5440
5441     case BUILT_IN_PARITY:
5442     case BUILT_IN_PARITYL:
5443     case BUILT_IN_PARITYLL:
5444     case BUILT_IN_PARITYIMAX:
5445       target = expand_builtin_unop (target_mode, arglist, target,
5446                                     subtarget, parity_optab);
5447       if (target)
5448         return target;
5449       break;
5450
5451     case BUILT_IN_STRLEN:
5452       target = expand_builtin_strlen (arglist, target, target_mode);
5453       if (target)
5454         return target;
5455       break;
5456
5457     case BUILT_IN_STRCPY:
5458       target = expand_builtin_strcpy (exp, target, mode);
5459       if (target)
5460         return target;
5461       break;
5462
5463     case BUILT_IN_STRNCPY:
5464       target = expand_builtin_strncpy (exp, target, mode);
5465       if (target)
5466         return target;
5467       break;
5468
5469     case BUILT_IN_STPCPY:
5470       target = expand_builtin_stpcpy (exp, target, mode);
5471       if (target)
5472         return target;
5473       break;
5474
5475     case BUILT_IN_STRCAT:
5476       target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
5477       if (target)
5478         return target;
5479       break;
5480
5481     case BUILT_IN_STRNCAT:
5482       target = expand_builtin_strncat (arglist, target, mode);
5483       if (target)
5484         return target;
5485       break;
5486
5487     case BUILT_IN_STRSPN:
5488       target = expand_builtin_strspn (arglist, target, mode);
5489       if (target)
5490         return target;
5491       break;
5492
5493     case BUILT_IN_STRCSPN:
5494       target = expand_builtin_strcspn (arglist, target, mode);
5495       if (target)
5496         return target;
5497       break;
5498
5499     case BUILT_IN_STRSTR:
5500       target = expand_builtin_strstr (arglist, TREE_TYPE (exp), target, mode);
5501       if (target)
5502         return target;
5503       break;
5504
5505     case BUILT_IN_STRPBRK:
5506       target = expand_builtin_strpbrk (arglist, TREE_TYPE (exp), target, mode);
5507       if (target)
5508         return target;
5509       break;
5510
5511     case BUILT_IN_INDEX:
5512     case BUILT_IN_STRCHR:
5513       target = expand_builtin_strchr (arglist, TREE_TYPE (exp), target, mode);
5514       if (target)
5515         return target;
5516       break;
5517
5518     case BUILT_IN_RINDEX:
5519     case BUILT_IN_STRRCHR:
5520       target = expand_builtin_strrchr (arglist, TREE_TYPE (exp), target, mode);
5521       if (target)
5522         return target;
5523       break;
5524
5525     case BUILT_IN_MEMCPY:
5526       target = expand_builtin_memcpy (exp, target, mode);
5527       if (target)
5528         return target;
5529       break;
5530
5531     case BUILT_IN_MEMPCPY:
5532       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5533       if (target)
5534         return target;
5535       break;
5536
5537     case BUILT_IN_MEMMOVE:
5538       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5539       if (target)
5540         return target;
5541       break;
5542
5543     case BUILT_IN_BCOPY:
5544       target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5545       if (target)
5546         return target;
5547       break;
5548
5549     case BUILT_IN_MEMSET:
5550       target = expand_builtin_memset (arglist, target, mode);
5551       if (target)
5552         return target;
5553       break;
5554
5555     case BUILT_IN_BZERO:
5556       target = expand_builtin_bzero (arglist);
5557       if (target)
5558         return target;
5559       break;
5560
5561     case BUILT_IN_STRCMP:
5562       target = expand_builtin_strcmp (exp, target, mode);
5563       if (target)
5564         return target;
5565       break;
5566
5567     case BUILT_IN_STRNCMP:
5568       target = expand_builtin_strncmp (exp, target, mode);
5569       if (target)
5570         return target;
5571       break;
5572
5573     case BUILT_IN_BCMP:
5574     case BUILT_IN_MEMCMP:
5575       target = expand_builtin_memcmp (exp, arglist, target, mode);
5576       if (target)
5577         return target;
5578       break;
5579
5580     case BUILT_IN_SETJMP:
5581       target = expand_builtin_setjmp (arglist, target);
5582       if (target)
5583         return target;
5584       break;
5585
5586       /* __builtin_longjmp is passed a pointer to an array of five words.
5587          It's similar to the C library longjmp function but works with
5588          __builtin_setjmp above.  */
5589     case BUILT_IN_LONGJMP:
5590       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5591         break;
5592       else
5593         {
5594           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5595                                       VOIDmode, 0);
5596           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5597                                    NULL_RTX, VOIDmode, 0);
5598
5599           if (value != const1_rtx)
5600             {
5601               error ("%<__builtin_longjmp%> second argument must be 1");
5602               return const0_rtx;
5603             }
5604
5605           expand_builtin_longjmp (buf_addr, value);
5606           return const0_rtx;
5607         }
5608
5609     case BUILT_IN_NONLOCAL_GOTO:
5610       target = expand_builtin_nonlocal_goto (arglist);
5611       if (target)
5612         return target;
5613       break;
5614
5615       /* This updates the setjmp buffer that is its argument with the value
5616          of the current stack pointer.  */
5617     case BUILT_IN_UPDATE_SETJMP_BUF:
5618       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5619         {
5620           rtx buf_addr
5621             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5622
5623           expand_builtin_update_setjmp_buf (buf_addr);
5624           return const0_rtx;
5625         }
5626       break;
5627
5628     case BUILT_IN_TRAP:
5629       expand_builtin_trap ();
5630       return const0_rtx;
5631
5632     case BUILT_IN_PRINTF:
5633       target = expand_builtin_printf (arglist, target, mode, false);
5634       if (target)
5635         return target;
5636       break;
5637
5638     case BUILT_IN_PRINTF_UNLOCKED:
5639       target = expand_builtin_printf (arglist, target, mode, true);
5640       if (target)
5641         return target;
5642       break;
5643
5644     case BUILT_IN_FPUTS:
5645       target = expand_builtin_fputs (arglist, target, false);
5646       if (target)
5647         return target;
5648       break;
5649     case BUILT_IN_FPUTS_UNLOCKED:
5650       target = expand_builtin_fputs (arglist, target, true);
5651       if (target)
5652         return target;
5653       break;
5654
5655     case BUILT_IN_FPRINTF:
5656       target = expand_builtin_fprintf (arglist, target, mode, false);
5657       if (target)
5658         return target;
5659       break;
5660
5661     case BUILT_IN_FPRINTF_UNLOCKED:
5662       target = expand_builtin_fprintf (arglist, target, mode, true);
5663       if (target)
5664         return target;
5665       break;
5666
5667     case BUILT_IN_SPRINTF:
5668       target = expand_builtin_sprintf (arglist, target, mode);
5669       if (target)
5670         return target;
5671       break;
5672
5673     case BUILT_IN_SIGNBIT:
5674     case BUILT_IN_SIGNBITF:
5675     case BUILT_IN_SIGNBITL:
5676       target = expand_builtin_signbit (exp, target);
5677       if (target)
5678         return target;
5679       break;
5680
5681       /* Various hooks for the DWARF 2 __throw routine.  */
5682     case BUILT_IN_UNWIND_INIT:
5683       expand_builtin_unwind_init ();
5684       return const0_rtx;
5685     case BUILT_IN_DWARF_CFA:
5686       return virtual_cfa_rtx;
5687 #ifdef DWARF2_UNWIND_INFO
5688     case BUILT_IN_DWARF_SP_COLUMN:
5689       return expand_builtin_dwarf_sp_column ();
5690     case BUILT_IN_INIT_DWARF_REG_SIZES:
5691       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5692       return const0_rtx;
5693 #endif
5694     case BUILT_IN_FROB_RETURN_ADDR:
5695       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5696     case BUILT_IN_EXTRACT_RETURN_ADDR:
5697       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5698     case BUILT_IN_EH_RETURN:
5699       expand_builtin_eh_return (TREE_VALUE (arglist),
5700                                 TREE_VALUE (TREE_CHAIN (arglist)));
5701       return const0_rtx;
5702 #ifdef EH_RETURN_DATA_REGNO
5703     case BUILT_IN_EH_RETURN_DATA_REGNO:
5704       return expand_builtin_eh_return_data_regno (arglist);
5705 #endif
5706     case BUILT_IN_EXTEND_POINTER:
5707       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5708
5709     case BUILT_IN_VA_START:
5710     case BUILT_IN_STDARG_START:
5711       return expand_builtin_va_start (arglist);
5712     case BUILT_IN_VA_END:
5713       return expand_builtin_va_end (arglist);
5714     case BUILT_IN_VA_COPY:
5715       return expand_builtin_va_copy (arglist);
5716     case BUILT_IN_EXPECT:
5717       return expand_builtin_expect (arglist, target);
5718     case BUILT_IN_PREFETCH:
5719       expand_builtin_prefetch (arglist);
5720       return const0_rtx;
5721
5722     case BUILT_IN_PROFILE_FUNC_ENTER:
5723       return expand_builtin_profile_func (false);
5724     case BUILT_IN_PROFILE_FUNC_EXIT:
5725       return expand_builtin_profile_func (true);
5726
5727     case BUILT_IN_INIT_TRAMPOLINE:
5728       return expand_builtin_init_trampoline (arglist);
5729     case BUILT_IN_ADJUST_TRAMPOLINE:
5730       return expand_builtin_adjust_trampoline (arglist);
5731
5732     case BUILT_IN_FORK:
5733     case BUILT_IN_EXECL:
5734     case BUILT_IN_EXECV:
5735     case BUILT_IN_EXECLP:
5736     case BUILT_IN_EXECLE:
5737     case BUILT_IN_EXECVP:
5738     case BUILT_IN_EXECVE:
5739       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5740       if (target)
5741         return target;
5742       break;
5743
5744     default:    /* just do library call, if unknown builtin */
5745       break;
5746     }
5747
5748   /* The switch statement above can drop through to cause the function
5749      to be called normally.  */
5750   return expand_call (exp, target, ignore);
5751 }
5752
5753 /* Determine whether a tree node represents a call to a built-in
5754    function.  If the tree T is a call to a built-in function with
5755    the right number of arguments of the appropriate types, return
5756    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5757    Otherwise the return value is END_BUILTINS.  */
5758
5759 enum built_in_function
5760 builtin_mathfn_code (tree t)
5761 {
5762   tree fndecl, arglist, parmlist;
5763   tree argtype, parmtype;
5764
5765   if (TREE_CODE (t) != CALL_EXPR
5766       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5767     return END_BUILTINS;
5768
5769   fndecl = get_callee_fndecl (t);
5770   if (fndecl == NULL_TREE
5771       || TREE_CODE (fndecl) != FUNCTION_DECL
5772       || ! DECL_BUILT_IN (fndecl)
5773       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5774     return END_BUILTINS;
5775
5776   arglist = TREE_OPERAND (t, 1);
5777   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5778   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5779     {
5780       /* If a function doesn't take a variable number of arguments,
5781          the last element in the list will have type `void'.  */
5782       parmtype = TREE_VALUE (parmlist);
5783       if (VOID_TYPE_P (parmtype))
5784         {
5785           if (arglist)
5786             return END_BUILTINS;
5787           return DECL_FUNCTION_CODE (fndecl);
5788         }
5789
5790       if (! arglist)
5791         return END_BUILTINS;
5792
5793       argtype = TREE_TYPE (TREE_VALUE (arglist));
5794
5795       if (SCALAR_FLOAT_TYPE_P (parmtype))
5796         {
5797           if (! SCALAR_FLOAT_TYPE_P (argtype))
5798             return END_BUILTINS;
5799         }
5800       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5801         {
5802           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5803             return END_BUILTINS;
5804         }
5805       else if (POINTER_TYPE_P (parmtype))
5806         {
5807           if (! POINTER_TYPE_P (argtype))
5808             return END_BUILTINS;
5809         }
5810       else if (INTEGRAL_TYPE_P (parmtype))
5811         {
5812           if (! INTEGRAL_TYPE_P (argtype))
5813             return END_BUILTINS;
5814         }
5815       else
5816         return END_BUILTINS;
5817
5818       arglist = TREE_CHAIN (arglist);
5819     }
5820
5821   /* Variable-length argument list.  */
5822   return DECL_FUNCTION_CODE (fndecl);
5823 }
5824
5825 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5826    constant.  ARGLIST is the argument list of the call.  */
5827
5828 static tree
5829 fold_builtin_constant_p (tree arglist)
5830 {
5831   if (arglist == 0)
5832     return 0;
5833
5834   arglist = TREE_VALUE (arglist);
5835
5836   /* We return 1 for a numeric type that's known to be a constant
5837      value at compile-time or for an aggregate type that's a
5838      literal constant.  */
5839   STRIP_NOPS (arglist);
5840
5841   /* If we know this is a constant, emit the constant of one.  */
5842   if (CONSTANT_CLASS_P (arglist)
5843       || (TREE_CODE (arglist) == CONSTRUCTOR
5844           && TREE_CONSTANT (arglist))
5845       || (TREE_CODE (arglist) == ADDR_EXPR
5846           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5847     return integer_one_node;
5848
5849   /* If this expression has side effects, show we don't know it to be a
5850      constant.  Likewise if it's a pointer or aggregate type since in
5851      those case we only want literals, since those are only optimized
5852      when generating RTL, not later.
5853      And finally, if we are compiling an initializer, not code, we
5854      need to return a definite result now; there's not going to be any
5855      more optimization done.  */
5856   if (TREE_SIDE_EFFECTS (arglist)
5857       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5858       || POINTER_TYPE_P (TREE_TYPE (arglist))
5859       || cfun == 0)
5860     return integer_zero_node;
5861
5862   return 0;
5863 }
5864
5865 /* Fold a call to __builtin_expect, if we expect that a comparison against
5866    the argument will fold to a constant.  In practice, this means a true
5867    constant or the address of a non-weak symbol.  ARGLIST is the argument
5868    list of the call.  */
5869
5870 static tree
5871 fold_builtin_expect (tree arglist)
5872 {
5873   tree arg, inner;
5874
5875   if (arglist == 0)
5876     return 0;
5877
5878   arg = TREE_VALUE (arglist);
5879
5880   /* If the argument isn't invariant, then there's nothing we can do.  */
5881   if (!TREE_INVARIANT (arg))
5882     return 0;
5883
5884   /* If we're looking at an address of a weak decl, then do not fold.  */
5885   inner = arg;
5886   STRIP_NOPS (inner);
5887   if (TREE_CODE (inner) == ADDR_EXPR)
5888     {
5889       do
5890         {
5891           inner = TREE_OPERAND (inner, 0);
5892         }
5893       while (TREE_CODE (inner) == COMPONENT_REF
5894              || TREE_CODE (inner) == ARRAY_REF);
5895       if (DECL_P (inner) && DECL_WEAK (inner))
5896         return 0;
5897     }
5898
5899   /* Otherwise, ARG already has the proper type for the return value.  */
5900   return arg;
5901 }
5902
5903 /* Fold a call to __builtin_classify_type.  */
5904
5905 static tree
5906 fold_builtin_classify_type (tree arglist)
5907 {
5908   if (arglist == 0)
5909     return build_int_cst (NULL_TREE, no_type_class);
5910
5911   return build_int_cst (NULL_TREE,
5912                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
5913 }
5914
5915 /* Fold a call to __builtin_strlen.  */
5916
5917 static tree
5918 fold_builtin_strlen (tree arglist)
5919 {
5920   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5921     return NULL_TREE;
5922   else
5923     {
5924       tree len = c_strlen (TREE_VALUE (arglist), 0);
5925
5926       if (len)
5927         {
5928           /* Convert from the internal "sizetype" type to "size_t".  */
5929           if (size_type_node)
5930             len = fold_convert (size_type_node, len);
5931           return len;
5932         }
5933
5934       return NULL_TREE;
5935     }
5936 }
5937
5938 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5939
5940 static tree
5941 fold_builtin_inf (tree type, int warn)
5942 {
5943   REAL_VALUE_TYPE real;
5944
5945   /* __builtin_inff is intended to be usable to define INFINITY on all
5946      targets.  If an infinity is not available, INFINITY expands "to a
5947      positive constant of type float that overflows at translation
5948      time", footnote "In this case, using INFINITY will violate the
5949      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
5950      Thus we pedwarn to ensure this constraint violation is
5951      diagnosed.  */
5952   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5953     pedwarn ("target format does not support infinity");
5954
5955   real_inf (&real);
5956   return build_real (type, real);
5957 }
5958
5959 /* Fold a call to __builtin_nan or __builtin_nans.  */
5960
5961 static tree
5962 fold_builtin_nan (tree arglist, tree type, int quiet)
5963 {
5964   REAL_VALUE_TYPE real;
5965   const char *str;
5966
5967   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5968     return 0;
5969   str = c_getstr (TREE_VALUE (arglist));
5970   if (!str)
5971     return 0;
5972
5973   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5974     return 0;
5975
5976   return build_real (type, real);
5977 }
5978
5979 /* Return true if the floating point expression T has an integer value.
5980    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5981
5982 static bool
5983 integer_valued_real_p (tree t)
5984 {
5985   switch (TREE_CODE (t))
5986     {
5987     case FLOAT_EXPR:
5988       return true;
5989
5990     case ABS_EXPR:
5991     case SAVE_EXPR:
5992     case NON_LVALUE_EXPR:
5993       return integer_valued_real_p (TREE_OPERAND (t, 0));
5994
5995     case COMPOUND_EXPR:
5996     case MODIFY_EXPR:
5997     case BIND_EXPR:
5998       return integer_valued_real_p (TREE_OPERAND (t, 1));
5999
6000     case PLUS_EXPR:
6001     case MINUS_EXPR:
6002     case MULT_EXPR:
6003     case MIN_EXPR:
6004     case MAX_EXPR:
6005       return integer_valued_real_p (TREE_OPERAND (t, 0))
6006              && integer_valued_real_p (TREE_OPERAND (t, 1));
6007
6008     case COND_EXPR:
6009       return integer_valued_real_p (TREE_OPERAND (t, 1))
6010              && integer_valued_real_p (TREE_OPERAND (t, 2));
6011
6012     case REAL_CST:
6013       if (! TREE_CONSTANT_OVERFLOW (t))
6014       {
6015         REAL_VALUE_TYPE c, cint;
6016
6017         c = TREE_REAL_CST (t);
6018         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6019         return real_identical (&c, &cint);
6020       }
6021
6022     case NOP_EXPR:
6023       {
6024         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6025         if (TREE_CODE (type) == INTEGER_TYPE)
6026           return true;
6027         if (TREE_CODE (type) == REAL_TYPE)
6028           return integer_valued_real_p (TREE_OPERAND (t, 0));
6029         break;
6030       }
6031
6032     case CALL_EXPR:
6033       switch (builtin_mathfn_code (t))
6034         {
6035         case BUILT_IN_CEIL:
6036         case BUILT_IN_CEILF:
6037         case BUILT_IN_CEILL:
6038         case BUILT_IN_FLOOR:
6039         case BUILT_IN_FLOORF:
6040         case BUILT_IN_FLOORL:
6041         case BUILT_IN_NEARBYINT:
6042         case BUILT_IN_NEARBYINTF:
6043         case BUILT_IN_NEARBYINTL:
6044         case BUILT_IN_RINT:
6045         case BUILT_IN_RINTF:
6046         case BUILT_IN_RINTL:
6047         case BUILT_IN_ROUND:
6048         case BUILT_IN_ROUNDF:
6049         case BUILT_IN_ROUNDL:
6050         case BUILT_IN_TRUNC:
6051         case BUILT_IN_TRUNCF:
6052         case BUILT_IN_TRUNCL:
6053           return true;
6054
6055         default:
6056           break;
6057         }
6058       break;
6059
6060     default:
6061       break;
6062     }
6063   return false;
6064 }
6065
6066 /* EXP is assumed to be builtin call where truncation can be propagated
6067    across (for instance floor((double)f) == (double)floorf (f).
6068    Do the transformation.  */
6069
6070 static tree
6071 fold_trunc_transparent_mathfn (tree exp)
6072 {
6073   tree fndecl = get_callee_fndecl (exp);
6074   tree arglist = TREE_OPERAND (exp, 1);
6075   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6076   tree arg;
6077
6078   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6079     return 0;
6080
6081   arg = TREE_VALUE (arglist);
6082   /* Integer rounding functions are idempotent.  */
6083   if (fcode == builtin_mathfn_code (arg))
6084     return arg;
6085
6086   /* If argument is already integer valued, and we don't need to worry
6087      about setting errno, there's no need to perform rounding.  */
6088   if (! flag_errno_math && integer_valued_real_p (arg))
6089     return arg;
6090
6091   if (optimize)
6092     {
6093       tree arg0 = strip_float_extensions (arg);
6094       tree ftype = TREE_TYPE (TREE_TYPE (fndecl));
6095       tree newtype = TREE_TYPE (arg0);
6096       tree decl;
6097
6098       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6099           && (decl = mathfn_built_in (newtype, fcode)))
6100         {
6101           arglist =
6102             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6103           return fold_convert (ftype,
6104                                build_function_call_expr (decl, arglist));
6105         }
6106     }
6107   return 0;
6108 }
6109
6110 /* EXP is assumed to be builtin call which can narrow the FP type of
6111    the argument, for instance lround((double)f) -> lroundf (f).  */
6112
6113 static tree
6114 fold_fixed_mathfn (tree exp)
6115 {
6116   tree fndecl = get_callee_fndecl (exp);
6117   tree arglist = TREE_OPERAND (exp, 1);
6118   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6119   tree arg;
6120
6121   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6122     return 0;
6123
6124   arg = TREE_VALUE (arglist);
6125
6126   /* If argument is already integer valued, and we don't need to worry
6127      about setting errno, there's no need to perform rounding.  */
6128   if (! flag_errno_math && integer_valued_real_p (arg))
6129     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (TREE_TYPE (fndecl)), arg));
6130
6131   if (optimize)
6132     {
6133       tree ftype = TREE_TYPE (arg);
6134       tree arg0 = strip_float_extensions (arg);
6135       tree newtype = TREE_TYPE (arg0);
6136       tree decl;
6137
6138       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6139           && (decl = mathfn_built_in (newtype, fcode)))
6140         {
6141           arglist =
6142             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6143           return build_function_call_expr (decl, arglist);
6144         }
6145     }
6146   return 0;
6147 }
6148
6149 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6150    is the argument list and TYPE is the return type.  Return
6151    NULL_TREE if no if no simplification can be made.  */
6152
6153 static tree
6154 fold_builtin_cabs (tree arglist, tree type)
6155 {
6156   tree arg;
6157
6158   if (!arglist || TREE_CHAIN (arglist))
6159     return NULL_TREE;
6160
6161   arg = TREE_VALUE (arglist);
6162   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6163       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6164     return NULL_TREE;
6165
6166   /* Evaluate cabs of a constant at compile-time.  */
6167   if (flag_unsafe_math_optimizations
6168       && TREE_CODE (arg) == COMPLEX_CST
6169       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6170       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6171       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6172       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6173     {
6174       REAL_VALUE_TYPE r, i;
6175
6176       r = TREE_REAL_CST (TREE_REALPART (arg));
6177       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6178
6179       real_arithmetic (&r, MULT_EXPR, &r, &r);
6180       real_arithmetic (&i, MULT_EXPR, &i, &i);
6181       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6182       if (real_sqrt (&r, TYPE_MODE (type), &r)
6183           || ! flag_trapping_math)
6184         return build_real (type, r);
6185     }
6186
6187   /* If either part is zero, cabs is fabs of the other.  */
6188   if (TREE_CODE (arg) == COMPLEX_EXPR
6189       && real_zerop (TREE_OPERAND (arg, 0)))
6190     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6191   if (TREE_CODE (arg) == COMPLEX_EXPR
6192       && real_zerop (TREE_OPERAND (arg, 1)))
6193     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6194
6195   /* Don't do this when optimizing for size.  */
6196   if (flag_unsafe_math_optimizations
6197       && optimize && !optimize_size)
6198     {
6199       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6200
6201       if (sqrtfn != NULL_TREE)
6202         {
6203           tree rpart, ipart, result, arglist;
6204
6205           arg = builtin_save_expr (arg);
6206
6207           rpart = fold (build1 (REALPART_EXPR, type, arg));
6208           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6209
6210           rpart = builtin_save_expr (rpart);
6211           ipart = builtin_save_expr (ipart);
6212
6213           result = fold (build2 (PLUS_EXPR, type,
6214                                  fold (build2 (MULT_EXPR, type,
6215                                                rpart, rpart)),
6216                                  fold (build2 (MULT_EXPR, type,
6217                                                ipart, ipart))));
6218
6219           arglist = build_tree_list (NULL_TREE, result);
6220           return build_function_call_expr (sqrtfn, arglist);
6221         }
6222     }
6223
6224   return NULL_TREE;
6225 }
6226
6227 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6228    NULL_TREE if no simplification can be made.  */
6229
6230 static tree
6231 fold_builtin_sqrt (tree arglist, tree type)
6232 {
6233
6234   enum built_in_function fcode;
6235   tree arg = TREE_VALUE (arglist);
6236
6237   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6238     return NULL_TREE;
6239
6240   /* Optimize sqrt of constant value.  */
6241   if (TREE_CODE (arg) == REAL_CST
6242       && ! TREE_CONSTANT_OVERFLOW (arg))
6243     {
6244       REAL_VALUE_TYPE r, x;
6245
6246       x = TREE_REAL_CST (arg);
6247       if (real_sqrt (&r, TYPE_MODE (type), &x)
6248           || (!flag_trapping_math && !flag_errno_math))
6249         return build_real (type, r);
6250     }
6251
6252   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6253   fcode = builtin_mathfn_code (arg);
6254   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6255     {
6256       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6257       arg = fold (build2 (MULT_EXPR, type,
6258                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6259                           build_real (type, dconsthalf)));
6260       arglist = build_tree_list (NULL_TREE, arg);
6261       return build_function_call_expr (expfn, arglist);
6262     }
6263
6264   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6265   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6266     {
6267       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6268
6269       if (powfn)
6270         {
6271           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6272           tree tree_root;
6273           /* The inner root was either sqrt or cbrt.  */
6274           REAL_VALUE_TYPE dconstroot =
6275             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6276
6277           /* Adjust for the outer root.  */
6278           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6279           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6280           tree_root = build_real (type, dconstroot);
6281           arglist = tree_cons (NULL_TREE, arg0,
6282                                build_tree_list (NULL_TREE, tree_root));
6283           return build_function_call_expr (powfn, arglist);
6284         }
6285     }
6286
6287   /* Optimize sqrt(pow(x,y)) = pow(|x|,y*0.5).  */
6288   if (flag_unsafe_math_optimizations
6289       && (fcode == BUILT_IN_POW
6290           || fcode == BUILT_IN_POWF
6291           || fcode == BUILT_IN_POWL))
6292     {
6293       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6294       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6295       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6296       tree narg1;
6297       if (!tree_expr_nonnegative_p (arg0))
6298         arg0 = build1 (ABS_EXPR, type, arg0);
6299       narg1 = fold (build2 (MULT_EXPR, type, arg1,
6300                             build_real (type, dconsthalf)));
6301       arglist = tree_cons (NULL_TREE, arg0,
6302                            build_tree_list (NULL_TREE, narg1));
6303       return build_function_call_expr (powfn, arglist);
6304     }
6305
6306   return NULL_TREE;
6307 }
6308
6309 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6310    NULL_TREE if no simplification can be made.  */
6311 static tree
6312 fold_builtin_cbrt (tree arglist, tree type)
6313 {
6314   tree arg = TREE_VALUE (arglist);
6315   const enum built_in_function fcode = builtin_mathfn_code (arg);
6316
6317   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6318     return NULL_TREE;
6319
6320   /* Optimize cbrt of constant value.  */
6321   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6322     return arg;
6323
6324   if (flag_unsafe_math_optimizations)
6325     {
6326       /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6327       if (BUILTIN_EXPONENT_P (fcode))
6328         {
6329           tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6330           const REAL_VALUE_TYPE third_trunc =
6331             real_value_truncate (TYPE_MODE (type), dconstthird);
6332           arg = fold (build2 (MULT_EXPR, type,
6333                               TREE_VALUE (TREE_OPERAND (arg, 1)),
6334                               build_real (type, third_trunc)));
6335           arglist = build_tree_list (NULL_TREE, arg);
6336           return build_function_call_expr (expfn, arglist);
6337         }
6338
6339       /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6340       if (BUILTIN_SQRT_P (fcode))
6341         {
6342           tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6343
6344           if (powfn)
6345             {
6346               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6347               tree tree_root;
6348               REAL_VALUE_TYPE dconstroot = dconstthird;
6349
6350               SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6351               dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6352               tree_root = build_real (type, dconstroot);
6353               arglist = tree_cons (NULL_TREE, arg0,
6354                                    build_tree_list (NULL_TREE, tree_root));
6355               return build_function_call_expr (powfn, arglist);
6356             }
6357         }
6358
6359       /* Optimize cbrt(cbrt(x)) -> pow(x,1/9) iff x is nonnegative.  */
6360       if (BUILTIN_CBRT_P (fcode))
6361         {
6362           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6363           if (tree_expr_nonnegative_p (arg0))
6364             {
6365               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6366
6367               if (powfn)
6368                 {
6369                   tree tree_root;
6370                   REAL_VALUE_TYPE dconstroot;
6371               
6372                   real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird);
6373                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6374                   tree_root = build_real (type, dconstroot);
6375                   arglist = tree_cons (NULL_TREE, arg0,
6376                                        build_tree_list (NULL_TREE, tree_root));
6377                   return build_function_call_expr (powfn, arglist);
6378                 }
6379             }
6380         }
6381       
6382       /* Optimize cbrt(pow(x,y)) -> pow(x,y/3) iff x is nonnegative.  */
6383       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
6384           || fcode == BUILT_IN_POWL)
6385         {
6386           tree arg00 = TREE_VALUE (TREE_OPERAND (arg, 1));
6387           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6388           if (tree_expr_nonnegative_p (arg00))
6389             {
6390               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6391               const REAL_VALUE_TYPE dconstroot
6392                 = real_value_truncate (TYPE_MODE (type), dconstthird);
6393               tree narg01 = fold (build2 (MULT_EXPR, type, arg01,
6394                                           build_real (type, dconstroot)));
6395               arglist = tree_cons (NULL_TREE, arg00,
6396                                    build_tree_list (NULL_TREE, narg01));
6397               return build_function_call_expr (powfn, arglist);
6398             }
6399         }
6400     }
6401   return NULL_TREE;
6402 }
6403
6404 /* Fold function call to builtin sin, sinf, or sinl.  Return
6405    NULL_TREE if no simplification can be made.  */
6406 static tree
6407 fold_builtin_sin (tree arglist)
6408 {
6409   tree arg = TREE_VALUE (arglist);
6410
6411   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6412     return NULL_TREE;
6413
6414   /* Optimize sin (0.0) = 0.0.  */
6415   if (real_zerop (arg))
6416     return arg;
6417
6418   return NULL_TREE;
6419 }
6420
6421 /* Fold function call to builtin cos, cosf, or cosl.  Return
6422    NULL_TREE if no simplification can be made.  */
6423 static tree
6424 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6425 {
6426   tree arg = TREE_VALUE (arglist);
6427
6428   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6429     return NULL_TREE;
6430
6431   /* Optimize cos (0.0) = 1.0.  */
6432   if (real_zerop (arg))
6433     return build_real (type, dconst1);
6434
6435   /* Optimize cos(-x) into cos (x).  */
6436   if (TREE_CODE (arg) == NEGATE_EXPR)
6437     {
6438       tree args = build_tree_list (NULL_TREE,
6439                                    TREE_OPERAND (arg, 0));
6440       return build_function_call_expr (fndecl, args);
6441     }
6442
6443   return NULL_TREE;
6444 }
6445
6446 /* Fold function call to builtin tan, tanf, or tanl.  Return
6447    NULL_TREE if no simplification can be made.  */
6448 static tree
6449 fold_builtin_tan (tree arglist)
6450 {
6451   enum built_in_function fcode;
6452   tree arg = TREE_VALUE (arglist);
6453
6454   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6455     return NULL_TREE;
6456
6457   /* Optimize tan(0.0) = 0.0.  */
6458   if (real_zerop (arg))
6459     return arg;
6460
6461   /* Optimize tan(atan(x)) = x.  */
6462   fcode = builtin_mathfn_code (arg);
6463   if (flag_unsafe_math_optimizations
6464       && (fcode == BUILT_IN_ATAN
6465           || fcode == BUILT_IN_ATANF
6466           || fcode == BUILT_IN_ATANL))
6467     return TREE_VALUE (TREE_OPERAND (arg, 1));
6468
6469   return NULL_TREE;
6470 }
6471
6472 /* Fold function call to builtin atan, atanf, or atanl.  Return
6473    NULL_TREE if no simplification can be made.  */
6474
6475 static tree
6476 fold_builtin_atan (tree arglist, tree type)
6477 {
6478
6479   tree arg = TREE_VALUE (arglist);
6480
6481   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6482     return NULL_TREE;
6483
6484   /* Optimize atan(0.0) = 0.0.  */
6485   if (real_zerop (arg))
6486     return arg;
6487
6488   /* Optimize atan(1.0) = pi/4.  */
6489   if (real_onep (arg))
6490     {
6491       REAL_VALUE_TYPE cst;
6492
6493       real_convert (&cst, TYPE_MODE (type), &dconstpi);
6494       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6495       return build_real (type, cst);
6496     }
6497
6498   return NULL_TREE;
6499 }
6500
6501 /* Fold function call to builtin trunc, truncf or truncl.  Return
6502    NULL_TREE if no simplification can be made.  */
6503
6504 static tree
6505 fold_builtin_trunc (tree exp)
6506 {
6507   tree fndecl = get_callee_fndecl (exp);
6508   tree arglist = TREE_OPERAND (exp, 1);
6509   tree arg;
6510
6511   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6512     return 0;
6513
6514   /* Optimize trunc of constant value.  */
6515   arg = TREE_VALUE (arglist);
6516   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6517     {
6518       REAL_VALUE_TYPE r, x;
6519       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6520
6521       x = TREE_REAL_CST (arg);
6522       real_trunc (&r, TYPE_MODE (type), &x);
6523       return build_real (type, r);
6524     }
6525
6526   return fold_trunc_transparent_mathfn (exp);
6527 }
6528
6529 /* Fold function call to builtin floor, floorf or floorl.  Return
6530    NULL_TREE if no simplification can be made.  */
6531
6532 static tree
6533 fold_builtin_floor (tree exp)
6534 {
6535   tree fndecl = get_callee_fndecl (exp);
6536   tree arglist = TREE_OPERAND (exp, 1);
6537   tree arg;
6538
6539   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6540     return 0;
6541
6542   /* Optimize floor of constant value.  */
6543   arg = TREE_VALUE (arglist);
6544   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6545     {
6546       REAL_VALUE_TYPE x;
6547
6548       x = TREE_REAL_CST (arg);
6549       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6550         {
6551           tree type = TREE_TYPE (TREE_TYPE (fndecl));
6552           REAL_VALUE_TYPE r;
6553
6554           real_floor (&r, TYPE_MODE (type), &x);
6555           return build_real (type, r);
6556         }
6557     }
6558
6559   return fold_trunc_transparent_mathfn (exp);
6560 }
6561
6562 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6563    NULL_TREE if no simplification can be made.  */
6564
6565 static tree
6566 fold_builtin_ceil (tree exp)
6567 {
6568   tree fndecl = get_callee_fndecl (exp);
6569   tree arglist = TREE_OPERAND (exp, 1);
6570   tree arg;
6571
6572   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6573     return 0;
6574
6575   /* Optimize ceil of constant value.  */
6576   arg = TREE_VALUE (arglist);
6577   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6578     {
6579       REAL_VALUE_TYPE x;
6580
6581       x = TREE_REAL_CST (arg);
6582       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6583         {
6584           tree type = TREE_TYPE (TREE_TYPE (fndecl));
6585           REAL_VALUE_TYPE r;
6586
6587           real_ceil (&r, TYPE_MODE (type), &x);
6588           return build_real (type, r);
6589         }
6590     }
6591
6592   return fold_trunc_transparent_mathfn (exp);
6593 }
6594
6595 /* Fold function call to builtin round, roundf or roundl.  Return
6596    NULL_TREE if no simplification can be made.  */
6597
6598 static tree
6599 fold_builtin_round (tree exp)
6600 {
6601   tree fndecl = get_callee_fndecl (exp);
6602   tree arglist = TREE_OPERAND (exp, 1);
6603   tree arg;
6604
6605   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6606     return 0;
6607
6608   /* Optimize round of constant value.  */
6609   arg = TREE_VALUE (arglist);
6610   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6611     {
6612       REAL_VALUE_TYPE x;
6613
6614       x = TREE_REAL_CST (arg);
6615       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6616         {
6617           tree type = TREE_TYPE (TREE_TYPE (fndecl));
6618           REAL_VALUE_TYPE r;
6619
6620           real_round (&r, TYPE_MODE (type), &x);
6621           return build_real (type, r);
6622         }
6623     }
6624
6625   return fold_trunc_transparent_mathfn (exp);
6626 }
6627
6628 /* Fold function call to builtin lround, lroundf or lroundl (or the
6629    corresponding long long versions).  Return NULL_TREE if no
6630    simplification can be made.  */
6631
6632 static tree
6633 fold_builtin_lround (tree exp)
6634 {
6635   tree fndecl = get_callee_fndecl (exp);
6636   tree arglist = TREE_OPERAND (exp, 1);
6637   tree arg;
6638
6639   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6640     return 0;
6641
6642   /* Optimize lround of constant value.  */
6643   arg = TREE_VALUE (arglist);
6644   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6645     {
6646       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6647
6648       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6649         {
6650           tree itype = TREE_TYPE (TREE_TYPE (fndecl));
6651           tree ftype = TREE_TYPE (arg), result;
6652           HOST_WIDE_INT hi, lo;
6653           REAL_VALUE_TYPE r;
6654
6655           real_round (&r, TYPE_MODE (ftype), &x);
6656           REAL_VALUE_TO_INT (&lo, &hi, r);
6657           result = build_int_cst_wide (NULL_TREE, lo, hi);
6658           if (int_fits_type_p (result, itype))
6659             return fold_convert (itype, result);
6660         }
6661     }
6662
6663   return fold_fixed_mathfn (exp);
6664 }
6665
6666 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6667    and their long and long long variants (i.e. ffsl and ffsll).
6668    Return NULL_TREE if no simplification can be made.  */
6669
6670 static tree
6671 fold_builtin_bitop (tree fndecl, tree arglist)
6672 {
6673   tree arg;
6674
6675   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6676     return NULL_TREE;
6677
6678   /* Optimize for constant argument.  */
6679   arg = TREE_VALUE (arglist);
6680   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6681     {
6682       HOST_WIDE_INT hi, width, result;
6683       unsigned HOST_WIDE_INT lo;
6684       tree type;
6685
6686       type = TREE_TYPE (arg);
6687       width = TYPE_PRECISION (type);
6688       lo = TREE_INT_CST_LOW (arg);
6689
6690       /* Clear all the bits that are beyond the type's precision.  */
6691       if (width > HOST_BITS_PER_WIDE_INT)
6692         {
6693           hi = TREE_INT_CST_HIGH (arg);
6694           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6695             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6696         }
6697       else
6698         {
6699           hi = 0;
6700           if (width < HOST_BITS_PER_WIDE_INT)
6701             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6702         }
6703
6704       switch (DECL_FUNCTION_CODE (fndecl))
6705         {
6706         case BUILT_IN_FFS:
6707         case BUILT_IN_FFSL:
6708         case BUILT_IN_FFSLL:
6709           if (lo != 0)
6710             result = exact_log2 (lo & -lo) + 1;
6711           else if (hi != 0)
6712             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6713           else
6714             result = 0;
6715           break;
6716
6717         case BUILT_IN_CLZ:
6718         case BUILT_IN_CLZL:
6719         case BUILT_IN_CLZLL:
6720           if (hi != 0)
6721             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6722           else if (lo != 0)
6723             result = width - floor_log2 (lo) - 1;
6724           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6725             result = width;
6726           break;
6727
6728         case BUILT_IN_CTZ:
6729         case BUILT_IN_CTZL:
6730         case BUILT_IN_CTZLL:
6731           if (lo != 0)
6732             result = exact_log2 (lo & -lo);
6733           else if (hi != 0)
6734             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6735           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6736             result = width;
6737           break;
6738
6739         case BUILT_IN_POPCOUNT:
6740         case BUILT_IN_POPCOUNTL:
6741         case BUILT_IN_POPCOUNTLL:
6742           result = 0;
6743           while (lo)
6744             result++, lo &= lo - 1;
6745           while (hi)
6746             result++, hi &= hi - 1;
6747           break;
6748
6749         case BUILT_IN_PARITY:
6750         case BUILT_IN_PARITYL:
6751         case BUILT_IN_PARITYLL:
6752           result = 0;
6753           while (lo)
6754             result++, lo &= lo - 1;
6755           while (hi)
6756             result++, hi &= hi - 1;
6757           result &= 1;
6758           break;
6759
6760         default:
6761           gcc_unreachable ();
6762         }
6763
6764       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
6765     }
6766
6767   return NULL_TREE;
6768 }
6769
6770 /* Return true if EXPR is the real constant contained in VALUE.  */
6771
6772 static bool
6773 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6774 {
6775   STRIP_NOPS (expr);
6776
6777   return ((TREE_CODE (expr) == REAL_CST
6778            && ! TREE_CONSTANT_OVERFLOW (expr)
6779            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6780           || (TREE_CODE (expr) == COMPLEX_CST
6781               && real_dconstp (TREE_REALPART (expr), value)
6782               && real_zerop (TREE_IMAGPART (expr))));
6783 }
6784
6785 /* A subroutine of fold_builtin to fold the various logarithmic
6786    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6787    function.  VALUE is the base of the logN function.  */
6788
6789 static tree
6790 fold_builtin_logarithm (tree fndecl, tree arglist,
6791                         const REAL_VALUE_TYPE *value)
6792 {
6793   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6794     {
6795       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6796       tree arg = TREE_VALUE (arglist);
6797       const enum built_in_function fcode = builtin_mathfn_code (arg);
6798
6799       /* Optimize logN(1.0) = 0.0.  */
6800       if (real_onep (arg))
6801         return build_real (type, dconst0);
6802
6803       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6804          exactly, then only do this if flag_unsafe_math_optimizations.  */
6805       if (exact_real_truncate (TYPE_MODE (type), value)
6806           || flag_unsafe_math_optimizations)
6807         {
6808           const REAL_VALUE_TYPE value_truncate =
6809             real_value_truncate (TYPE_MODE (type), *value);
6810           if (real_dconstp (arg, &value_truncate))
6811             return build_real (type, dconst1);
6812         }
6813
6814       /* Special case, optimize logN(expN(x)) = x.  */
6815       if (flag_unsafe_math_optimizations
6816           && ((value == &dconste
6817                && (fcode == BUILT_IN_EXP
6818                    || fcode == BUILT_IN_EXPF
6819                    || fcode == BUILT_IN_EXPL))
6820               || (value == &dconst2
6821                   && (fcode == BUILT_IN_EXP2
6822                       || fcode == BUILT_IN_EXP2F
6823                       || fcode == BUILT_IN_EXP2L))
6824               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6825         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6826
6827       /* Optimize logN(func()) for various exponential functions.  We
6828          want to determine the value "x" and the power "exponent" in
6829          order to transform logN(x**exponent) into exponent*logN(x).  */
6830       if (flag_unsafe_math_optimizations)
6831         {
6832           tree exponent = 0, x = 0;
6833
6834           switch (fcode)
6835           {
6836           case BUILT_IN_EXP:
6837           case BUILT_IN_EXPF:
6838           case BUILT_IN_EXPL:
6839             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6840             x = build_real (type,
6841                             real_value_truncate (TYPE_MODE (type), dconste));
6842             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6843             break;
6844           case BUILT_IN_EXP2:
6845           case BUILT_IN_EXP2F:
6846           case BUILT_IN_EXP2L:
6847             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6848             x = build_real (type, dconst2);
6849             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6850             break;
6851           case BUILT_IN_EXP10:
6852           case BUILT_IN_EXP10F:
6853           case BUILT_IN_EXP10L:
6854           case BUILT_IN_POW10:
6855           case BUILT_IN_POW10F:
6856           case BUILT_IN_POW10L:
6857             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6858             x = build_real (type, dconst10);
6859             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6860             break;
6861           case BUILT_IN_SQRT:
6862           case BUILT_IN_SQRTF:
6863           case BUILT_IN_SQRTL:
6864             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6865             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6866             exponent = build_real (type, dconsthalf);
6867             break;
6868           case BUILT_IN_CBRT:
6869           case BUILT_IN_CBRTF:
6870           case BUILT_IN_CBRTL:
6871             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6872             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6873             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6874                                                               dconstthird));
6875             break;
6876           case BUILT_IN_POW:
6877           case BUILT_IN_POWF:
6878           case BUILT_IN_POWL:
6879             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6880             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6881             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6882             break;
6883           default:
6884             break;
6885           }
6886
6887           /* Now perform the optimization.  */
6888           if (x && exponent)
6889             {
6890               tree logfn;
6891               arglist = build_tree_list (NULL_TREE, x);
6892               logfn = build_function_call_expr (fndecl, arglist);
6893               return fold (build2 (MULT_EXPR, type, exponent, logfn));
6894             }
6895         }
6896     }
6897
6898   return 0;
6899 }
6900
6901 /* Fold a builtin function call to pow, powf, or powl.  Return
6902    NULL_TREE if no simplification can be made.  */
6903 static tree
6904 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6905 {
6906   tree arg0 = TREE_VALUE (arglist);
6907   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6908
6909   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6910     return NULL_TREE;
6911
6912   /* Optimize pow(1.0,y) = 1.0.  */
6913   if (real_onep (arg0))
6914     return omit_one_operand (type, build_real (type, dconst1), arg1);
6915
6916   if (TREE_CODE (arg1) == REAL_CST
6917       && ! TREE_CONSTANT_OVERFLOW (arg1))
6918     {
6919       REAL_VALUE_TYPE cint;
6920       REAL_VALUE_TYPE c;
6921       HOST_WIDE_INT n;
6922
6923       c = TREE_REAL_CST (arg1);
6924
6925       /* Optimize pow(x,0.0) = 1.0.  */
6926       if (REAL_VALUES_EQUAL (c, dconst0))
6927         return omit_one_operand (type, build_real (type, dconst1),
6928                                  arg0);
6929
6930       /* Optimize pow(x,1.0) = x.  */
6931       if (REAL_VALUES_EQUAL (c, dconst1))
6932         return arg0;
6933
6934       /* Optimize pow(x,-1.0) = 1.0/x.  */
6935       if (REAL_VALUES_EQUAL (c, dconstm1))
6936         return fold (build2 (RDIV_EXPR, type,
6937                              build_real (type, dconst1), arg0));
6938
6939       /* Optimize pow(x,0.5) = sqrt(x).  */
6940       if (flag_unsafe_math_optimizations
6941           && REAL_VALUES_EQUAL (c, dconsthalf))
6942         {
6943           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6944
6945           if (sqrtfn != NULL_TREE)
6946             {
6947               tree arglist = build_tree_list (NULL_TREE, arg0);
6948               return build_function_call_expr (sqrtfn, arglist);
6949             }
6950         }
6951
6952       /* Check for an integer exponent.  */
6953       n = real_to_integer (&c);
6954       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
6955       if (real_identical (&c, &cint))
6956         {
6957           /* Attempt to evaluate pow at compile-time.  */
6958           if (TREE_CODE (arg0) == REAL_CST
6959               && ! TREE_CONSTANT_OVERFLOW (arg0))
6960             {
6961               REAL_VALUE_TYPE x;
6962               bool inexact;
6963
6964               x = TREE_REAL_CST (arg0);
6965               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6966               if (flag_unsafe_math_optimizations || !inexact)
6967                 return build_real (type, x);
6968             }
6969
6970           /* Strip sign ops from even integer powers.  */
6971           if ((n & 1) == 0 && flag_unsafe_math_optimizations)
6972             {
6973               tree narg0 = fold_strip_sign_ops (arg0);
6974               if (narg0)
6975                 {
6976                   arglist = build_tree_list (NULL_TREE, arg1);
6977                   arglist = tree_cons (NULL_TREE, narg0, arglist);
6978                   return build_function_call_expr (fndecl, arglist);
6979                 }
6980             }
6981         }
6982     }
6983
6984   if (flag_unsafe_math_optimizations)
6985     {
6986       const enum built_in_function fcode = builtin_mathfn_code (arg0);
6987
6988       /* Optimize pow(expN(x),y) = expN(x*y).  */
6989       if (BUILTIN_EXPONENT_P (fcode))
6990         {
6991           tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6992           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6993           arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6994           arglist = build_tree_list (NULL_TREE, arg);
6995           return build_function_call_expr (expfn, arglist);
6996         }
6997
6998       /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6999       if (BUILTIN_SQRT_P (fcode))
7000         {
7001           tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7002           tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7003                                      build_real (type, dconsthalf)));
7004
7005           arglist = tree_cons (NULL_TREE, narg0,
7006                                build_tree_list (NULL_TREE, narg1));
7007           return build_function_call_expr (fndecl, arglist);
7008         }
7009
7010       /* Optimize pow(cbrt(x),y) = pow(x,y/3) iff x is nonnegative.  */
7011       if (BUILTIN_CBRT_P (fcode))
7012         {
7013           tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
7014           if (tree_expr_nonnegative_p (arg))
7015             {
7016               const REAL_VALUE_TYPE dconstroot
7017                 = real_value_truncate (TYPE_MODE (type), dconstthird);
7018               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7019                                          build_real (type, dconstroot)));
7020               arglist = tree_cons (NULL_TREE, arg,
7021                                    build_tree_list (NULL_TREE, narg1));
7022               return build_function_call_expr (fndecl, arglist);
7023             }
7024         }
7025       
7026       /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
7027       if (fcode == BUILT_IN_POW || fcode == BUILT_IN_POWF
7028            || fcode == BUILT_IN_POWL)
7029         {
7030           tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
7031           tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
7032           tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
7033           arglist = tree_cons (NULL_TREE, arg00,
7034                                build_tree_list (NULL_TREE, narg1));
7035           return build_function_call_expr (fndecl, arglist);
7036         }
7037     }
7038
7039   return NULL_TREE;
7040 }
7041
7042 /* Fold a builtin function call to powi, powif, or powil.  Return
7043    NULL_TREE if no simplification can be made.  */
7044 static tree
7045 fold_builtin_powi (tree fndecl ATTRIBUTE_UNUSED, tree arglist, tree type)
7046 {
7047   tree arg0 = TREE_VALUE (arglist);
7048   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7049
7050   if (!validate_arglist (arglist, REAL_TYPE, INTEGER_TYPE, VOID_TYPE))
7051     return NULL_TREE;
7052
7053   /* Optimize pow(1.0,y) = 1.0.  */
7054   if (real_onep (arg0))
7055     return omit_one_operand (type, build_real (type, dconst1), arg1);
7056
7057   if (host_integerp (arg1, 0))
7058     {
7059       HOST_WIDE_INT c = TREE_INT_CST_LOW (arg1);
7060
7061       /* Evaluate powi at compile-time.  */
7062       if (TREE_CODE (arg0) == REAL_CST
7063           && ! TREE_CONSTANT_OVERFLOW (arg0))
7064         {
7065           REAL_VALUE_TYPE x;
7066           x = TREE_REAL_CST (arg0);
7067           real_powi (&x, TYPE_MODE (type), &x, c);
7068           return build_real (type, x);
7069         }
7070
7071       /* Optimize pow(x,0) = 1.0.  */
7072       if (c == 0)
7073         return omit_one_operand (type, build_real (type, dconst1),
7074                                  arg0);
7075
7076       /* Optimize pow(x,1) = x.  */
7077       if (c == 1)
7078         return arg0;
7079
7080       /* Optimize pow(x,-1) = 1.0/x.  */
7081       if (c == -1)
7082         return fold (build2 (RDIV_EXPR, type,
7083                              build_real (type, dconst1), arg0));
7084     }
7085
7086   return NULL_TREE;
7087 }
7088
7089 /* A subroutine of fold_builtin to fold the various exponent
7090    functions.  EXP is the CALL_EXPR of a call to a builtin function.
7091    VALUE is the value which will be raised to a power.  */
7092
7093 static tree
7094 fold_builtin_exponent (tree fndecl, tree arglist,
7095                        const REAL_VALUE_TYPE *value)
7096 {
7097   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7098     {
7099       tree type = TREE_TYPE (TREE_TYPE (fndecl));
7100       tree arg = TREE_VALUE (arglist);
7101
7102       /* Optimize exp*(0.0) = 1.0.  */
7103       if (real_zerop (arg))
7104         return build_real (type, dconst1);
7105
7106       /* Optimize expN(1.0) = N.  */
7107       if (real_onep (arg))
7108         {
7109           REAL_VALUE_TYPE cst;
7110
7111           real_convert (&cst, TYPE_MODE (type), value);
7112           return build_real (type, cst);
7113         }
7114
7115       /* Attempt to evaluate expN(integer) at compile-time.  */
7116       if (flag_unsafe_math_optimizations
7117           && TREE_CODE (arg) == REAL_CST
7118           && ! TREE_CONSTANT_OVERFLOW (arg))
7119         {
7120           REAL_VALUE_TYPE cint;
7121           REAL_VALUE_TYPE c;
7122           HOST_WIDE_INT n;
7123
7124           c = TREE_REAL_CST (arg);
7125           n = real_to_integer (&c);
7126           real_from_integer (&cint, VOIDmode, n,
7127                              n < 0 ? -1 : 0, 0);
7128           if (real_identical (&c, &cint))
7129             {
7130               REAL_VALUE_TYPE x;
7131
7132               real_powi (&x, TYPE_MODE (type), value, n);
7133               return build_real (type, x);
7134             }
7135         }
7136
7137       /* Optimize expN(logN(x)) = x.  */
7138       if (flag_unsafe_math_optimizations)
7139         {
7140           const enum built_in_function fcode = builtin_mathfn_code (arg);
7141
7142           if ((value == &dconste
7143                && (fcode == BUILT_IN_LOG
7144                    || fcode == BUILT_IN_LOGF
7145                    || fcode == BUILT_IN_LOGL))
7146               || (value == &dconst2
7147                   && (fcode == BUILT_IN_LOG2
7148                       || fcode == BUILT_IN_LOG2F
7149                       || fcode == BUILT_IN_LOG2L))
7150               || (value == &dconst10
7151                   && (fcode == BUILT_IN_LOG10
7152                       || fcode == BUILT_IN_LOG10F
7153                       || fcode == BUILT_IN_LOG10L)))
7154             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7155         }
7156     }
7157
7158   return 0;
7159 }
7160
7161 /* Fold function call to builtin memcpy.  Return
7162    NULL_TREE if no simplification can be made.  */
7163
7164 static tree
7165 fold_builtin_memcpy (tree exp)
7166 {
7167   tree fndecl = get_callee_fndecl (exp);
7168   tree arglist = TREE_OPERAND (exp, 1);
7169   tree dest, src, len;
7170
7171   if (!validate_arglist (arglist,
7172                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7173     return 0;
7174
7175   dest = TREE_VALUE (arglist);
7176   src = TREE_VALUE (TREE_CHAIN (arglist));
7177   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7178
7179   /* If the LEN parameter is zero, return DEST.  */
7180   if (integer_zerop (len))
7181     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7182
7183   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7184   if (operand_equal_p (src, dest, 0))
7185     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, len);
7186
7187   return 0;
7188 }
7189
7190 /* Fold function call to builtin mempcpy.  Return
7191    NULL_TREE if no simplification can be made.  */
7192
7193 static tree
7194 fold_builtin_mempcpy (tree arglist, tree type, int endp)
7195 {
7196   if (validate_arglist (arglist,
7197                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7198     {
7199       tree dest = TREE_VALUE (arglist);
7200       tree src = TREE_VALUE (TREE_CHAIN (arglist));
7201       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7202
7203       /* If the LEN parameter is zero, return DEST.  */
7204       if (integer_zerop (len))
7205         return omit_one_operand (type, dest, src);
7206
7207       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7208       if (operand_equal_p (src, dest, 0))
7209         {
7210           if (endp == 0)
7211             return omit_one_operand (type, dest, len);
7212
7213           if (endp == 2)
7214             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
7215                                 ssize_int (1)));
7216       
7217           len = fold_convert (TREE_TYPE (dest), len);
7218           len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
7219           return fold_convert (type, len);
7220         }
7221     }
7222   return 0;
7223 }
7224
7225 /* Fold function call to builtin memmove.  Return
7226    NULL_TREE if no simplification can be made.  */
7227
7228 static tree
7229 fold_builtin_memmove (tree arglist, tree type)
7230 {
7231   tree dest, src, len;
7232
7233   if (!validate_arglist (arglist,
7234                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7235     return 0;
7236
7237   dest = TREE_VALUE (arglist);
7238   src = TREE_VALUE (TREE_CHAIN (arglist));
7239   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7240
7241   /* If the LEN parameter is zero, return DEST.  */
7242   if (integer_zerop (len))
7243     return omit_one_operand (type, dest, src);
7244
7245   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7246   if (operand_equal_p (src, dest, 0))
7247     return omit_one_operand (type, dest, len);
7248
7249   return 0;
7250 }
7251
7252 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7253    the length of the string to be copied.  Return NULL_TREE if no
7254    simplification can be made.  */
7255
7256 tree
7257 fold_builtin_strcpy (tree fndecl, tree arglist, tree len)
7258 {
7259   tree dest, src, fn;
7260
7261   if (!validate_arglist (arglist,
7262                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7263     return 0;
7264
7265   dest = TREE_VALUE (arglist);
7266   src = TREE_VALUE (TREE_CHAIN (arglist));
7267
7268   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7269   if (operand_equal_p (src, dest, 0))
7270     return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), dest);
7271
7272   if (optimize_size)
7273     return 0;
7274
7275   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7276   if (!fn)
7277     return 0;
7278
7279   if (!len)
7280     {
7281       len = c_strlen (src, 1);
7282       if (! len || TREE_SIDE_EFFECTS (len))
7283         return 0;
7284     }
7285
7286   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7287   arglist = build_tree_list (NULL_TREE, len);
7288   arglist = tree_cons (NULL_TREE, src, arglist);
7289   arglist = tree_cons (NULL_TREE, dest, arglist);
7290   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7291                        build_function_call_expr (fn, arglist));
7292 }
7293
7294 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7295    the length of the source string.  Return NULL_TREE if no simplification
7296    can be made.  */
7297
7298 tree
7299 fold_builtin_strncpy (tree fndecl, tree arglist, tree slen)
7300 {
7301   tree dest, src, len, fn;
7302
7303   if (!validate_arglist (arglist,
7304                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7305     return 0;
7306
7307   dest = TREE_VALUE (arglist);
7308   src = TREE_VALUE (TREE_CHAIN (arglist));
7309   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7310
7311   /* If the LEN parameter is zero, return DEST.  */
7312   if (integer_zerop (len))
7313     return omit_one_operand (TREE_TYPE (TREE_TYPE (fndecl)), dest, src);
7314
7315   /* We can't compare slen with len as constants below if len is not a
7316      constant.  */
7317   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7318     return 0;
7319
7320   if (!slen)
7321     slen = c_strlen (src, 1);
7322
7323   /* Now, we must be passed a constant src ptr parameter.  */
7324   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7325     return 0;
7326
7327   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7328
7329   /* We do not support simplification of this case, though we do
7330      support it when expanding trees into RTL.  */
7331   /* FIXME: generate a call to __builtin_memset.  */
7332   if (tree_int_cst_lt (slen, len))
7333     return 0;
7334
7335   /* OK transform into builtin memcpy.  */
7336   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7337   if (!fn)
7338     return 0;
7339   return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)),
7340                        build_function_call_expr (fn, arglist));
7341 }
7342
7343 /* Fold function call to builtin memcmp.  Return
7344    NULL_TREE if no simplification can be made.  */
7345
7346 static tree
7347 fold_builtin_memcmp (tree arglist)
7348 {
7349   tree arg1, arg2, len;
7350   const char *p1, *p2;
7351
7352   if (!validate_arglist (arglist,
7353                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7354     return 0;
7355
7356   arg1 = TREE_VALUE (arglist);
7357   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7358   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7359
7360   /* If the LEN parameter is zero, return zero.  */
7361   if (integer_zerop (len))
7362     return omit_two_operands (integer_type_node, integer_zero_node,
7363                               arg1, arg2);
7364
7365   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7366   if (operand_equal_p (arg1, arg2, 0))
7367     return omit_one_operand (integer_type_node, integer_zero_node, len);
7368
7369   p1 = c_getstr (arg1);
7370   p2 = c_getstr (arg2);
7371
7372   /* If all arguments are constant, and the value of len is not greater
7373      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7374   if (host_integerp (len, 1) && p1 && p2
7375       && compare_tree_int (len, strlen (p1) + 1) <= 0
7376       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7377     {
7378       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7379
7380       if (r > 0)
7381         return integer_one_node;
7382       else if (r < 0)
7383         return integer_minus_one_node;
7384       else
7385         return integer_zero_node;
7386     }
7387
7388   /* If len parameter is one, return an expression corresponding to
7389      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7390   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7391     {
7392       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7393       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7394       tree ind1 = fold_convert (integer_type_node,
7395                                 build1 (INDIRECT_REF, cst_uchar_node,
7396                                         fold_convert (cst_uchar_ptr_node,
7397                                                       arg1)));
7398       tree ind2 = fold_convert (integer_type_node,
7399                                 build1 (INDIRECT_REF, cst_uchar_node,
7400                                         fold_convert (cst_uchar_ptr_node,
7401                                                       arg2)));
7402       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7403     }
7404
7405   return 0;
7406 }
7407
7408 /* Fold function call to builtin strcmp.  Return
7409    NULL_TREE if no simplification can be made.  */
7410
7411 static tree
7412 fold_builtin_strcmp (tree arglist)
7413 {
7414   tree arg1, arg2;
7415   const char *p1, *p2;
7416
7417   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7418     return 0;
7419
7420   arg1 = TREE_VALUE (arglist);
7421   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7422
7423   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7424   if (operand_equal_p (arg1, arg2, 0))
7425     return integer_zero_node;
7426
7427   p1 = c_getstr (arg1);
7428   p2 = c_getstr (arg2);
7429
7430   if (p1 && p2)
7431     {
7432       const int i = strcmp (p1, p2);
7433       if (i < 0)
7434         return integer_minus_one_node;
7435       else if (i > 0)
7436         return integer_one_node;
7437       else
7438         return integer_zero_node;
7439     }
7440
7441   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7442   if (p2 && *p2 == '\0')
7443     {
7444       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7445       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7446       return fold_convert (integer_type_node,
7447                            build1 (INDIRECT_REF, cst_uchar_node,
7448                                    fold_convert (cst_uchar_ptr_node,
7449                                                  arg1)));
7450     }
7451
7452   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7453   if (p1 && *p1 == '\0')
7454     {
7455       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7456       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7457       tree temp = fold_convert (integer_type_node,
7458                                 build1 (INDIRECT_REF, cst_uchar_node,
7459                                         fold_convert (cst_uchar_ptr_node,
7460                                                       arg2)));
7461       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7462     }
7463
7464   return 0;
7465 }
7466
7467 /* Fold function call to builtin strncmp.  Return
7468    NULL_TREE if no simplification can be made.  */
7469
7470 static tree
7471 fold_builtin_strncmp (tree arglist)
7472 {
7473   tree arg1, arg2, len;
7474   const char *p1, *p2;
7475
7476   if (!validate_arglist (arglist,
7477                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7478     return 0;
7479
7480   arg1 = TREE_VALUE (arglist);
7481   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7482   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7483
7484   /* If the LEN parameter is zero, return zero.  */
7485   if (integer_zerop (len))
7486     return omit_two_operands (integer_type_node, integer_zero_node,
7487                               arg1, arg2);
7488
7489   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7490   if (operand_equal_p (arg1, arg2, 0))
7491     return omit_one_operand (integer_type_node, integer_zero_node, len);
7492
7493   p1 = c_getstr (arg1);
7494   p2 = c_getstr (arg2);
7495
7496   if (host_integerp (len, 1) && p1 && p2)
7497     {
7498       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7499       if (i > 0)
7500         return integer_one_node;
7501       else if (i < 0)
7502         return integer_minus_one_node;
7503       else
7504         return integer_zero_node;
7505     }
7506
7507   /* If the second arg is "", and the length is greater than zero,
7508      return *(const unsigned char*)arg1.  */
7509   if (p2 && *p2 == '\0'
7510       && TREE_CODE (len) == INTEGER_CST
7511       && tree_int_cst_sgn (len) == 1)
7512     {
7513       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7514       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7515       return fold_convert (integer_type_node,
7516                            build1 (INDIRECT_REF, cst_uchar_node,
7517                                    fold_convert (cst_uchar_ptr_node,
7518                                                  arg1)));
7519     }
7520
7521   /* If the first arg is "", and the length is greater than zero,
7522      return -*(const unsigned char*)arg2.  */
7523   if (p1 && *p1 == '\0'
7524       && TREE_CODE (len) == INTEGER_CST
7525       && tree_int_cst_sgn (len) == 1)
7526     {
7527       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7528       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7529       tree temp = fold_convert (integer_type_node,
7530                                 build1 (INDIRECT_REF, cst_uchar_node,
7531                                         fold_convert (cst_uchar_ptr_node,
7532                                                       arg2)));
7533       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7534     }
7535
7536   /* If len parameter is one, return an expression corresponding to
7537      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7538   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7539     {
7540       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7541       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7542       tree ind1 = fold_convert (integer_type_node,
7543                                 build1 (INDIRECT_REF, cst_uchar_node,
7544                                         fold_convert (cst_uchar_ptr_node,
7545                                                       arg1)));
7546       tree ind2 = fold_convert (integer_type_node,
7547                                 build1 (INDIRECT_REF, cst_uchar_node,
7548                                         fold_convert (cst_uchar_ptr_node,
7549                                                       arg2)));
7550       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7551     }
7552
7553   return 0;
7554 }
7555
7556 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7557    NULL_TREE if no simplification can be made.  */
7558
7559 static tree
7560 fold_builtin_signbit (tree fndecl, tree arglist)
7561 {
7562   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7563   tree arg, temp;
7564
7565   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7566     return NULL_TREE;
7567
7568   arg = TREE_VALUE (arglist);
7569
7570   /* If ARG is a compile-time constant, determine the result.  */
7571   if (TREE_CODE (arg) == REAL_CST
7572       && !TREE_CONSTANT_OVERFLOW (arg))
7573     {
7574       REAL_VALUE_TYPE c;
7575
7576       c = TREE_REAL_CST (arg);
7577       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7578       return fold_convert (type, temp);
7579     }
7580
7581   /* If ARG is non-negative, the result is always zero.  */
7582   if (tree_expr_nonnegative_p (arg))
7583     return omit_one_operand (type, integer_zero_node, arg);
7584
7585   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7586   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7587     return fold (build2 (LT_EXPR, type, arg,
7588                          build_real (TREE_TYPE (arg), dconst0)));
7589
7590   return NULL_TREE;
7591 }
7592
7593 /* Fold function call to builtin copysign, copysignf or copysignl.
7594    Return NULL_TREE if no simplification can be made.  */
7595
7596 static tree
7597 fold_builtin_copysign (tree fndecl, tree arglist, tree type)
7598 {
7599   tree arg1, arg2, tem;
7600
7601   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7602     return NULL_TREE;
7603
7604   arg1 = TREE_VALUE (arglist);
7605   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7606
7607   /* copysign(X,X) is X.  */
7608   if (operand_equal_p (arg1, arg2, 0))
7609     return fold_convert (type, arg1);
7610
7611   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7612   if (TREE_CODE (arg1) == REAL_CST
7613       && TREE_CODE (arg2) == REAL_CST
7614       && !TREE_CONSTANT_OVERFLOW (arg1)
7615       && !TREE_CONSTANT_OVERFLOW (arg2))
7616     {
7617       REAL_VALUE_TYPE c1, c2;
7618
7619       c1 = TREE_REAL_CST (arg1);
7620       c2 = TREE_REAL_CST (arg2);
7621       real_copysign (&c1, &c2);
7622       return build_real (type, c1);
7623       c1.sign = c2.sign;
7624     }
7625
7626   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7627      Remember to evaluate Y for side-effects.  */
7628   if (tree_expr_nonnegative_p (arg2))
7629     return omit_one_operand (type,
7630                              fold (build1 (ABS_EXPR, type, arg1)),
7631                              arg2);
7632
7633   /* Strip sign changing operations for the first argument.  */
7634   tem = fold_strip_sign_ops (arg1);
7635   if (tem)
7636     {
7637       arglist = tree_cons (NULL_TREE, tem, TREE_CHAIN (arglist));
7638       return build_function_call_expr (fndecl, arglist);
7639     }
7640
7641   return NULL_TREE;
7642 }
7643
7644 /* Fold a call to builtin isascii.  */
7645
7646 static tree
7647 fold_builtin_isascii (tree arglist)
7648 {
7649   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7650     return 0;
7651   else
7652     {
7653       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7654       tree arg = TREE_VALUE (arglist);
7655
7656       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7657                     build_int_cst (NULL_TREE,
7658                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
7659       arg = fold (build2 (EQ_EXPR, integer_type_node,
7660                           arg, integer_zero_node));
7661
7662       if (in_gimple_form && !TREE_CONSTANT (arg))
7663         return NULL_TREE;
7664       else
7665         return arg;
7666     }
7667 }
7668
7669 /* Fold a call to builtin toascii.  */
7670
7671 static tree
7672 fold_builtin_toascii (tree arglist)
7673 {
7674   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7675     return 0;
7676   else
7677     {
7678       /* Transform toascii(c) -> (c & 0x7f).  */
7679       tree arg = TREE_VALUE (arglist);
7680
7681       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7682                            build_int_cst (NULL_TREE, 0x7f)));
7683     }
7684 }
7685
7686 /* Fold a call to builtin isdigit.  */
7687
7688 static tree
7689 fold_builtin_isdigit (tree arglist)
7690 {
7691   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7692     return 0;
7693   else
7694     {
7695       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7696       /* According to the C standard, isdigit is unaffected by locale.
7697          However, it definitely is affected by the target character set.  */
7698       tree arg;
7699       unsigned HOST_WIDE_INT target_digit0
7700         = lang_hooks.to_target_charset ('0');
7701
7702       if (target_digit0 == 0)
7703         return NULL_TREE;
7704
7705       arg = fold_convert (unsigned_type_node, TREE_VALUE (arglist));
7706       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7707                     build_int_cst (unsigned_type_node, target_digit0));
7708       arg = build2 (LE_EXPR, integer_type_node, arg,
7709                     build_int_cst (unsigned_type_node, 9));
7710       arg = fold (arg);
7711       if (in_gimple_form && !TREE_CONSTANT (arg))
7712         return NULL_TREE;
7713       else
7714         return arg;
7715     }
7716 }
7717
7718 /* Fold a call to fabs, fabsf or fabsl.  */
7719
7720 static tree
7721 fold_builtin_fabs (tree arglist, tree type)
7722 {
7723   tree arg;
7724
7725   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7726     return 0;
7727
7728   arg = TREE_VALUE (arglist);
7729   arg = fold_convert (type, arg);
7730   if (TREE_CODE (arg) == REAL_CST)
7731     return fold_abs_const (arg, type);
7732   return fold (build1 (ABS_EXPR, type, arg));
7733 }
7734
7735 /* Fold a call to abs, labs, llabs or imaxabs.  */
7736
7737 static tree
7738 fold_builtin_abs (tree arglist, tree type)
7739 {
7740   tree arg;
7741
7742   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7743     return 0;
7744
7745   arg = TREE_VALUE (arglist);
7746   arg = fold_convert (type, arg);
7747   if (TREE_CODE (arg) == INTEGER_CST)
7748     return fold_abs_const (arg, type);
7749   return fold (build1 (ABS_EXPR, type, arg));
7750 }
7751
7752 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7753    EXP is the CALL_EXPR for the call.  */
7754
7755 static tree
7756 fold_builtin_classify (tree fndecl, tree arglist, int builtin_index)
7757 {
7758   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7759   tree arg;
7760   REAL_VALUE_TYPE r;
7761
7762   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7763     {
7764       /* Check that we have exactly one argument.  */
7765       if (arglist == 0)
7766         {
7767           error ("too few arguments to function %qs",
7768                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7769           return error_mark_node;
7770         }
7771       else if (TREE_CHAIN (arglist) != 0)
7772         {
7773           error ("too many arguments to function %qs",
7774                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7775           return error_mark_node;
7776         }
7777       else
7778         {
7779           error ("non-floating-point argument to function %qs",
7780                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7781           return error_mark_node;
7782         }
7783     }
7784
7785   arg = TREE_VALUE (arglist);
7786   switch (builtin_index)
7787     {
7788     case BUILT_IN_ISINF:
7789       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7790         return omit_one_operand (type, integer_zero_node, arg);
7791
7792       if (TREE_CODE (arg) == REAL_CST)
7793         {
7794           r = TREE_REAL_CST (arg);
7795           if (real_isinf (&r))
7796             return real_compare (GT_EXPR, &r, &dconst0)
7797                    ? integer_one_node : integer_minus_one_node;
7798           else
7799             return integer_zero_node;
7800         }
7801
7802       return NULL_TREE;
7803
7804     case BUILT_IN_FINITE:
7805       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7806           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7807         return omit_one_operand (type, integer_zero_node, arg);
7808
7809       if (TREE_CODE (arg) == REAL_CST)
7810         {
7811           r = TREE_REAL_CST (arg);
7812           return real_isinf (&r) || real_isnan (&r)
7813                  ? integer_zero_node : integer_one_node;
7814         }
7815
7816       return NULL_TREE;
7817
7818     case BUILT_IN_ISNAN:
7819       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7820         return omit_one_operand (type, integer_zero_node, arg);
7821
7822       if (TREE_CODE (arg) == REAL_CST)
7823         {
7824           r = TREE_REAL_CST (arg);
7825           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7826         }
7827
7828       arg = builtin_save_expr (arg);
7829       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7830
7831     default:
7832       gcc_unreachable ();
7833     }
7834 }
7835
7836 /* Fold a call to an unordered comparison function such as
7837    __builtin_isgreater().  FNDECL is the FUNCTION_DECL for the function
7838    being called and ARGLIST is the argument list for the call.
7839    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7840    the opposite of the desired result.  UNORDERED_CODE is used
7841    for modes that can hold NaNs and ORDERED_CODE is used for
7842    the rest.  */
7843
7844 static tree
7845 fold_builtin_unordered_cmp (tree fndecl, tree arglist,
7846                             enum tree_code unordered_code,
7847                             enum tree_code ordered_code)
7848 {
7849   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7850   enum tree_code code;
7851   tree arg0, arg1;
7852   tree type0, type1;
7853   enum tree_code code0, code1;
7854   tree cmp_type = NULL_TREE;
7855
7856   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7857     {
7858       /* Check that we have exactly two arguments.  */
7859       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7860         {
7861           error ("too few arguments to function %qs",
7862                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7863           return error_mark_node;
7864         }
7865       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7866         {
7867           error ("too many arguments to function %qs",
7868                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7869           return error_mark_node;
7870         }
7871     }
7872
7873   arg0 = TREE_VALUE (arglist);
7874   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7875   
7876   type0 = TREE_TYPE (arg0);
7877   type1 = TREE_TYPE (arg1);
7878   
7879   code0 = TREE_CODE (type0);
7880   code1 = TREE_CODE (type1);
7881   
7882   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7883     /* Choose the wider of two real types.  */
7884     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7885       ? type0 : type1;
7886   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7887     cmp_type = type0;
7888   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7889     cmp_type = type1;
7890   else
7891     {
7892       error ("non-floating-point argument to function %qs",
7893                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7894       return error_mark_node;
7895     }
7896   
7897   arg0 = fold_convert (cmp_type, arg0);
7898   arg1 = fold_convert (cmp_type, arg1);
7899
7900   if (unordered_code == UNORDERED_EXPR)
7901     {
7902       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7903         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7904       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7905     }
7906
7907   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7908                                                       : ordered_code;
7909   return fold (build1 (TRUTH_NOT_EXPR, type,
7910                        fold (build2 (code, type, arg0, arg1))));
7911 }
7912
7913 /* Fold a call to one of the external complex multiply libcalls.  */
7914
7915 static tree
7916 fold_builtin_complex_mul (tree type, tree arglist)
7917 {
7918   tree ar, ai, br, bi;
7919
7920   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
7921                          REAL_TYPE, VOID_TYPE))
7922     return NULL;
7923
7924   ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7925   ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7926   br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7927   bi = TREE_VALUE (arglist);
7928
7929   return fold_complex_mult_parts (type, ar, ai, br, bi);
7930 }
7931
7932 /* Fold a call to one of the external complex division libcalls.  */
7933
7934 static tree
7935 fold_builtin_complex_div (tree type, tree arglist)
7936 {
7937   tree ar, ai, br, bi;
7938
7939   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, REAL_TYPE,
7940                          REAL_TYPE, VOID_TYPE))
7941     return NULL;
7942
7943   ar = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7944   ai = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7945   br = TREE_VALUE (arglist); arglist = TREE_CHAIN (arglist);
7946   bi = TREE_VALUE (arglist);
7947
7948   return fold_complex_div_parts (type, ar, ai, br, bi, RDIV_EXPR);
7949 }
7950
7951 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7952    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7953    result of the function call is ignored.  This function returns NULL_TREE
7954    if no simplification was possible.  */
7955
7956 static tree
7957 fold_builtin_1 (tree exp, bool ignore)
7958 {
7959   tree fndecl = get_callee_fndecl (exp);
7960   tree arglist = TREE_OPERAND (exp, 1);
7961   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7962   enum built_in_function fcode;
7963
7964   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7965     return targetm.fold_builtin (exp, ignore);
7966
7967   fcode = DECL_FUNCTION_CODE (fndecl);
7968   switch (fcode)
7969     {
7970     case BUILT_IN_FPUTS:
7971       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7972
7973     case BUILT_IN_FPUTS_UNLOCKED:
7974       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7975
7976     case BUILT_IN_STRSTR:
7977       return fold_builtin_strstr (arglist, type);
7978
7979     case BUILT_IN_STRCAT:
7980       return fold_builtin_strcat (arglist);
7981
7982     case BUILT_IN_STRNCAT:
7983       return fold_builtin_strncat (arglist);
7984
7985     case BUILT_IN_STRSPN:
7986       return fold_builtin_strspn (arglist);
7987
7988     case BUILT_IN_STRCSPN:
7989       return fold_builtin_strcspn (arglist);
7990
7991     case BUILT_IN_STRCHR:
7992     case BUILT_IN_INDEX:
7993       return fold_builtin_strchr (arglist, type);
7994
7995     case BUILT_IN_STRRCHR:
7996     case BUILT_IN_RINDEX:
7997       return fold_builtin_strrchr (arglist, type);
7998
7999     case BUILT_IN_STRCPY:
8000       return fold_builtin_strcpy (fndecl, arglist, NULL_TREE);
8001
8002     case BUILT_IN_STRNCPY:
8003       return fold_builtin_strncpy (fndecl, arglist, NULL_TREE);
8004
8005     case BUILT_IN_STRCMP:
8006       return fold_builtin_strcmp (arglist);
8007
8008     case BUILT_IN_STRNCMP:
8009       return fold_builtin_strncmp (arglist);
8010
8011     case BUILT_IN_STRPBRK:
8012       return fold_builtin_strpbrk (arglist, type);
8013
8014     case BUILT_IN_BCMP:
8015     case BUILT_IN_MEMCMP:
8016       return fold_builtin_memcmp (arglist);
8017
8018     case BUILT_IN_SPRINTF:
8019       return fold_builtin_sprintf (arglist, ignore);
8020
8021     case BUILT_IN_CONSTANT_P:
8022       {
8023         tree val;
8024
8025         val = fold_builtin_constant_p (arglist);
8026         /* Gimplification will pull the CALL_EXPR for the builtin out of
8027            an if condition.  When not optimizing, we'll not CSE it back.
8028            To avoid link error types of regressions, return false now.  */
8029         if (!val && !optimize)
8030           val = integer_zero_node;
8031
8032         return val;
8033       }
8034
8035     case BUILT_IN_EXPECT:
8036       return fold_builtin_expect (arglist);
8037
8038     case BUILT_IN_CLASSIFY_TYPE:
8039       return fold_builtin_classify_type (arglist);
8040
8041     case BUILT_IN_STRLEN:
8042       return fold_builtin_strlen (arglist);
8043
8044     case BUILT_IN_FABS:
8045     case BUILT_IN_FABSF:
8046     case BUILT_IN_FABSL:
8047       return fold_builtin_fabs (arglist, type);
8048
8049     case BUILT_IN_ABS:
8050     case BUILT_IN_LABS:
8051     case BUILT_IN_LLABS:
8052     case BUILT_IN_IMAXABS:
8053       return fold_builtin_abs (arglist, type);
8054
8055     case BUILT_IN_CONJ:
8056     case BUILT_IN_CONJF:
8057     case BUILT_IN_CONJL:
8058       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8059         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
8060       break;
8061
8062     case BUILT_IN_CREAL:
8063     case BUILT_IN_CREALF:
8064     case BUILT_IN_CREALL:
8065       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8066         return non_lvalue (fold (build1 (REALPART_EXPR, type,
8067                                          TREE_VALUE (arglist))));
8068       break;
8069
8070     case BUILT_IN_CIMAG:
8071     case BUILT_IN_CIMAGF:
8072     case BUILT_IN_CIMAGL:
8073       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
8074         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
8075                                          TREE_VALUE (arglist))));
8076       break;
8077
8078     case BUILT_IN_CABS:
8079     case BUILT_IN_CABSF:
8080     case BUILT_IN_CABSL:
8081       return fold_builtin_cabs (arglist, type);
8082
8083     case BUILT_IN_SQRT:
8084     case BUILT_IN_SQRTF:
8085     case BUILT_IN_SQRTL:
8086       return fold_builtin_sqrt (arglist, type);
8087
8088     case BUILT_IN_CBRT:
8089     case BUILT_IN_CBRTF:
8090     case BUILT_IN_CBRTL:
8091       return fold_builtin_cbrt (arglist, type);
8092
8093     case BUILT_IN_SIN:
8094     case BUILT_IN_SINF:
8095     case BUILT_IN_SINL:
8096       return fold_builtin_sin (arglist);
8097
8098     case BUILT_IN_COS:
8099     case BUILT_IN_COSF:
8100     case BUILT_IN_COSL:
8101       return fold_builtin_cos (arglist, type, fndecl);
8102
8103     case BUILT_IN_EXP:
8104     case BUILT_IN_EXPF:
8105     case BUILT_IN_EXPL:
8106       return fold_builtin_exponent (fndecl, arglist, &dconste);
8107
8108     case BUILT_IN_EXP2:
8109     case BUILT_IN_EXP2F:
8110     case BUILT_IN_EXP2L:
8111       return fold_builtin_exponent (fndecl, arglist, &dconst2);
8112
8113     case BUILT_IN_EXP10:
8114     case BUILT_IN_EXP10F:
8115     case BUILT_IN_EXP10L:
8116     case BUILT_IN_POW10:
8117     case BUILT_IN_POW10F:
8118     case BUILT_IN_POW10L:
8119       return fold_builtin_exponent (fndecl, arglist, &dconst10);
8120
8121     case BUILT_IN_LOG:
8122     case BUILT_IN_LOGF:
8123     case BUILT_IN_LOGL:
8124       return fold_builtin_logarithm (fndecl, arglist, &dconste);
8125
8126     case BUILT_IN_LOG2:
8127     case BUILT_IN_LOG2F:
8128     case BUILT_IN_LOG2L:
8129       return fold_builtin_logarithm (fndecl, arglist, &dconst2);
8130
8131     case BUILT_IN_LOG10:
8132     case BUILT_IN_LOG10F:
8133     case BUILT_IN_LOG10L:
8134       return fold_builtin_logarithm (fndecl, arglist, &dconst10);
8135
8136     case BUILT_IN_TAN:
8137     case BUILT_IN_TANF:
8138     case BUILT_IN_TANL:
8139       return fold_builtin_tan (arglist);
8140
8141     case BUILT_IN_ATAN:
8142     case BUILT_IN_ATANF:
8143     case BUILT_IN_ATANL:
8144       return fold_builtin_atan (arglist, type);
8145
8146     case BUILT_IN_POW:
8147     case BUILT_IN_POWF:
8148     case BUILT_IN_POWL:
8149       return fold_builtin_pow (fndecl, arglist, type);
8150
8151     case BUILT_IN_POWI:
8152     case BUILT_IN_POWIF:
8153     case BUILT_IN_POWIL:
8154       return fold_builtin_powi (fndecl, arglist, type);
8155
8156     case BUILT_IN_INF:
8157     case BUILT_IN_INFF:
8158     case BUILT_IN_INFL:
8159       return fold_builtin_inf (type, true);
8160
8161     case BUILT_IN_HUGE_VAL:
8162     case BUILT_IN_HUGE_VALF:
8163     case BUILT_IN_HUGE_VALL:
8164       return fold_builtin_inf (type, false);
8165
8166     case BUILT_IN_NAN:
8167     case BUILT_IN_NANF:
8168     case BUILT_IN_NANL:
8169       return fold_builtin_nan (arglist, type, true);
8170
8171     case BUILT_IN_NANS:
8172     case BUILT_IN_NANSF:
8173     case BUILT_IN_NANSL:
8174       return fold_builtin_nan (arglist, type, false);
8175
8176     case BUILT_IN_FLOOR:
8177     case BUILT_IN_FLOORF:
8178     case BUILT_IN_FLOORL:
8179       return fold_builtin_floor (exp);
8180
8181     case BUILT_IN_CEIL:
8182     case BUILT_IN_CEILF:
8183     case BUILT_IN_CEILL:
8184       return fold_builtin_ceil (exp);
8185
8186     case BUILT_IN_TRUNC:
8187     case BUILT_IN_TRUNCF:
8188     case BUILT_IN_TRUNCL:
8189       return fold_builtin_trunc (exp);
8190
8191     case BUILT_IN_ROUND:
8192     case BUILT_IN_ROUNDF:
8193     case BUILT_IN_ROUNDL:
8194       return fold_builtin_round (exp);
8195
8196     case BUILT_IN_NEARBYINT:
8197     case BUILT_IN_NEARBYINTF:
8198     case BUILT_IN_NEARBYINTL:
8199     case BUILT_IN_RINT:
8200     case BUILT_IN_RINTF:
8201     case BUILT_IN_RINTL:
8202       return fold_trunc_transparent_mathfn (exp);
8203
8204     case BUILT_IN_LROUND:
8205     case BUILT_IN_LROUNDF:
8206     case BUILT_IN_LROUNDL:
8207     case BUILT_IN_LLROUND:
8208     case BUILT_IN_LLROUNDF:
8209     case BUILT_IN_LLROUNDL:
8210       return fold_builtin_lround (exp);
8211
8212     case BUILT_IN_LRINT:
8213     case BUILT_IN_LRINTF:
8214     case BUILT_IN_LRINTL:
8215     case BUILT_IN_LLRINT:
8216     case BUILT_IN_LLRINTF:
8217     case BUILT_IN_LLRINTL:
8218       return fold_fixed_mathfn (exp);
8219
8220     case BUILT_IN_FFS:
8221     case BUILT_IN_FFSL:
8222     case BUILT_IN_FFSLL:
8223     case BUILT_IN_CLZ:
8224     case BUILT_IN_CLZL:
8225     case BUILT_IN_CLZLL:
8226     case BUILT_IN_CTZ:
8227     case BUILT_IN_CTZL:
8228     case BUILT_IN_CTZLL:
8229     case BUILT_IN_POPCOUNT:
8230     case BUILT_IN_POPCOUNTL:
8231     case BUILT_IN_POPCOUNTLL:
8232     case BUILT_IN_PARITY:
8233     case BUILT_IN_PARITYL:
8234     case BUILT_IN_PARITYLL:
8235       return fold_builtin_bitop (fndecl, arglist);
8236
8237     case BUILT_IN_MEMCPY:
8238       return fold_builtin_memcpy (exp);
8239
8240     case BUILT_IN_MEMPCPY:
8241       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
8242
8243     case BUILT_IN_MEMMOVE:
8244       return fold_builtin_memmove (arglist, type);
8245
8246     case BUILT_IN_SIGNBIT:
8247     case BUILT_IN_SIGNBITF:
8248     case BUILT_IN_SIGNBITL:
8249       return fold_builtin_signbit (fndecl, arglist);
8250
8251     case BUILT_IN_ISASCII:
8252       return fold_builtin_isascii (arglist);
8253
8254     case BUILT_IN_TOASCII:
8255       return fold_builtin_toascii (arglist);
8256
8257     case BUILT_IN_ISDIGIT:
8258       return fold_builtin_isdigit (arglist);
8259
8260     case BUILT_IN_COPYSIGN:
8261     case BUILT_IN_COPYSIGNF:
8262     case BUILT_IN_COPYSIGNL:
8263       return fold_builtin_copysign (fndecl, arglist, type);
8264
8265     case BUILT_IN_FINITE:
8266     case BUILT_IN_FINITEF:
8267     case BUILT_IN_FINITEL:
8268       return fold_builtin_classify (fndecl, arglist, BUILT_IN_FINITE);
8269
8270     case BUILT_IN_ISINF:
8271     case BUILT_IN_ISINFF:
8272     case BUILT_IN_ISINFL:
8273       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISINF);
8274
8275     case BUILT_IN_ISNAN:
8276     case BUILT_IN_ISNANF:
8277     case BUILT_IN_ISNANL:
8278       return fold_builtin_classify (fndecl, arglist, BUILT_IN_ISNAN);
8279
8280     case BUILT_IN_ISGREATER:
8281       return fold_builtin_unordered_cmp (fndecl, arglist, UNLE_EXPR, LE_EXPR);
8282     case BUILT_IN_ISGREATEREQUAL:
8283       return fold_builtin_unordered_cmp (fndecl, arglist, UNLT_EXPR, LT_EXPR);
8284     case BUILT_IN_ISLESS:
8285       return fold_builtin_unordered_cmp (fndecl, arglist, UNGE_EXPR, GE_EXPR);
8286     case BUILT_IN_ISLESSEQUAL:
8287       return fold_builtin_unordered_cmp (fndecl, arglist, UNGT_EXPR, GT_EXPR);
8288     case BUILT_IN_ISLESSGREATER:
8289       return fold_builtin_unordered_cmp (fndecl, arglist, UNEQ_EXPR, EQ_EXPR);
8290     case BUILT_IN_ISUNORDERED:
8291       return fold_builtin_unordered_cmp (fndecl, arglist, UNORDERED_EXPR,
8292                                          NOP_EXPR);
8293
8294       /* We do the folding for va_start in the expander.  */
8295     case BUILT_IN_VA_START:
8296       break;
8297
8298     default:
8299       if (fcode >= BUILT_IN_COMPLEX_MUL_MIN
8300           && fcode <= BUILT_IN_COMPLEX_MUL_MAX)
8301         return fold_builtin_complex_mul (type, arglist);
8302       if (fcode >= BUILT_IN_COMPLEX_DIV_MIN
8303           && fcode <= BUILT_IN_COMPLEX_DIV_MAX)
8304         return fold_builtin_complex_div (type, arglist);
8305       break;
8306     }
8307
8308   return 0;
8309 }
8310
8311 /* A wrapper function for builtin folding that prevents warnings for
8312    "statement without effect" and the like, caused by removing the
8313    call node earlier than the warning is generated.  */
8314
8315 tree
8316 fold_builtin (tree exp, bool ignore)
8317 {
8318   exp = fold_builtin_1 (exp, ignore);
8319   if (exp)
8320     {
8321       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8322       if (CONSTANT_CLASS_P (exp))
8323         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8324       TREE_NO_WARNING (exp) = 1;
8325     }
8326
8327   return exp;
8328 }
8329
8330 /* Conveniently construct a function call expression.  */
8331
8332 tree
8333 build_function_call_expr (tree fn, tree arglist)
8334 {
8335   tree call_expr;
8336
8337   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8338   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8339                       call_expr, arglist, NULL_TREE);
8340   return fold (call_expr);
8341 }
8342
8343 /* This function validates the types of a function call argument list
8344    represented as a tree chain of parameters against a specified list
8345    of tree_codes.  If the last specifier is a 0, that represents an
8346    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8347
8348 static int
8349 validate_arglist (tree arglist, ...)
8350 {
8351   enum tree_code code;
8352   int res = 0;
8353   va_list ap;
8354
8355   va_start (ap, arglist);
8356
8357   do
8358     {
8359       code = va_arg (ap, enum tree_code);
8360       switch (code)
8361         {
8362         case 0:
8363           /* This signifies an ellipses, any further arguments are all ok.  */
8364           res = 1;
8365           goto end;
8366         case VOID_TYPE:
8367           /* This signifies an endlink, if no arguments remain, return
8368              true, otherwise return false.  */
8369           res = arglist == 0;
8370           goto end;
8371         default:
8372           /* If no parameters remain or the parameter's code does not
8373              match the specified code, return false.  Otherwise continue
8374              checking any remaining arguments.  */
8375           if (arglist == 0)
8376             goto end;
8377           if (code == POINTER_TYPE)
8378             {
8379               if (! POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arglist))))
8380                 goto end;
8381             }
8382           else if (code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8383             goto end;
8384           break;
8385         }
8386       arglist = TREE_CHAIN (arglist);
8387     }
8388   while (1);
8389
8390   /* We need gotos here since we can only have one VA_CLOSE in a
8391      function.  */
8392  end: ;
8393   va_end (ap);
8394
8395   return res;
8396 }
8397
8398 /* Default target-specific builtin expander that does nothing.  */
8399
8400 rtx
8401 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8402                         rtx target ATTRIBUTE_UNUSED,
8403                         rtx subtarget ATTRIBUTE_UNUSED,
8404                         enum machine_mode mode ATTRIBUTE_UNUSED,
8405                         int ignore ATTRIBUTE_UNUSED)
8406 {
8407   return NULL_RTX;
8408 }
8409
8410 /* Returns true is EXP represents data that would potentially reside
8411    in a readonly section.  */
8412
8413 static bool
8414 readonly_data_expr (tree exp)
8415 {
8416   STRIP_NOPS (exp);
8417
8418   if (TREE_CODE (exp) != ADDR_EXPR)
8419     return false;
8420
8421   exp = get_base_address (TREE_OPERAND (exp, 0));
8422   if (!exp)
8423     return false;
8424
8425   /* Make sure we call decl_readonly_section only for trees it
8426      can handle (since it returns true for everything it doesn't
8427      understand).  */
8428   if (TREE_CODE (exp) == STRING_CST
8429       || TREE_CODE (exp) == CONSTRUCTOR
8430       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8431     return decl_readonly_section (exp, 0);
8432   else
8433     return false;
8434 }
8435
8436 /* Simplify a call to the strstr builtin.
8437
8438    Return 0 if no simplification was possible, otherwise return the
8439    simplified form of the call as a tree.
8440
8441    The simplified form may be a constant or other expression which
8442    computes the same value, but in a more efficient manner (including
8443    calls to other builtin functions).
8444
8445    The call may contain arguments which need to be evaluated, but
8446    which are not useful to determine the result of the call.  In
8447    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8448    COMPOUND_EXPR will be an argument which must be evaluated.
8449    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8450    COMPOUND_EXPR in the chain will contain the tree for the simplified
8451    form of the builtin function call.  */
8452
8453 static tree
8454 fold_builtin_strstr (tree arglist, tree type)
8455 {
8456   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8457     return 0;
8458   else
8459     {
8460       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8461       tree fn;
8462       const char *p1, *p2;
8463
8464       p2 = c_getstr (s2);
8465       if (p2 == NULL)
8466         return 0;
8467
8468       p1 = c_getstr (s1);
8469       if (p1 != NULL)
8470         {
8471           const char *r = strstr (p1, p2);
8472           tree tem;
8473
8474           if (r == NULL)
8475             return build_int_cst (TREE_TYPE (s1), 0);
8476
8477           /* Return an offset into the constant string argument.  */
8478           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8479                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8480           return fold_convert (type, tem);
8481         }
8482
8483       if (p2[0] == '\0')
8484         return s1;
8485
8486       if (p2[1] != '\0')
8487         return 0;
8488
8489       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8490       if (!fn)
8491         return 0;
8492
8493       /* New argument list transforming strstr(s1, s2) to
8494          strchr(s1, s2[0]).  */
8495       arglist = build_tree_list (NULL_TREE,
8496                                  build_int_cst (NULL_TREE, p2[0]));
8497       arglist = tree_cons (NULL_TREE, s1, arglist);
8498       return build_function_call_expr (fn, arglist);
8499     }
8500 }
8501
8502 /* Simplify a call to the strchr builtin.
8503
8504    Return 0 if no simplification was possible, otherwise return the
8505    simplified form of the call as a tree.
8506
8507    The simplified form may be a constant or other expression which
8508    computes the same value, but in a more efficient manner (including
8509    calls to other builtin functions).
8510
8511    The call may contain arguments which need to be evaluated, but
8512    which are not useful to determine the result of the call.  In
8513    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8514    COMPOUND_EXPR will be an argument which must be evaluated.
8515    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8516    COMPOUND_EXPR in the chain will contain the tree for the simplified
8517    form of the builtin function call.  */
8518
8519 static tree
8520 fold_builtin_strchr (tree arglist, tree type)
8521 {
8522   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8523     return 0;
8524   else
8525     {
8526       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8527       const char *p1;
8528
8529       if (TREE_CODE (s2) != INTEGER_CST)
8530         return 0;
8531
8532       p1 = c_getstr (s1);
8533       if (p1 != NULL)
8534         {
8535           char c;
8536           const char *r;
8537           tree tem;
8538
8539           if (target_char_cast (s2, &c))
8540             return 0;
8541
8542           r = strchr (p1, c);
8543
8544           if (r == NULL)
8545             return build_int_cst (TREE_TYPE (s1), 0);
8546
8547           /* Return an offset into the constant string argument.  */
8548           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8549                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8550           return fold_convert (type, tem);
8551         }
8552       return 0;
8553     }
8554 }
8555
8556 /* Simplify a call to the strrchr builtin.
8557
8558    Return 0 if no simplification was possible, otherwise return the
8559    simplified form of the call as a tree.
8560
8561    The simplified form may be a constant or other expression which
8562    computes the same value, but in a more efficient manner (including
8563    calls to other builtin functions).
8564
8565    The call may contain arguments which need to be evaluated, but
8566    which are not useful to determine the result of the call.  In
8567    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8568    COMPOUND_EXPR will be an argument which must be evaluated.
8569    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8570    COMPOUND_EXPR in the chain will contain the tree for the simplified
8571    form of the builtin function call.  */
8572
8573 static tree
8574 fold_builtin_strrchr (tree arglist, tree type)
8575 {
8576   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8577     return 0;
8578   else
8579     {
8580       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8581       tree fn;
8582       const char *p1;
8583
8584       if (TREE_CODE (s2) != INTEGER_CST)
8585         return 0;
8586
8587       p1 = c_getstr (s1);
8588       if (p1 != NULL)
8589         {
8590           char c;
8591           const char *r;
8592           tree tem;
8593
8594           if (target_char_cast (s2, &c))
8595             return 0;
8596
8597           r = strrchr (p1, c);
8598
8599           if (r == NULL)
8600             return build_int_cst (TREE_TYPE (s1), 0);
8601
8602           /* Return an offset into the constant string argument.  */
8603           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8604                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8605           return fold_convert (type, tem);
8606         }
8607
8608       if (! integer_zerop (s2))
8609         return 0;
8610
8611       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8612       if (!fn)
8613         return 0;
8614
8615       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8616       return build_function_call_expr (fn, arglist);
8617     }
8618 }
8619
8620 /* Simplify a call to the strpbrk builtin.
8621
8622    Return 0 if no simplification was possible, otherwise return the
8623    simplified form of the call as a tree.
8624
8625    The simplified form may be a constant or other expression which
8626    computes the same value, but in a more efficient manner (including
8627    calls to other builtin functions).
8628
8629    The call may contain arguments which need to be evaluated, but
8630    which are not useful to determine the result of the call.  In
8631    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8632    COMPOUND_EXPR will be an argument which must be evaluated.
8633    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8634    COMPOUND_EXPR in the chain will contain the tree for the simplified
8635    form of the builtin function call.  */
8636
8637 static tree
8638 fold_builtin_strpbrk (tree arglist, tree type)
8639 {
8640   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8641     return 0;
8642   else
8643     {
8644       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8645       tree fn;
8646       const char *p1, *p2;
8647
8648       p2 = c_getstr (s2);
8649       if (p2 == NULL)
8650         return 0;
8651
8652       p1 = c_getstr (s1);
8653       if (p1 != NULL)
8654         {
8655           const char *r = strpbrk (p1, p2);
8656           tree tem;
8657
8658           if (r == NULL)
8659             return build_int_cst (TREE_TYPE (s1), 0);
8660
8661           /* Return an offset into the constant string argument.  */
8662           tem = fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8663                               s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8664           return fold_convert (type, tem);
8665         }
8666
8667       if (p2[0] == '\0')
8668         /* strpbrk(x, "") == NULL.
8669            Evaluate and ignore s1 in case it had side-effects.  */
8670         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8671
8672       if (p2[1] != '\0')
8673         return 0;  /* Really call strpbrk.  */
8674
8675       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8676       if (!fn)
8677         return 0;
8678
8679       /* New argument list transforming strpbrk(s1, s2) to
8680          strchr(s1, s2[0]).  */
8681       arglist = build_tree_list (NULL_TREE,
8682                                  build_int_cst (NULL_TREE, p2[0]));
8683       arglist = tree_cons (NULL_TREE, s1, arglist);
8684       return build_function_call_expr (fn, arglist);
8685     }
8686 }
8687
8688 /* Simplify a call to the strcat builtin.
8689
8690    Return 0 if no simplification was possible, otherwise return the
8691    simplified form of the call as a tree.
8692
8693    The simplified form may be a constant or other expression which
8694    computes the same value, but in a more efficient manner (including
8695    calls to other builtin functions).
8696
8697    The call may contain arguments which need to be evaluated, but
8698    which are not useful to determine the result of the call.  In
8699    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8700    COMPOUND_EXPR will be an argument which must be evaluated.
8701    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8702    COMPOUND_EXPR in the chain will contain the tree for the simplified
8703    form of the builtin function call.  */
8704
8705 static tree
8706 fold_builtin_strcat (tree arglist)
8707 {
8708   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8709     return 0;
8710   else
8711     {
8712       tree dst = TREE_VALUE (arglist),
8713         src = TREE_VALUE (TREE_CHAIN (arglist));
8714       const char *p = c_getstr (src);
8715
8716       /* If the string length is zero, return the dst parameter.  */
8717       if (p && *p == '\0')
8718         return dst;
8719
8720       return 0;
8721     }
8722 }
8723
8724 /* Simplify a call to the strncat builtin.
8725
8726    Return 0 if no simplification was possible, otherwise return the
8727    simplified form of the call as a tree.
8728
8729    The simplified form may be a constant or other expression which
8730    computes the same value, but in a more efficient manner (including
8731    calls to other builtin functions).
8732
8733    The call may contain arguments which need to be evaluated, but
8734    which are not useful to determine the result of the call.  In
8735    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8736    COMPOUND_EXPR will be an argument which must be evaluated.
8737    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8738    COMPOUND_EXPR in the chain will contain the tree for the simplified
8739    form of the builtin function call.  */
8740
8741 static tree
8742 fold_builtin_strncat (tree arglist)
8743 {
8744   if (!validate_arglist (arglist,
8745                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8746     return 0;
8747   else
8748     {
8749       tree dst = TREE_VALUE (arglist);
8750       tree src = TREE_VALUE (TREE_CHAIN (arglist));
8751       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8752       const char *p = c_getstr (src);
8753
8754       /* If the requested length is zero, or the src parameter string
8755           length is zero, return the dst parameter.  */
8756       if (integer_zerop (len) || (p && *p == '\0'))
8757         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8758
8759       /* If the requested len is greater than or equal to the string
8760          length, call strcat.  */
8761       if (TREE_CODE (len) == INTEGER_CST && p
8762           && compare_tree_int (len, strlen (p)) >= 0)
8763         {
8764           tree newarglist
8765             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8766           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8767
8768           /* If the replacement _DECL isn't initialized, don't do the
8769              transformation.  */
8770           if (!fn)
8771             return 0;
8772
8773           return build_function_call_expr (fn, newarglist);
8774         }
8775       return 0;
8776     }
8777 }
8778
8779 /* Simplify a call to the strspn builtin.
8780
8781    Return 0 if no simplification was possible, otherwise return the
8782    simplified form of the call as a tree.
8783
8784    The simplified form may be a constant or other expression which
8785    computes the same value, but in a more efficient manner (including
8786    calls to other builtin functions).
8787
8788    The call may contain arguments which need to be evaluated, but
8789    which are not useful to determine the result of the call.  In
8790    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8791    COMPOUND_EXPR will be an argument which must be evaluated.
8792    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8793    COMPOUND_EXPR in the chain will contain the tree for the simplified
8794    form of the builtin function call.  */
8795
8796 static tree
8797 fold_builtin_strspn (tree arglist)
8798 {
8799   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8800     return 0;
8801   else
8802     {
8803       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8804       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8805
8806       /* If both arguments are constants, evaluate at compile-time.  */
8807       if (p1 && p2)
8808         {
8809           const size_t r = strspn (p1, p2);
8810           return size_int (r);
8811         }
8812
8813       /* If either argument is "", return 0.  */
8814       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8815         /* Evaluate and ignore both arguments in case either one has
8816            side-effects.  */
8817         return omit_two_operands (integer_type_node, integer_zero_node,
8818                                   s1, s2);
8819       return 0;
8820     }
8821 }
8822
8823 /* Simplify a call to the strcspn builtin.
8824
8825    Return 0 if no simplification was possible, otherwise return the
8826    simplified form of the call as a tree.
8827
8828    The simplified form may be a constant or other expression which
8829    computes the same value, but in a more efficient manner (including
8830    calls to other builtin functions).
8831
8832    The call may contain arguments which need to be evaluated, but
8833    which are not useful to determine the result of the call.  In
8834    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8835    COMPOUND_EXPR will be an argument which must be evaluated.
8836    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8837    COMPOUND_EXPR in the chain will contain the tree for the simplified
8838    form of the builtin function call.  */
8839
8840 static tree
8841 fold_builtin_strcspn (tree arglist)
8842 {
8843   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8844     return 0;
8845   else
8846     {
8847       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8848       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8849
8850       /* If both arguments are constants, evaluate at compile-time.  */
8851       if (p1 && p2)
8852         {
8853           const size_t r = strcspn (p1, p2);
8854           return size_int (r);
8855         }
8856
8857       /* If the first argument is "", return 0.  */
8858       if (p1 && *p1 == '\0')
8859         {
8860           /* Evaluate and ignore argument s2 in case it has
8861              side-effects.  */
8862           return omit_one_operand (integer_type_node,
8863                                    integer_zero_node, s2);
8864         }
8865
8866       /* If the second argument is "", return __builtin_strlen(s1).  */
8867       if (p2 && *p2 == '\0')
8868         {
8869           tree newarglist = build_tree_list (NULL_TREE, s1),
8870             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8871
8872           /* If the replacement _DECL isn't initialized, don't do the
8873              transformation.  */
8874           if (!fn)
8875             return 0;
8876
8877           return build_function_call_expr (fn, newarglist);
8878         }
8879       return 0;
8880     }
8881 }
8882
8883 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
8884    by the builtin will be ignored.  UNLOCKED is true is true if this
8885    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
8886    the known length of the string.  Return NULL_TREE if no simplification
8887    was possible.  */
8888
8889 tree
8890 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8891 {
8892   tree fn;
8893   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8894     : implicit_built_in_decls[BUILT_IN_FPUTC];
8895   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8896     : implicit_built_in_decls[BUILT_IN_FWRITE];
8897
8898   /* If the return value is used, or the replacement _DECL isn't
8899      initialized, don't do the transformation.  */
8900   if (!ignore || !fn_fputc || !fn_fwrite)
8901     return 0;
8902
8903   /* Verify the arguments in the original call.  */
8904   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8905     return 0;
8906
8907   if (! len)
8908     len = c_strlen (TREE_VALUE (arglist), 0);
8909
8910   /* Get the length of the string passed to fputs.  If the length
8911      can't be determined, punt.  */
8912   if (!len
8913       || TREE_CODE (len) != INTEGER_CST)
8914     return 0;
8915
8916   switch (compare_tree_int (len, 1))
8917     {
8918     case -1: /* length is 0, delete the call entirely .  */
8919       return omit_one_operand (integer_type_node, integer_zero_node,
8920                                TREE_VALUE (TREE_CHAIN (arglist)));
8921
8922     case 0: /* length is 1, call fputc.  */
8923       {
8924         const char *p = c_getstr (TREE_VALUE (arglist));
8925
8926         if (p != NULL)
8927           {
8928             /* New argument list transforming fputs(string, stream) to
8929                fputc(string[0], stream).  */
8930             arglist = build_tree_list (NULL_TREE,
8931                                        TREE_VALUE (TREE_CHAIN (arglist)));
8932             arglist = tree_cons (NULL_TREE,
8933                                  build_int_cst (NULL_TREE, p[0]),
8934                                  arglist);
8935             fn = fn_fputc;
8936             break;
8937           }
8938       }
8939       /* FALLTHROUGH */
8940     case 1: /* length is greater than 1, call fwrite.  */
8941       {
8942         tree string_arg;
8943
8944         /* If optimizing for size keep fputs.  */
8945         if (optimize_size)
8946           return 0;
8947         string_arg = TREE_VALUE (arglist);
8948         /* New argument list transforming fputs(string, stream) to
8949            fwrite(string, 1, len, stream).  */
8950         arglist = build_tree_list (NULL_TREE,
8951                                    TREE_VALUE (TREE_CHAIN (arglist)));
8952         arglist = tree_cons (NULL_TREE, len, arglist);
8953         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8954         arglist = tree_cons (NULL_TREE, string_arg, arglist);
8955         fn = fn_fwrite;
8956         break;
8957       }
8958     default:
8959       gcc_unreachable ();
8960     }
8961
8962   /* These optimizations are only performed when the result is ignored,
8963      hence there's no need to cast the result to integer_type_node.  */
8964   return build_function_call_expr (fn, arglist);
8965 }
8966
8967 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
8968    produced.  False otherwise.  This is done so that we don't output the error
8969    or warning twice or three times.  */
8970 bool
8971 fold_builtin_next_arg (tree arglist)
8972 {
8973   tree fntype = TREE_TYPE (current_function_decl);
8974
8975   if (TYPE_ARG_TYPES (fntype) == 0
8976       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8977           == void_type_node))
8978     {
8979       error ("%<va_start%> used in function with fixed args");
8980       return true;
8981     }
8982   else if (!arglist)
8983     {
8984       /* Evidently an out of date version of <stdarg.h>; can't validate
8985          va_start's second argument, but can still work as intended.  */
8986       warning ("%<__builtin_next_arg%> called without an argument");
8987       return true;
8988     }
8989   /* We use __builtin_va_start (ap, 0, 0) or __builtin_next_arg (0, 0)
8990      when we checked the arguments and if needed issued a warning.  */
8991   else if (!TREE_CHAIN (arglist)
8992            || !integer_zerop (TREE_VALUE (arglist))
8993            || !integer_zerop (TREE_VALUE (TREE_CHAIN (arglist)))
8994            || TREE_CHAIN (TREE_CHAIN (arglist)))
8995     {
8996       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8997       tree arg = TREE_VALUE (arglist);
8998
8999       if (TREE_CHAIN (arglist))
9000         {
9001           error ("%<va_start%> used with too many arguments");
9002           return true;
9003         }
9004
9005       /* Strip off all nops for the sake of the comparison.  This
9006          is not quite the same as STRIP_NOPS.  It does more.
9007          We must also strip off INDIRECT_EXPR for C++ reference
9008          parameters.  */
9009       while (TREE_CODE (arg) == NOP_EXPR
9010              || TREE_CODE (arg) == CONVERT_EXPR
9011              || TREE_CODE (arg) == NON_LVALUE_EXPR
9012              || TREE_CODE (arg) == INDIRECT_REF)
9013         arg = TREE_OPERAND (arg, 0);
9014       if (arg != last_parm)
9015         {
9016           /* FIXME: Sometimes with the tree optimizers we can get the
9017              not the last argument even though the user used the last
9018              argument.  We just warn and set the arg to be the last
9019              argument so that we will get wrong-code because of
9020              it.  */
9021           warning ("second parameter of %<va_start%> not last named argument");
9022         }
9023       /* We want to verify the second parameter just once before the tree
9024          optimizers are run and then avoid keeping it in the tree,
9025          as otherwise we could warn even for correct code like:
9026          void foo (int i, ...)
9027          { va_list ap; i++; va_start (ap, i); va_end (ap); }  */
9028       TREE_VALUE (arglist) = integer_zero_node;
9029       TREE_CHAIN (arglist) = build_tree_list (NULL, integer_zero_node);
9030     }
9031   return false;
9032 }
9033
9034
9035 /* Simplify a call to the sprintf builtin.
9036
9037    Return 0 if no simplification was possible, otherwise return the
9038    simplified form of the call as a tree.  If IGNORED is true, it means that
9039    the caller does not use the returned value of the function.  */
9040
9041 static tree
9042 fold_builtin_sprintf (tree arglist, int ignored)
9043 {
9044   tree call, retval, dest, fmt;
9045   const char *fmt_str = NULL;
9046
9047   /* Verify the required arguments in the original call.  We deal with two
9048      types of sprintf() calls: 'sprintf (str, fmt)' and
9049      'sprintf (dest, "%s", orig)'.  */
9050   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9051       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9052                             VOID_TYPE))
9053     return NULL_TREE;
9054
9055   /* Get the destination string and the format specifier.  */
9056   dest = TREE_VALUE (arglist);
9057   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9058
9059   /* Check whether the format is a literal string constant.  */
9060   fmt_str = c_getstr (fmt);
9061   if (fmt_str == NULL)
9062     return NULL_TREE;
9063
9064   call = NULL_TREE;
9065   retval = NULL_TREE;
9066
9067   /* If the format doesn't contain % args or %%, use strcpy.  */
9068   if (strchr (fmt_str, '%') == NULL)
9069     {
9070       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9071
9072       if (!fn)
9073         return NULL_TREE;
9074
9075       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9076          'format' is known to contain no % formats.  */
9077       arglist = build_tree_list (NULL_TREE, fmt);
9078       arglist = tree_cons (NULL_TREE, dest, arglist);
9079       call = build_function_call_expr (fn, arglist);
9080       if (!ignored)
9081         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
9082     }
9083
9084   /* If the format is "%s", use strcpy if the result isn't used.  */
9085   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9086     {
9087       tree fn, orig;
9088       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9089
9090       if (!fn)
9091         return NULL_TREE;
9092
9093       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9094       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9095       arglist = build_tree_list (NULL_TREE, orig);
9096       arglist = tree_cons (NULL_TREE, dest, arglist);
9097       if (!ignored)
9098         {
9099           retval = c_strlen (orig, 1);
9100           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9101             return NULL_TREE;
9102         }
9103       call = build_function_call_expr (fn, arglist);
9104     }
9105
9106   if (call && retval)
9107     {
9108       retval = convert
9109         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9110          retval);
9111       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9112     }
9113   else
9114     return call;
9115 }