OSDN Git Service

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