OSDN Git Service

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