OSDN Git Service

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