OSDN Git Service

PR c++/18733
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
1 /* Expand builtin functions.
2    Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3    2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "machmode.h"
27 #include "real.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "tree-gimple.h"
31 #include "flags.h"
32 #include "regs.h"
33 #include "hard-reg-set.h"
34 #include "except.h"
35 #include "function.h"
36 #include "insn-config.h"
37 #include "expr.h"
38 #include "optabs.h"
39 #include "libfuncs.h"
40 #include "recog.h"
41 #include "output.h"
42 #include "typeclass.h"
43 #include "toplev.h"
44 #include "predict.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "langhooks.h"
48 #include "basic-block.h"
49 #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 (tree);
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 (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
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 (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
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 ARGLIST, from a call to __builtin_next_arg.  */
3747
3748 static rtx
3749 expand_builtin_next_arg (tree arglist)
3750 {
3751   tree fntype = TREE_TYPE (current_function_decl);
3752
3753   if (TYPE_ARG_TYPES (fntype) == 0
3754       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3755           == void_type_node))
3756     {
3757       error ("%<va_start%> used in function with fixed args");
3758       return const0_rtx;
3759     }
3760
3761   if (arglist)
3762     {
3763       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3764       tree arg = TREE_VALUE (arglist);
3765
3766       /* Strip off all nops for the sake of the comparison.  This
3767          is not quite the same as STRIP_NOPS.  It does more.
3768          We must also strip off INDIRECT_EXPR for C++ reference
3769          parameters.  */
3770       while (TREE_CODE (arg) == NOP_EXPR
3771              || TREE_CODE (arg) == CONVERT_EXPR
3772              || TREE_CODE (arg) == NON_LVALUE_EXPR
3773              || TREE_CODE (arg) == INDIRECT_REF)
3774         arg = TREE_OPERAND (arg, 0);
3775       if (arg != last_parm)
3776         warning ("second parameter of %<va_start%> not last named argument");
3777     }
3778   else
3779     /* Evidently an out of date version of <stdarg.h>; can't validate
3780        va_start's second argument, but can still work as intended.  */
3781     warning ("%<__builtin_next_arg%> called without an argument");
3782
3783   return expand_binop (Pmode, add_optab,
3784                        current_function_internal_arg_pointer,
3785                        current_function_arg_offset_rtx,
3786                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3787 }
3788
3789 /* Make it easier for the backends by protecting the valist argument
3790    from multiple evaluations.  */
3791
3792 static tree
3793 stabilize_va_list (tree valist, int needs_lvalue)
3794 {
3795   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3796     {
3797       if (TREE_SIDE_EFFECTS (valist))
3798         valist = save_expr (valist);
3799
3800       /* For this case, the backends will be expecting a pointer to
3801          TREE_TYPE (va_list_type_node), but it's possible we've
3802          actually been given an array (an actual va_list_type_node).
3803          So fix it.  */
3804       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3805         {
3806           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3807           valist = build_fold_addr_expr_with_type (valist, p1);
3808         }
3809     }
3810   else
3811     {
3812       tree pt;
3813
3814       if (! needs_lvalue)
3815         {
3816           if (! TREE_SIDE_EFFECTS (valist))
3817             return valist;
3818
3819           pt = build_pointer_type (va_list_type_node);
3820           valist = fold (build1 (ADDR_EXPR, pt, valist));
3821           TREE_SIDE_EFFECTS (valist) = 1;
3822         }
3823
3824       if (TREE_SIDE_EFFECTS (valist))
3825         valist = save_expr (valist);
3826       valist = build_fold_indirect_ref (valist);
3827     }
3828
3829   return valist;
3830 }
3831
3832 /* The "standard" definition of va_list is void*.  */
3833
3834 tree
3835 std_build_builtin_va_list (void)
3836 {
3837   return ptr_type_node;
3838 }
3839
3840 /* The "standard" implementation of va_start: just assign `nextarg' to
3841    the variable.  */
3842
3843 void
3844 std_expand_builtin_va_start (tree valist, rtx nextarg)
3845 {
3846   tree t;
3847
3848   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
3849               make_tree (ptr_type_node, nextarg));
3850   TREE_SIDE_EFFECTS (t) = 1;
3851
3852   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3853 }
3854
3855 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3856
3857 static rtx
3858 expand_builtin_va_start (tree arglist)
3859 {
3860   rtx nextarg;
3861   tree chain, valist;
3862
3863   chain = TREE_CHAIN (arglist);
3864
3865   if (!chain)
3866     {
3867       error ("too few arguments to function %<va_start%>");
3868       return const0_rtx;
3869     }
3870   if (TREE_CHAIN (chain))
3871     error ("too many arguments to function %<va_start%>");
3872
3873   if (fold_builtin_next_arg (chain))
3874     {
3875       return const0_rtx;
3876     }
3877
3878   nextarg = expand_builtin_next_arg (chain);
3879   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3880
3881 #ifdef EXPAND_BUILTIN_VA_START
3882   EXPAND_BUILTIN_VA_START (valist, nextarg);
3883 #else
3884   std_expand_builtin_va_start (valist, nextarg);
3885 #endif
3886
3887   return const0_rtx;
3888 }
3889
3890 /* The "standard" implementation of va_arg: read the value from the
3891    current (padded) address and increment by the (padded) size.  */
3892
3893 tree
3894 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3895 {
3896   tree addr, t, type_size, rounded_size, valist_tmp;
3897   unsigned HOST_WIDE_INT align, boundary;
3898   bool indirect;
3899
3900 #ifdef ARGS_GROW_DOWNWARD
3901   /* All of the alignment and movement below is for args-grow-up machines.
3902      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
3903      implement their own specialized gimplify_va_arg_expr routines.  */
3904   gcc_unreachable ();
3905 #endif
3906
3907   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
3908   if (indirect)
3909     type = build_pointer_type (type);
3910
3911   align = PARM_BOUNDARY / BITS_PER_UNIT;
3912   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
3913
3914   /* Hoist the valist value into a temporary for the moment.  */
3915   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
3916
3917   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
3918      requires greater alignment, we must perform dynamic alignment.  */
3919   if (boundary > align)
3920     {
3921       t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
3922       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3923                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
3924       gimplify_and_add (t, pre_p);
3925
3926       t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
3927       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3928                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
3929       gimplify_and_add (t, pre_p);
3930     }
3931
3932   /* Compute the rounded size of the type.  */
3933   type_size = size_in_bytes (type);
3934   rounded_size = round_up (type_size, align);
3935
3936   /* Reduce rounded_size so it's sharable with the postqueue.  */
3937   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
3938
3939   /* Get AP.  */
3940   addr = valist_tmp;
3941   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
3942     {
3943       /* Small args are padded downward.  */
3944       t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
3945       t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
3946                         size_binop (MINUS_EXPR, rounded_size, type_size)));
3947       t = fold_convert (TREE_TYPE (addr), t);
3948       addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
3949     }
3950
3951   /* Compute new value for AP.  */
3952   t = fold_convert (TREE_TYPE (valist), rounded_size);
3953   t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
3954   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
3955   gimplify_and_add (t, pre_p);
3956
3957   addr = fold_convert (build_pointer_type (type), addr);
3958
3959   if (indirect)
3960     addr = build_va_arg_indirect_ref (addr);
3961
3962   return build_va_arg_indirect_ref (addr);
3963 }
3964
3965 /* Build an indirect-ref expression over the given TREE, which represents a
3966    piece of a va_arg() expansion.  */
3967 tree
3968 build_va_arg_indirect_ref (tree addr)
3969 {
3970   addr = build_fold_indirect_ref (addr);
3971
3972   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
3973     mf_mark (addr);
3974
3975   return addr;
3976 }
3977
3978 /* Return a dummy expression of type TYPE in order to keep going after an
3979    error.  */
3980
3981 static tree
3982 dummy_object (tree type)
3983 {
3984   tree t = convert (build_pointer_type (type), null_pointer_node);
3985   return build1 (INDIRECT_REF, type, t);
3986 }
3987
3988 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
3989    builtin function, but a very special sort of operator.  */
3990
3991 enum gimplify_status
3992 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
3993 {
3994   tree promoted_type, want_va_type, have_va_type;
3995   tree valist = TREE_OPERAND (*expr_p, 0);
3996   tree type = TREE_TYPE (*expr_p);
3997   tree t;
3998
3999   /* Verify that valist is of the proper type.  */
4000   want_va_type = va_list_type_node;
4001   have_va_type = TREE_TYPE (valist);
4002
4003   if (have_va_type == error_mark_node)
4004     return GS_ERROR;
4005
4006   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4007     {
4008       /* If va_list is an array type, the argument may have decayed
4009          to a pointer type, e.g. by being passed to another function.
4010          In that case, unwrap both types so that we can compare the
4011          underlying records.  */
4012       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4013           || TREE_CODE (have_va_type) == POINTER_TYPE)
4014         {
4015           want_va_type = TREE_TYPE (want_va_type);
4016           have_va_type = TREE_TYPE (have_va_type);
4017         }
4018     }
4019
4020   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4021     {
4022       error ("first argument to %<va_arg%> not of type %<va_list%>");
4023       return GS_ERROR;
4024     }
4025
4026   /* Generate a diagnostic for requesting data of a type that cannot
4027      be passed through `...' due to type promotion at the call site.  */
4028   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4029            != type)
4030     {
4031       static bool gave_help;
4032
4033       /* Unfortunately, this is merely undefined, rather than a constraint
4034          violation, so we cannot make this an error.  If this call is never
4035          executed, the program is still strictly conforming.  */
4036       warning ("%qT is promoted to %qT when passed through %<...%>",
4037                type, promoted_type);
4038       if (! gave_help)
4039         {
4040           gave_help = true;
4041           warning ("(so you should pass %qT not %qT to %<va_arg%>)",
4042                    promoted_type, type);
4043         }
4044
4045       /* We can, however, treat "undefined" any way we please.
4046          Call abort to encourage the user to fix the program.  */
4047       inform ("if this code is reached, the program will abort");
4048       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4049                                     NULL);
4050       append_to_statement_list (t, pre_p);
4051
4052       /* This is dead code, but go ahead and finish so that the
4053          mode of the result comes out right.  */
4054       *expr_p = dummy_object (type);
4055       return GS_ALL_DONE;
4056     }
4057   else
4058     {
4059       /* Make it easier for the backends by protecting the valist argument
4060          from multiple evaluations.  */
4061       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4062         {
4063           /* For this case, the backends will be expecting a pointer to
4064              TREE_TYPE (va_list_type_node), but it's possible we've
4065              actually been given an array (an actual va_list_type_node).
4066              So fix it.  */
4067           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4068             {
4069               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4070               valist = build_fold_addr_expr_with_type (valist, p1);
4071             }
4072           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4073         }
4074       else
4075         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4076
4077       if (!targetm.gimplify_va_arg_expr)
4078         /* Once most targets are converted this should abort.  */
4079         return GS_ALL_DONE;
4080
4081       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4082       return GS_OK;
4083     }
4084 }
4085
4086 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4087
4088 static rtx
4089 expand_builtin_va_end (tree arglist)
4090 {
4091   tree valist = TREE_VALUE (arglist);
4092
4093   /* Evaluate for side effects, if needed.  I hate macros that don't
4094      do that.  */
4095   if (TREE_SIDE_EFFECTS (valist))
4096     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4097
4098   return const0_rtx;
4099 }
4100
4101 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4102    builtin rather than just as an assignment in stdarg.h because of the
4103    nastiness of array-type va_list types.  */
4104
4105 static rtx
4106 expand_builtin_va_copy (tree arglist)
4107 {
4108   tree dst, src, t;
4109
4110   dst = TREE_VALUE (arglist);
4111   src = TREE_VALUE (TREE_CHAIN (arglist));
4112
4113   dst = stabilize_va_list (dst, 1);
4114   src = stabilize_va_list (src, 0);
4115
4116   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4117     {
4118       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4119       TREE_SIDE_EFFECTS (t) = 1;
4120       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4121     }
4122   else
4123     {
4124       rtx dstb, srcb, size;
4125
4126       /* Evaluate to pointers.  */
4127       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4128       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4129       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4130                           VOIDmode, EXPAND_NORMAL);
4131
4132       dstb = convert_memory_address (Pmode, dstb);
4133       srcb = convert_memory_address (Pmode, srcb);
4134
4135       /* "Dereference" to BLKmode memories.  */
4136       dstb = gen_rtx_MEM (BLKmode, dstb);
4137       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4138       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4139       srcb = gen_rtx_MEM (BLKmode, srcb);
4140       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4141       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4142
4143       /* Copy.  */
4144       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4145     }
4146
4147   return const0_rtx;
4148 }
4149
4150 /* Expand a call to one of the builtin functions __builtin_frame_address or
4151    __builtin_return_address.  */
4152
4153 static rtx
4154 expand_builtin_frame_address (tree fndecl, tree arglist)
4155 {
4156   /* The argument must be a nonnegative integer constant.
4157      It counts the number of frames to scan up the stack.
4158      The value is the return address saved in that frame.  */
4159   if (arglist == 0)
4160     /* Warning about missing arg was already issued.  */
4161     return const0_rtx;
4162   else if (! host_integerp (TREE_VALUE (arglist), 1))
4163     {
4164       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4165         error ("invalid argument to %<__builtin_frame_address%>");
4166       else
4167         error ("invalid argument to %<__builtin_return_address%>");
4168       return const0_rtx;
4169     }
4170   else
4171     {
4172       rtx tem
4173         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4174                                       tree_low_cst (TREE_VALUE (arglist), 1),
4175                                       hard_frame_pointer_rtx);
4176
4177       /* Some ports cannot access arbitrary stack frames.  */
4178       if (tem == NULL)
4179         {
4180           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4181             warning ("unsupported argument to %<__builtin_frame_address%>");
4182           else
4183             warning ("unsupported argument to %<__builtin_return_address%>");
4184           return const0_rtx;
4185         }
4186
4187       /* For __builtin_frame_address, return what we've got.  */
4188       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4189         return tem;
4190
4191       if (!REG_P (tem)
4192           && ! CONSTANT_P (tem))
4193         tem = copy_to_mode_reg (Pmode, tem);
4194       return tem;
4195     }
4196 }
4197
4198 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4199    we failed and the caller should emit a normal call, otherwise try to get
4200    the result in TARGET, if convenient.  */
4201
4202 static rtx
4203 expand_builtin_alloca (tree arglist, rtx target)
4204 {
4205   rtx op0;
4206   rtx result;
4207
4208   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4209      should always expand to function calls.  These can be intercepted
4210      in libmudflap.  */
4211   if (flag_mudflap)
4212     return 0;
4213
4214   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4215     return 0;
4216
4217   /* Compute the argument.  */
4218   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4219
4220   /* Allocate the desired space.  */
4221   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4222   result = convert_memory_address (ptr_mode, result);
4223
4224   return result;
4225 }
4226
4227 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4228    Return 0 if a normal call should be emitted rather than expanding the
4229    function in-line.  If convenient, the result should be placed in TARGET.
4230    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4231
4232 static rtx
4233 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4234                      rtx subtarget, optab op_optab)
4235 {
4236   rtx op0;
4237   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4238     return 0;
4239
4240   /* Compute the argument.  */
4241   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4242   /* Compute op, into TARGET if possible.
4243      Set TARGET to wherever the result comes back.  */
4244   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4245                         op_optab, op0, target, 1);
4246   gcc_assert (target);
4247
4248   return convert_to_mode (target_mode, target, 0);
4249 }
4250
4251 /* If the string passed to fputs is a constant and is one character
4252    long, we attempt to transform this call into __builtin_fputc().  */
4253
4254 static rtx
4255 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4256 {
4257   /* Verify the arguments in the original call.  */
4258   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4259     {
4260       tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4261                                         unlocked, NULL_TREE);
4262       if (result)
4263         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4264     }
4265   return 0;
4266 }
4267
4268 /* Expand a call to __builtin_expect.  We return our argument and emit a
4269    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4270    a non-jump context.  */
4271
4272 static rtx
4273 expand_builtin_expect (tree arglist, rtx target)
4274 {
4275   tree exp, c;
4276   rtx note, rtx_c;
4277
4278   if (arglist == NULL_TREE
4279       || TREE_CHAIN (arglist) == NULL_TREE)
4280     return const0_rtx;
4281   exp = TREE_VALUE (arglist);
4282   c = TREE_VALUE (TREE_CHAIN (arglist));
4283
4284   if (TREE_CODE (c) != INTEGER_CST)
4285     {
4286       error ("second argument to %<__builtin_expect%> must be a constant");
4287       c = integer_zero_node;
4288     }
4289
4290   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4291
4292   /* Don't bother with expected value notes for integral constants.  */
4293   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4294     {
4295       /* We do need to force this into a register so that we can be
4296          moderately sure to be able to correctly interpret the branch
4297          condition later.  */
4298       target = force_reg (GET_MODE (target), target);
4299
4300       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4301
4302       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4303       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4304     }
4305
4306   return target;
4307 }
4308
4309 /* Like expand_builtin_expect, except do this in a jump context.  This is
4310    called from do_jump if the conditional is a __builtin_expect.  Return either
4311    a list of insns to emit the jump or NULL if we cannot optimize
4312    __builtin_expect.  We need to optimize this at jump time so that machines
4313    like the PowerPC don't turn the test into a SCC operation, and then jump
4314    based on the test being 0/1.  */
4315
4316 rtx
4317 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4318 {
4319   tree arglist = TREE_OPERAND (exp, 1);
4320   tree arg0 = TREE_VALUE (arglist);
4321   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4322   rtx ret = NULL_RTX;
4323
4324   /* Only handle __builtin_expect (test, 0) and
4325      __builtin_expect (test, 1).  */
4326   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4327       && (integer_zerop (arg1) || integer_onep (arg1)))
4328     {
4329       rtx insn, drop_through_label, temp;
4330
4331       /* Expand the jump insns.  */
4332       start_sequence ();
4333       do_jump (arg0, if_false_label, if_true_label);
4334       ret = get_insns ();
4335
4336       drop_through_label = get_last_insn ();
4337       if (drop_through_label && NOTE_P (drop_through_label))
4338         drop_through_label = prev_nonnote_insn (drop_through_label);
4339       if (drop_through_label && !LABEL_P (drop_through_label))
4340         drop_through_label = NULL_RTX;
4341       end_sequence ();
4342
4343       if (! if_true_label)
4344         if_true_label = drop_through_label;
4345       if (! if_false_label)
4346         if_false_label = drop_through_label;
4347
4348       /* Go through and add the expect's to each of the conditional jumps.  */
4349       insn = ret;
4350       while (insn != NULL_RTX)
4351         {
4352           rtx next = NEXT_INSN (insn);
4353
4354           if (JUMP_P (insn) && any_condjump_p (insn))
4355             {
4356               rtx ifelse = SET_SRC (pc_set (insn));
4357               rtx then_dest = XEXP (ifelse, 1);
4358               rtx else_dest = XEXP (ifelse, 2);
4359               int taken = -1;
4360
4361               /* First check if we recognize any of the labels.  */
4362               if (GET_CODE (then_dest) == LABEL_REF
4363                   && XEXP (then_dest, 0) == if_true_label)
4364                 taken = 1;
4365               else if (GET_CODE (then_dest) == LABEL_REF
4366                        && XEXP (then_dest, 0) == if_false_label)
4367                 taken = 0;
4368               else if (GET_CODE (else_dest) == LABEL_REF
4369                        && XEXP (else_dest, 0) == if_false_label)
4370                 taken = 1;
4371               else if (GET_CODE (else_dest) == LABEL_REF
4372                        && XEXP (else_dest, 0) == if_true_label)
4373                 taken = 0;
4374               /* Otherwise check where we drop through.  */
4375               else if (else_dest == pc_rtx)
4376                 {
4377                   if (next && NOTE_P (next))
4378                     next = next_nonnote_insn (next);
4379
4380                   if (next && JUMP_P (next)
4381                       && any_uncondjump_p (next))
4382                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4383                   else
4384                     temp = next;
4385
4386                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4387                      else that can't possibly match either target label.  */
4388                   if (temp == if_false_label)
4389                     taken = 1;
4390                   else if (temp == if_true_label)
4391                     taken = 0;
4392                 }
4393               else if (then_dest == pc_rtx)
4394                 {
4395                   if (next && NOTE_P (next))
4396                     next = next_nonnote_insn (next);
4397
4398                   if (next && JUMP_P (next)
4399                       && any_uncondjump_p (next))
4400                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4401                   else
4402                     temp = next;
4403
4404                   if (temp == if_false_label)
4405                     taken = 0;
4406                   else if (temp == if_true_label)
4407                     taken = 1;
4408                 }
4409
4410               if (taken != -1)
4411                 {
4412                   /* If the test is expected to fail, reverse the
4413                      probabilities.  */
4414                   if (integer_zerop (arg1))
4415                     taken = 1 - taken;
4416                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4417                 }
4418             }
4419
4420           insn = next;
4421         }
4422     }
4423
4424   return ret;
4425 }
4426
4427 static void
4428 expand_builtin_trap (void)
4429 {
4430 #ifdef HAVE_trap
4431   if (HAVE_trap)
4432     emit_insn (gen_trap ());
4433   else
4434 #endif
4435     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4436   emit_barrier ();
4437 }
4438
4439 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4440    Return 0 if a normal call should be emitted rather than expanding
4441    the function inline.  If convenient, the result should be placed
4442    in TARGET.  SUBTARGET may be used as the target for computing
4443    the operand.  */
4444
4445 static rtx
4446 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4447 {
4448   enum machine_mode mode;
4449   tree arg;
4450   rtx op0;
4451
4452   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4453     return 0;
4454
4455   arg = TREE_VALUE (arglist);
4456   mode = TYPE_MODE (TREE_TYPE (arg));
4457   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4458   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4459 }
4460
4461 /* Create a new constant string literal and return a char* pointer to it.
4462    The STRING_CST value is the LEN characters at STR.  */
4463 static tree
4464 build_string_literal (int len, const char *str)
4465 {
4466   tree t, elem, index, type;
4467
4468   t = build_string (len, str);
4469   elem = build_type_variant (char_type_node, 1, 0);
4470   index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4471   type = build_array_type (elem, index);
4472   TREE_TYPE (t) = type;
4473   TREE_CONSTANT (t) = 1;
4474   TREE_INVARIANT (t) = 1;
4475   TREE_READONLY (t) = 1;
4476   TREE_STATIC (t) = 1;
4477
4478   type = build_pointer_type (type);
4479   t = build1 (ADDR_EXPR, type, t);
4480
4481   type = build_pointer_type (elem);
4482   t = build1 (NOP_EXPR, type, t);
4483   return t;
4484 }
4485
4486 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4487    Return 0 if a normal call should be emitted rather than transforming
4488    the function inline.  If convenient, the result should be placed in
4489    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4490    call.  */
4491 static rtx
4492 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4493                        bool unlocked)
4494 {
4495   tree fn_putchar = unlocked
4496                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4497                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4498   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4499                           : implicit_built_in_decls[BUILT_IN_PUTS];
4500   const char *fmt_str;
4501   tree fn, fmt, arg;
4502
4503   /* If the return value is used, don't do the transformation.  */
4504   if (target != const0_rtx)
4505     return 0;
4506
4507   /* Verify the required arguments in the original call.  */
4508   if (! arglist)
4509     return 0;
4510   fmt = TREE_VALUE (arglist);
4511   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4512     return 0;
4513   arglist = TREE_CHAIN (arglist);
4514
4515   /* Check whether the format is a literal string constant.  */
4516   fmt_str = c_getstr (fmt);
4517   if (fmt_str == NULL)
4518     return 0;
4519
4520   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4521   if (strcmp (fmt_str, "%s\n") == 0)
4522     {
4523       if (! arglist
4524           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4525           || TREE_CHAIN (arglist))
4526         return 0;
4527       fn = fn_puts;
4528     }
4529   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4530   else if (strcmp (fmt_str, "%c") == 0)
4531     {
4532       if (! arglist
4533           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4534           || TREE_CHAIN (arglist))
4535         return 0;
4536       fn = fn_putchar;
4537     }
4538   else
4539     {
4540       /* We can't handle anything else with % args or %% ... yet.  */
4541       if (strchr (fmt_str, '%'))
4542         return 0;
4543
4544       if (arglist)
4545         return 0;
4546
4547       /* If the format specifier was "", printf does nothing.  */
4548       if (fmt_str[0] == '\0')
4549         return const0_rtx;
4550       /* If the format specifier has length of 1, call putchar.  */
4551       if (fmt_str[1] == '\0')
4552         {
4553           /* Given printf("c"), (where c is any one character,)
4554              convert "c"[0] to an int and pass that to the replacement
4555              function.  */
4556           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4557           arglist = build_tree_list (NULL_TREE, arg);
4558           fn = fn_putchar;
4559         }
4560       else
4561         {
4562           /* If the format specifier was "string\n", call puts("string").  */
4563           size_t len = strlen (fmt_str);
4564           if (fmt_str[len - 1] == '\n')
4565             {
4566               /* Create a NUL-terminated string that's one char shorter
4567                  than the original, stripping off the trailing '\n'.  */
4568               char *newstr = alloca (len);
4569               memcpy (newstr, fmt_str, len - 1);
4570               newstr[len - 1] = 0;
4571
4572               arg = build_string_literal (len, newstr);
4573               arglist = build_tree_list (NULL_TREE, arg);
4574               fn = fn_puts;
4575             }
4576           else
4577             /* We'd like to arrange to call fputs(string,stdout) here,
4578                but we need stdout and don't have a way to get it yet.  */
4579             return 0;
4580         }
4581     }
4582
4583   if (!fn)
4584     return 0;
4585   return expand_expr (build_function_call_expr (fn, arglist),
4586                       target, mode, EXPAND_NORMAL);
4587 }
4588
4589 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4590    Return 0 if a normal call should be emitted rather than transforming
4591    the function inline.  If convenient, the result should be placed in
4592    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4593    call.  */
4594 static rtx
4595 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4596                         bool unlocked)
4597 {
4598   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4599                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4600   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4601                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4602   const char *fmt_str;
4603   tree fn, fmt, fp, arg;
4604
4605   /* If the return value is used, don't do the transformation.  */
4606   if (target != const0_rtx)
4607     return 0;
4608
4609   /* Verify the required arguments in the original call.  */
4610   if (! arglist)
4611     return 0;
4612   fp = TREE_VALUE (arglist);
4613   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4614     return 0;
4615   arglist = TREE_CHAIN (arglist);
4616   if (! arglist)
4617     return 0;
4618   fmt = TREE_VALUE (arglist);
4619   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4620     return 0;
4621   arglist = TREE_CHAIN (arglist);
4622
4623   /* Check whether the format is a literal string constant.  */
4624   fmt_str = c_getstr (fmt);
4625   if (fmt_str == NULL)
4626     return 0;
4627
4628   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4629   if (strcmp (fmt_str, "%s") == 0)
4630     {
4631       if (! arglist
4632           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4633           || TREE_CHAIN (arglist))
4634         return 0;
4635       arg = TREE_VALUE (arglist);
4636       arglist = build_tree_list (NULL_TREE, fp);
4637       arglist = tree_cons (NULL_TREE, arg, arglist);
4638       fn = fn_fputs;
4639     }
4640   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4641   else if (strcmp (fmt_str, "%c") == 0)
4642     {
4643       if (! arglist
4644           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4645           || TREE_CHAIN (arglist))
4646         return 0;
4647       arg = TREE_VALUE (arglist);
4648       arglist = build_tree_list (NULL_TREE, fp);
4649       arglist = tree_cons (NULL_TREE, arg, arglist);
4650       fn = fn_fputc;
4651     }
4652   else
4653     {
4654       /* We can't handle anything else with % args or %% ... yet.  */
4655       if (strchr (fmt_str, '%'))
4656         return 0;
4657
4658       if (arglist)
4659         return 0;
4660
4661       /* If the format specifier was "", fprintf does nothing.  */
4662       if (fmt_str[0] == '\0')
4663         {
4664           /* Evaluate and ignore FILE* argument for side-effects.  */
4665           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4666           return const0_rtx;
4667         }
4668
4669       /* When "string" doesn't contain %, replace all cases of
4670          fprintf(stream,string) with fputs(string,stream).  The fputs
4671          builtin will take care of special cases like length == 1.  */
4672       arglist = build_tree_list (NULL_TREE, fp);
4673       arglist = tree_cons (NULL_TREE, fmt, arglist);
4674       fn = fn_fputs;
4675     }
4676
4677   if (!fn)
4678     return 0;
4679   return expand_expr (build_function_call_expr (fn, arglist),
4680                       target, mode, EXPAND_NORMAL);
4681 }
4682
4683 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4684    a normal call should be emitted rather than expanding the function
4685    inline.  If convenient, the result should be placed in TARGET with
4686    mode MODE.  */
4687
4688 static rtx
4689 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4690 {
4691   tree orig_arglist, dest, fmt;
4692   const char *fmt_str;
4693
4694   orig_arglist = arglist;
4695
4696   /* Verify the required arguments in the original call.  */
4697   if (! arglist)
4698     return 0;
4699   dest = TREE_VALUE (arglist);
4700   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4701     return 0;
4702   arglist = TREE_CHAIN (arglist);
4703   if (! arglist)
4704     return 0;
4705   fmt = TREE_VALUE (arglist);
4706   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4707     return 0;
4708   arglist = TREE_CHAIN (arglist);
4709
4710   /* Check whether the format is a literal string constant.  */
4711   fmt_str = c_getstr (fmt);
4712   if (fmt_str == NULL)
4713     return 0;
4714
4715   /* If the format doesn't contain % args or %%, use strcpy.  */
4716   if (strchr (fmt_str, '%') == 0)
4717     {
4718       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4719       tree exp;
4720
4721       if (arglist || ! fn)
4722         return 0;
4723       expand_expr (build_function_call_expr (fn, orig_arglist),
4724                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4725       if (target == const0_rtx)
4726         return const0_rtx;
4727       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
4728       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4729     }
4730   /* If the format is "%s", use strcpy if the result isn't used.  */
4731   else if (strcmp (fmt_str, "%s") == 0)
4732     {
4733       tree fn, arg, len;
4734       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4735
4736       if (! fn)
4737         return 0;
4738
4739       if (! arglist || TREE_CHAIN (arglist))
4740         return 0;
4741       arg = TREE_VALUE (arglist);
4742       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4743         return 0;
4744
4745       if (target != const0_rtx)
4746         {
4747           len = c_strlen (arg, 1);
4748           if (! len || TREE_CODE (len) != INTEGER_CST)
4749             return 0;
4750         }
4751       else
4752         len = NULL_TREE;
4753
4754       arglist = build_tree_list (NULL_TREE, arg);
4755       arglist = tree_cons (NULL_TREE, dest, arglist);
4756       expand_expr (build_function_call_expr (fn, arglist),
4757                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4758
4759       if (target == const0_rtx)
4760         return const0_rtx;
4761       return expand_expr (len, target, mode, EXPAND_NORMAL);
4762     }
4763
4764   return 0;
4765 }
4766
4767 /* Expand a call to either the entry or exit function profiler.  */
4768
4769 static rtx
4770 expand_builtin_profile_func (bool exitp)
4771 {
4772   rtx this, which;
4773
4774   this = DECL_RTL (current_function_decl);
4775   gcc_assert (MEM_P (this));
4776   this = XEXP (this, 0);
4777
4778   if (exitp)
4779     which = profile_function_exit_libfunc;
4780   else
4781     which = profile_function_entry_libfunc;
4782
4783   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
4784                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
4785                                                  0, hard_frame_pointer_rtx),
4786                      Pmode);
4787
4788   return const0_rtx;
4789 }
4790
4791 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4792
4793 static rtx
4794 round_trampoline_addr (rtx tramp)
4795 {
4796   rtx temp, addend, mask;
4797
4798   /* If we don't need too much alignment, we'll have been guaranteed
4799      proper alignment by get_trampoline_type.  */
4800   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4801     return tramp;
4802
4803   /* Round address up to desired boundary.  */
4804   temp = gen_reg_rtx (Pmode);
4805   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4806   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4807
4808   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4809                                temp, 0, OPTAB_LIB_WIDEN);
4810   tramp = expand_simple_binop (Pmode, AND, temp, mask,
4811                                temp, 0, OPTAB_LIB_WIDEN);
4812
4813   return tramp;
4814 }
4815
4816 static rtx
4817 expand_builtin_init_trampoline (tree arglist)
4818 {
4819   tree t_tramp, t_func, t_chain;
4820   rtx r_tramp, r_func, r_chain;
4821 #ifdef TRAMPOLINE_TEMPLATE
4822   rtx blktramp;
4823 #endif
4824
4825   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
4826                          POINTER_TYPE, VOID_TYPE))
4827     return NULL_RTX;
4828
4829   t_tramp = TREE_VALUE (arglist);
4830   arglist = TREE_CHAIN (arglist);
4831   t_func = TREE_VALUE (arglist);
4832   arglist = TREE_CHAIN (arglist);
4833   t_chain = TREE_VALUE (arglist);
4834
4835   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
4836   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
4837   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
4838
4839   /* Generate insns to initialize the trampoline.  */
4840   r_tramp = round_trampoline_addr (r_tramp);
4841 #ifdef TRAMPOLINE_TEMPLATE
4842   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
4843   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
4844   emit_block_move (blktramp, assemble_trampoline_template (),
4845                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4846 #endif
4847   trampolines_created = 1;
4848   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
4849
4850   return const0_rtx;
4851 }
4852
4853 static rtx
4854 expand_builtin_adjust_trampoline (tree arglist)
4855 {
4856   rtx tramp;
4857
4858   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4859     return NULL_RTX;
4860
4861   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4862   tramp = round_trampoline_addr (tramp);
4863 #ifdef TRAMPOLINE_ADJUST_ADDRESS
4864   TRAMPOLINE_ADJUST_ADDRESS (tramp);
4865 #endif
4866
4867   return tramp;
4868 }
4869
4870 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4871    Return NULL_RTX if a normal call should be emitted rather than expanding
4872    the function in-line.  EXP is the expression that is a call to the builtin
4873    function; if convenient, the result should be placed in TARGET.  */
4874
4875 static rtx
4876 expand_builtin_signbit (tree exp, rtx target)
4877 {
4878   const struct real_format *fmt;
4879   enum machine_mode fmode, imode, rmode;
4880   HOST_WIDE_INT hi, lo;
4881   tree arg, arglist;
4882   int bitpos;
4883   rtx temp;
4884
4885   arglist = TREE_OPERAND (exp, 1);
4886   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4887     return 0;
4888
4889   arg = TREE_VALUE (arglist);
4890   fmode = TYPE_MODE (TREE_TYPE (arg));
4891   rmode = TYPE_MODE (TREE_TYPE (exp));
4892   fmt = REAL_MODE_FORMAT (fmode);
4893
4894   /* For floating point formats without a sign bit, implement signbit
4895      as "ARG < 0.0".  */
4896   if (fmt->signbit < 0)
4897   {
4898     /* But we can't do this if the format supports signed zero.  */
4899     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4900       return 0;
4901
4902     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
4903                         build_real (TREE_TYPE (arg), dconst0)));
4904     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4905   }
4906
4907   imode = int_mode_for_mode (fmode);
4908   if (imode == BLKmode)
4909     return 0;
4910
4911   bitpos = fmt->signbit;
4912   /* Handle targets with different FP word orders.  */
4913   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4914     {
4915       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4916       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4917       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4918     }
4919
4920   /* If the sign bit is not in the lowpart and the floating point format
4921      is wider than an integer, check that is twice the size of an integer
4922      so that we can use gen_highpart below.  */
4923   if (bitpos >= GET_MODE_BITSIZE (rmode)
4924       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4925     return 0;
4926
4927   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4928   temp = gen_lowpart (imode, temp);
4929
4930   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4931     {
4932       if (BYTES_BIG_ENDIAN)
4933         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
4934       temp = copy_to_mode_reg (imode, temp);
4935       temp = extract_bit_field (temp, 1, bitpos, 1,
4936                                 NULL_RTX, rmode, rmode);
4937     }
4938   else
4939     {
4940       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
4941         temp = gen_lowpart (rmode, temp);
4942       if (bitpos < HOST_BITS_PER_WIDE_INT)
4943         {
4944           hi = 0;
4945           lo = (HOST_WIDE_INT) 1 << bitpos;
4946         }
4947       else
4948         {
4949           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
4950           lo = 0;
4951         }
4952
4953       temp = force_reg (rmode, temp);
4954       temp = expand_binop (rmode, and_optab, temp,
4955                            immed_double_const (lo, hi, rmode),
4956                            target, 1, OPTAB_LIB_WIDEN);
4957     }
4958   return temp;
4959 }
4960
4961 /* Expand fork or exec calls.  TARGET is the desired target of the
4962    call.  ARGLIST is the list of arguments of the call.  FN is the
4963    identificator of the actual function.  IGNORE is nonzero if the
4964    value is to be ignored.  */
4965
4966 static rtx
4967 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
4968 {
4969   tree id, decl;
4970   tree call;
4971
4972   /* If we are not profiling, just call the function.  */
4973   if (!profile_arc_flag)
4974     return NULL_RTX;
4975
4976   /* Otherwise call the wrapper.  This should be equivalent for the rest of
4977      compiler, so the code does not diverge, and the wrapper may run the
4978      code necessary for keeping the profiling sane.  */
4979
4980   switch (DECL_FUNCTION_CODE (fn))
4981     {
4982     case BUILT_IN_FORK:
4983       id = get_identifier ("__gcov_fork");
4984       break;
4985
4986     case BUILT_IN_EXECL:
4987       id = get_identifier ("__gcov_execl");
4988       break;
4989
4990     case BUILT_IN_EXECV:
4991       id = get_identifier ("__gcov_execv");
4992       break;
4993
4994     case BUILT_IN_EXECLP:
4995       id = get_identifier ("__gcov_execlp");
4996       break;
4997
4998     case BUILT_IN_EXECLE:
4999       id = get_identifier ("__gcov_execle");
5000       break;
5001
5002     case BUILT_IN_EXECVP:
5003       id = get_identifier ("__gcov_execvp");
5004       break;
5005
5006     case BUILT_IN_EXECVE:
5007       id = get_identifier ("__gcov_execve");
5008       break;
5009
5010     default:
5011       gcc_unreachable ();
5012     }
5013
5014   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5015   DECL_EXTERNAL (decl) = 1;
5016   TREE_PUBLIC (decl) = 1;
5017   DECL_ARTIFICIAL (decl) = 1;
5018   TREE_NOTHROW (decl) = 1;
5019   call = build_function_call_expr (decl, arglist);
5020
5021   return expand_call (call, target, ignore);
5022 }
5023 \f
5024 /* Expand an expression EXP that calls a built-in function,
5025    with result going to TARGET if that's convenient
5026    (and in mode MODE if that's convenient).
5027    SUBTARGET may be used as the target for computing one of EXP's operands.
5028    IGNORE is nonzero if the value is to be ignored.  */
5029
5030 rtx
5031 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5032                 int ignore)
5033 {
5034   tree fndecl = get_callee_fndecl (exp);
5035   tree arglist = TREE_OPERAND (exp, 1);
5036   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5037   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5038
5039   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5040     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5041
5042   /* When not optimizing, generate calls to library functions for a certain
5043      set of builtins.  */
5044   if (!optimize
5045       && !CALLED_AS_BUILT_IN (fndecl)
5046       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5047       && fcode != BUILT_IN_ALLOCA)
5048     return expand_call (exp, target, ignore);
5049
5050   /* The built-in function expanders test for target == const0_rtx
5051      to determine whether the function's result will be ignored.  */
5052   if (ignore)
5053     target = const0_rtx;
5054
5055   /* If the result of a pure or const built-in function is ignored, and
5056      none of its arguments are volatile, we can avoid expanding the
5057      built-in call and just evaluate the arguments for side-effects.  */
5058   if (target == const0_rtx
5059       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5060     {
5061       bool volatilep = false;
5062       tree arg;
5063
5064       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5065         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5066           {
5067             volatilep = true;
5068             break;
5069           }
5070
5071       if (! volatilep)
5072         {
5073           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5074             expand_expr (TREE_VALUE (arg), const0_rtx,
5075                          VOIDmode, EXPAND_NORMAL);
5076           return const0_rtx;
5077         }
5078     }
5079
5080   switch (fcode)
5081     {
5082     case BUILT_IN_FABS:
5083     case BUILT_IN_FABSF:
5084     case BUILT_IN_FABSL:
5085       target = expand_builtin_fabs (arglist, target, subtarget);
5086       if (target)
5087         return target;
5088       break;
5089
5090       /* Just do a normal library call if we were unable to fold
5091          the values.  */
5092     case BUILT_IN_CABS:
5093     case BUILT_IN_CABSF:
5094     case BUILT_IN_CABSL:
5095       break;
5096
5097     case BUILT_IN_EXP:
5098     case BUILT_IN_EXPF:
5099     case BUILT_IN_EXPL:
5100     case BUILT_IN_EXP10:
5101     case BUILT_IN_EXP10F:
5102     case BUILT_IN_EXP10L:
5103     case BUILT_IN_POW10:
5104     case BUILT_IN_POW10F:
5105     case BUILT_IN_POW10L:
5106     case BUILT_IN_EXP2:
5107     case BUILT_IN_EXP2F:
5108     case BUILT_IN_EXP2L:
5109     case BUILT_IN_EXPM1:
5110     case BUILT_IN_EXPM1F:
5111     case BUILT_IN_EXPM1L:
5112     case BUILT_IN_LOGB:
5113     case BUILT_IN_LOGBF:
5114     case BUILT_IN_LOGBL:
5115     case BUILT_IN_ILOGB:
5116     case BUILT_IN_ILOGBF:
5117     case BUILT_IN_ILOGBL:
5118     case BUILT_IN_LOG:
5119     case BUILT_IN_LOGF:
5120     case BUILT_IN_LOGL:
5121     case BUILT_IN_LOG10:
5122     case BUILT_IN_LOG10F:
5123     case BUILT_IN_LOG10L:
5124     case BUILT_IN_LOG2:
5125     case BUILT_IN_LOG2F:
5126     case BUILT_IN_LOG2L:
5127     case BUILT_IN_LOG1P:
5128     case BUILT_IN_LOG1PF:
5129     case BUILT_IN_LOG1PL:
5130     case BUILT_IN_TAN:
5131     case BUILT_IN_TANF:
5132     case BUILT_IN_TANL:
5133     case BUILT_IN_ASIN:
5134     case BUILT_IN_ASINF:
5135     case BUILT_IN_ASINL:
5136     case BUILT_IN_ACOS:
5137     case BUILT_IN_ACOSF:
5138     case BUILT_IN_ACOSL:
5139     case BUILT_IN_ATAN:
5140     case BUILT_IN_ATANF:
5141     case BUILT_IN_ATANL:
5142       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5143          because of possible accuracy problems.  */
5144       if (! flag_unsafe_math_optimizations)
5145         break;
5146     case BUILT_IN_SQRT:
5147     case BUILT_IN_SQRTF:
5148     case BUILT_IN_SQRTL:
5149     case BUILT_IN_FLOOR:
5150     case BUILT_IN_FLOORF:
5151     case BUILT_IN_FLOORL:
5152     case BUILT_IN_CEIL:
5153     case BUILT_IN_CEILF:
5154     case BUILT_IN_CEILL:
5155     case BUILT_IN_TRUNC:
5156     case BUILT_IN_TRUNCF:
5157     case BUILT_IN_TRUNCL:
5158     case BUILT_IN_ROUND:
5159     case BUILT_IN_ROUNDF:
5160     case BUILT_IN_ROUNDL:
5161     case BUILT_IN_NEARBYINT:
5162     case BUILT_IN_NEARBYINTF:
5163     case BUILT_IN_NEARBYINTL:
5164     case BUILT_IN_RINT:
5165     case BUILT_IN_RINTF:
5166     case BUILT_IN_RINTL:
5167       target = expand_builtin_mathfn (exp, target, subtarget);
5168       if (target)
5169         return target;
5170       break;
5171
5172     case BUILT_IN_POW:
5173     case BUILT_IN_POWF:
5174     case BUILT_IN_POWL:
5175       target = expand_builtin_pow (exp, target, subtarget);
5176       if (target)
5177         return target;
5178       break;
5179
5180     case BUILT_IN_ATAN2:
5181     case BUILT_IN_ATAN2F:
5182     case BUILT_IN_ATAN2L:
5183     case BUILT_IN_FMOD:
5184     case BUILT_IN_FMODF:
5185     case BUILT_IN_FMODL:
5186     case BUILT_IN_DREM:
5187     case BUILT_IN_DREMF:
5188     case BUILT_IN_DREML:
5189       if (! flag_unsafe_math_optimizations)
5190         break;
5191       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5192       if (target)
5193         return target;
5194       break;
5195
5196     case BUILT_IN_SIN:
5197     case BUILT_IN_SINF:
5198     case BUILT_IN_SINL:
5199     case BUILT_IN_COS:
5200     case BUILT_IN_COSF:
5201     case BUILT_IN_COSL:
5202       if (! flag_unsafe_math_optimizations)
5203         break;
5204       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5205       if (target)
5206         return target;
5207       break;
5208
5209     case BUILT_IN_APPLY_ARGS:
5210       return expand_builtin_apply_args ();
5211
5212       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5213          FUNCTION with a copy of the parameters described by
5214          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5215          allocated on the stack into which is stored all the registers
5216          that might possibly be used for returning the result of a
5217          function.  ARGUMENTS is the value returned by
5218          __builtin_apply_args.  ARGSIZE is the number of bytes of
5219          arguments that must be copied.  ??? How should this value be
5220          computed?  We'll also need a safe worst case value for varargs
5221          functions.  */
5222     case BUILT_IN_APPLY:
5223       if (!validate_arglist (arglist, POINTER_TYPE,
5224                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5225           && !validate_arglist (arglist, REFERENCE_TYPE,
5226                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5227         return const0_rtx;
5228       else
5229         {
5230           int i;
5231           tree t;
5232           rtx ops[3];
5233
5234           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5235             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5236
5237           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5238         }
5239
5240       /* __builtin_return (RESULT) causes the function to return the
5241          value described by RESULT.  RESULT is address of the block of
5242          memory returned by __builtin_apply.  */
5243     case BUILT_IN_RETURN:
5244       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5245         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5246                                             NULL_RTX, VOIDmode, 0));
5247       return const0_rtx;
5248
5249     case BUILT_IN_SAVEREGS:
5250       return expand_builtin_saveregs ();
5251
5252     case BUILT_IN_ARGS_INFO:
5253       return expand_builtin_args_info (arglist);
5254
5255       /* Return the address of the first anonymous stack arg.  */
5256     case BUILT_IN_NEXT_ARG:
5257       if (fold_builtin_next_arg (arglist))
5258         return const0_rtx;
5259       return expand_builtin_next_arg (arglist);
5260
5261     case BUILT_IN_CLASSIFY_TYPE:
5262       return expand_builtin_classify_type (arglist);
5263
5264     case BUILT_IN_CONSTANT_P:
5265       return const0_rtx;
5266
5267     case BUILT_IN_FRAME_ADDRESS:
5268     case BUILT_IN_RETURN_ADDRESS:
5269       return expand_builtin_frame_address (fndecl, arglist);
5270
5271     /* Returns the address of the area where the structure is returned.
5272        0 otherwise.  */
5273     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5274       if (arglist != 0
5275           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5276           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5277         return const0_rtx;
5278       else
5279         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5280
5281     case BUILT_IN_ALLOCA:
5282       target = expand_builtin_alloca (arglist, target);
5283       if (target)
5284         return target;
5285       break;
5286
5287     case BUILT_IN_STACK_SAVE:
5288       return expand_stack_save ();
5289
5290     case BUILT_IN_STACK_RESTORE:
5291       expand_stack_restore (TREE_VALUE (arglist));
5292       return const0_rtx;
5293
5294     case BUILT_IN_FFS:
5295     case BUILT_IN_FFSL:
5296     case BUILT_IN_FFSLL:
5297     case BUILT_IN_FFSIMAX:
5298       target = expand_builtin_unop (target_mode, arglist, target,
5299                                     subtarget, ffs_optab);
5300       if (target)
5301         return target;
5302       break;
5303
5304     case BUILT_IN_CLZ:
5305     case BUILT_IN_CLZL:
5306     case BUILT_IN_CLZLL:
5307     case BUILT_IN_CLZIMAX:
5308       target = expand_builtin_unop (target_mode, arglist, target,
5309                                     subtarget, clz_optab);
5310       if (target)
5311         return target;
5312       break;
5313
5314     case BUILT_IN_CTZ:
5315     case BUILT_IN_CTZL:
5316     case BUILT_IN_CTZLL:
5317     case BUILT_IN_CTZIMAX:
5318       target = expand_builtin_unop (target_mode, arglist, target,
5319                                     subtarget, ctz_optab);
5320       if (target)
5321         return target;
5322       break;
5323
5324     case BUILT_IN_POPCOUNT:
5325     case BUILT_IN_POPCOUNTL:
5326     case BUILT_IN_POPCOUNTLL:
5327     case BUILT_IN_POPCOUNTIMAX:
5328       target = expand_builtin_unop (target_mode, arglist, target,
5329                                     subtarget, popcount_optab);
5330       if (target)
5331         return target;
5332       break;
5333
5334     case BUILT_IN_PARITY:
5335     case BUILT_IN_PARITYL:
5336     case BUILT_IN_PARITYLL:
5337     case BUILT_IN_PARITYIMAX:
5338       target = expand_builtin_unop (target_mode, arglist, target,
5339                                     subtarget, parity_optab);
5340       if (target)
5341         return target;
5342       break;
5343
5344     case BUILT_IN_STRLEN:
5345       target = expand_builtin_strlen (arglist, target, target_mode);
5346       if (target)
5347         return target;
5348       break;
5349
5350     case BUILT_IN_STRCPY:
5351       target = expand_builtin_strcpy (exp, target, mode);
5352       if (target)
5353         return target;
5354       break;
5355
5356     case BUILT_IN_STRNCPY:
5357       target = expand_builtin_strncpy (exp, target, mode);
5358       if (target)
5359         return target;
5360       break;
5361
5362     case BUILT_IN_STPCPY:
5363       target = expand_builtin_stpcpy (exp, target, mode);
5364       if (target)
5365         return target;
5366       break;
5367
5368     case BUILT_IN_STRCAT:
5369       target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
5370       if (target)
5371         return target;
5372       break;
5373
5374     case BUILT_IN_STRNCAT:
5375       target = expand_builtin_strncat (arglist, target, mode);
5376       if (target)
5377         return target;
5378       break;
5379
5380     case BUILT_IN_STRSPN:
5381       target = expand_builtin_strspn (arglist, target, mode);
5382       if (target)
5383         return target;
5384       break;
5385
5386     case BUILT_IN_STRCSPN:
5387       target = expand_builtin_strcspn (arglist, target, mode);
5388       if (target)
5389         return target;
5390       break;
5391
5392     case BUILT_IN_STRSTR:
5393       target = expand_builtin_strstr (arglist, target, mode);
5394       if (target)
5395         return target;
5396       break;
5397
5398     case BUILT_IN_STRPBRK:
5399       target = expand_builtin_strpbrk (arglist, target, mode);
5400       if (target)
5401         return target;
5402       break;
5403
5404     case BUILT_IN_INDEX:
5405     case BUILT_IN_STRCHR:
5406       target = expand_builtin_strchr (arglist, target, mode);
5407       if (target)
5408         return target;
5409       break;
5410
5411     case BUILT_IN_RINDEX:
5412     case BUILT_IN_STRRCHR:
5413       target = expand_builtin_strrchr (arglist, target, mode);
5414       if (target)
5415         return target;
5416       break;
5417
5418     case BUILT_IN_MEMCPY:
5419       target = expand_builtin_memcpy (exp, target, mode);
5420       if (target)
5421         return target;
5422       break;
5423
5424     case BUILT_IN_MEMPCPY:
5425       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5426       if (target)
5427         return target;
5428       break;
5429
5430     case BUILT_IN_MEMMOVE:
5431       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5432       if (target)
5433         return target;
5434       break;
5435
5436     case BUILT_IN_BCOPY:
5437       target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5438       if (target)
5439         return target;
5440       break;
5441
5442     case BUILT_IN_MEMSET:
5443       target = expand_builtin_memset (arglist, target, mode);
5444       if (target)
5445         return target;
5446       break;
5447
5448     case BUILT_IN_BZERO:
5449       target = expand_builtin_bzero (arglist);
5450       if (target)
5451         return target;
5452       break;
5453
5454     case BUILT_IN_STRCMP:
5455       target = expand_builtin_strcmp (exp, target, mode);
5456       if (target)
5457         return target;
5458       break;
5459
5460     case BUILT_IN_STRNCMP:
5461       target = expand_builtin_strncmp (exp, target, mode);
5462       if (target)
5463         return target;
5464       break;
5465
5466     case BUILT_IN_BCMP:
5467     case BUILT_IN_MEMCMP:
5468       target = expand_builtin_memcmp (exp, arglist, target, mode);
5469       if (target)
5470         return target;
5471       break;
5472
5473     case BUILT_IN_SETJMP:
5474       target = expand_builtin_setjmp (arglist, target);
5475       if (target)
5476         return target;
5477       break;
5478
5479       /* __builtin_longjmp is passed a pointer to an array of five words.
5480          It's similar to the C library longjmp function but works with
5481          __builtin_setjmp above.  */
5482     case BUILT_IN_LONGJMP:
5483       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5484         break;
5485       else
5486         {
5487           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5488                                       VOIDmode, 0);
5489           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5490                                    NULL_RTX, VOIDmode, 0);
5491
5492           if (value != const1_rtx)
5493             {
5494               error ("%<__builtin_longjmp%> second argument must be 1");
5495               return const0_rtx;
5496             }
5497
5498           expand_builtin_longjmp (buf_addr, value);
5499           return const0_rtx;
5500         }
5501
5502     case BUILT_IN_NONLOCAL_GOTO:
5503       target = expand_builtin_nonlocal_goto (arglist);
5504       if (target)
5505         return target;
5506       break;
5507
5508       /* This updates the setjmp buffer that is its argument with the value
5509          of the current stack pointer.  */
5510     case BUILT_IN_UPDATE_SETJMP_BUF:
5511       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5512         {
5513           rtx buf_addr
5514             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5515
5516           expand_builtin_update_setjmp_buf (buf_addr);
5517           return const0_rtx;
5518         }
5519       break;
5520
5521     case BUILT_IN_TRAP:
5522       expand_builtin_trap ();
5523       return const0_rtx;
5524
5525     case BUILT_IN_PRINTF:
5526       target = expand_builtin_printf (arglist, target, mode, false);
5527       if (target)
5528         return target;
5529       break;
5530
5531     case BUILT_IN_PRINTF_UNLOCKED:
5532       target = expand_builtin_printf (arglist, target, mode, true);
5533       if (target)
5534         return target;
5535       break;
5536
5537     case BUILT_IN_FPUTS:
5538       target = expand_builtin_fputs (arglist, target, false);
5539       if (target)
5540         return target;
5541       break;
5542     case BUILT_IN_FPUTS_UNLOCKED:
5543       target = expand_builtin_fputs (arglist, target, true);
5544       if (target)
5545         return target;
5546       break;
5547
5548     case BUILT_IN_FPRINTF:
5549       target = expand_builtin_fprintf (arglist, target, mode, false);
5550       if (target)
5551         return target;
5552       break;
5553
5554     case BUILT_IN_FPRINTF_UNLOCKED:
5555       target = expand_builtin_fprintf (arglist, target, mode, true);
5556       if (target)
5557         return target;
5558       break;
5559
5560     case BUILT_IN_SPRINTF:
5561       target = expand_builtin_sprintf (arglist, target, mode);
5562       if (target)
5563         return target;
5564       break;
5565
5566     case BUILT_IN_SIGNBIT:
5567     case BUILT_IN_SIGNBITF:
5568     case BUILT_IN_SIGNBITL:
5569       target = expand_builtin_signbit (exp, target);
5570       if (target)
5571         return target;
5572       break;
5573
5574       /* Various hooks for the DWARF 2 __throw routine.  */
5575     case BUILT_IN_UNWIND_INIT:
5576       expand_builtin_unwind_init ();
5577       return const0_rtx;
5578     case BUILT_IN_DWARF_CFA:
5579       return virtual_cfa_rtx;
5580 #ifdef DWARF2_UNWIND_INFO
5581     case BUILT_IN_DWARF_SP_COLUMN:
5582       return expand_builtin_dwarf_sp_column ();
5583     case BUILT_IN_INIT_DWARF_REG_SIZES:
5584       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5585       return const0_rtx;
5586 #endif
5587     case BUILT_IN_FROB_RETURN_ADDR:
5588       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5589     case BUILT_IN_EXTRACT_RETURN_ADDR:
5590       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5591     case BUILT_IN_EH_RETURN:
5592       expand_builtin_eh_return (TREE_VALUE (arglist),
5593                                 TREE_VALUE (TREE_CHAIN (arglist)));
5594       return const0_rtx;
5595 #ifdef EH_RETURN_DATA_REGNO
5596     case BUILT_IN_EH_RETURN_DATA_REGNO:
5597       return expand_builtin_eh_return_data_regno (arglist);
5598 #endif
5599     case BUILT_IN_EXTEND_POINTER:
5600       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5601
5602     case BUILT_IN_VA_START:
5603     case BUILT_IN_STDARG_START:
5604       return expand_builtin_va_start (arglist);
5605     case BUILT_IN_VA_END:
5606       return expand_builtin_va_end (arglist);
5607     case BUILT_IN_VA_COPY:
5608       return expand_builtin_va_copy (arglist);
5609     case BUILT_IN_EXPECT:
5610       return expand_builtin_expect (arglist, target);
5611     case BUILT_IN_PREFETCH:
5612       expand_builtin_prefetch (arglist);
5613       return const0_rtx;
5614
5615     case BUILT_IN_PROFILE_FUNC_ENTER:
5616       return expand_builtin_profile_func (false);
5617     case BUILT_IN_PROFILE_FUNC_EXIT:
5618       return expand_builtin_profile_func (true);
5619
5620     case BUILT_IN_INIT_TRAMPOLINE:
5621       return expand_builtin_init_trampoline (arglist);
5622     case BUILT_IN_ADJUST_TRAMPOLINE:
5623       return expand_builtin_adjust_trampoline (arglist);
5624
5625     case BUILT_IN_FORK:
5626     case BUILT_IN_EXECL:
5627     case BUILT_IN_EXECV:
5628     case BUILT_IN_EXECLP:
5629     case BUILT_IN_EXECLE:
5630     case BUILT_IN_EXECVP:
5631     case BUILT_IN_EXECVE:
5632       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5633       if (target)
5634         return target;
5635       break;
5636
5637     default:    /* just do library call, if unknown builtin */
5638       break;
5639     }
5640
5641   /* The switch statement above can drop through to cause the function
5642      to be called normally.  */
5643   return expand_call (exp, target, ignore);
5644 }
5645
5646 /* Determine whether a tree node represents a call to a built-in
5647    function.  If the tree T is a call to a built-in function with
5648    the right number of arguments of the appropriate types, return
5649    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5650    Otherwise the return value is END_BUILTINS.  */
5651
5652 enum built_in_function
5653 builtin_mathfn_code (tree t)
5654 {
5655   tree fndecl, arglist, parmlist;
5656   tree argtype, parmtype;
5657
5658   if (TREE_CODE (t) != CALL_EXPR
5659       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5660     return END_BUILTINS;
5661
5662   fndecl = get_callee_fndecl (t);
5663   if (fndecl == NULL_TREE
5664       || TREE_CODE (fndecl) != FUNCTION_DECL
5665       || ! DECL_BUILT_IN (fndecl)
5666       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5667     return END_BUILTINS;
5668
5669   arglist = TREE_OPERAND (t, 1);
5670   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5671   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5672     {
5673       /* If a function doesn't take a variable number of arguments,
5674          the last element in the list will have type `void'.  */
5675       parmtype = TREE_VALUE (parmlist);
5676       if (VOID_TYPE_P (parmtype))
5677         {
5678           if (arglist)
5679             return END_BUILTINS;
5680           return DECL_FUNCTION_CODE (fndecl);
5681         }
5682
5683       if (! arglist)
5684         return END_BUILTINS;
5685
5686       argtype = TREE_TYPE (TREE_VALUE (arglist));
5687
5688       if (SCALAR_FLOAT_TYPE_P (parmtype))
5689         {
5690           if (! SCALAR_FLOAT_TYPE_P (argtype))
5691             return END_BUILTINS;
5692         }
5693       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5694         {
5695           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5696             return END_BUILTINS;
5697         }
5698       else if (POINTER_TYPE_P (parmtype))
5699         {
5700           if (! POINTER_TYPE_P (argtype))
5701             return END_BUILTINS;
5702         }
5703       else if (INTEGRAL_TYPE_P (parmtype))
5704         {
5705           if (! INTEGRAL_TYPE_P (argtype))
5706             return END_BUILTINS;
5707         }
5708       else
5709         return END_BUILTINS;
5710
5711       arglist = TREE_CHAIN (arglist);
5712     }
5713
5714   /* Variable-length argument list.  */
5715   return DECL_FUNCTION_CODE (fndecl);
5716 }
5717
5718 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5719    constant.  ARGLIST is the argument list of the call.  */
5720
5721 static tree
5722 fold_builtin_constant_p (tree arglist)
5723 {
5724   if (arglist == 0)
5725     return 0;
5726
5727   arglist = TREE_VALUE (arglist);
5728
5729   /* We return 1 for a numeric type that's known to be a constant
5730      value at compile-time or for an aggregate type that's a
5731      literal constant.  */
5732   STRIP_NOPS (arglist);
5733
5734   /* If we know this is a constant, emit the constant of one.  */
5735   if (CONSTANT_CLASS_P (arglist)
5736       || (TREE_CODE (arglist) == CONSTRUCTOR
5737           && TREE_CONSTANT (arglist))
5738       || (TREE_CODE (arglist) == ADDR_EXPR
5739           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5740     return integer_one_node;
5741
5742   /* If this expression has side effects, show we don't know it to be a
5743      constant.  Likewise if it's a pointer or aggregate type since in
5744      those case we only want literals, since those are only optimized
5745      when generating RTL, not later.
5746      And finally, if we are compiling an initializer, not code, we
5747      need to return a definite result now; there's not going to be any
5748      more optimization done.  */
5749   if (TREE_SIDE_EFFECTS (arglist)
5750       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5751       || POINTER_TYPE_P (TREE_TYPE (arglist))
5752       || cfun == 0)
5753     return integer_zero_node;
5754
5755   return 0;
5756 }
5757
5758 /* Fold a call to __builtin_expect, if we expect that a comparison against
5759    the argument will fold to a constant.  In practice, this means a true
5760    constant or the address of a non-weak symbol.  ARGLIST is the argument
5761    list of the call.  */
5762
5763 static tree
5764 fold_builtin_expect (tree arglist)
5765 {
5766   tree arg, inner;
5767
5768   if (arglist == 0)
5769     return 0;
5770
5771   arg = TREE_VALUE (arglist);
5772
5773   /* If the argument isn't invariant, then there's nothing we can do.  */
5774   if (!TREE_INVARIANT (arg))
5775     return 0;
5776
5777   /* If we're looking at an address of a weak decl, then do not fold.  */
5778   inner = arg;
5779   STRIP_NOPS (inner);
5780   if (TREE_CODE (inner) == ADDR_EXPR)
5781     {
5782       do
5783         {
5784           inner = TREE_OPERAND (inner, 0);
5785         }
5786       while (TREE_CODE (inner) == COMPONENT_REF
5787              || TREE_CODE (inner) == ARRAY_REF);
5788       if (DECL_P (inner) && DECL_WEAK (inner))
5789         return 0;
5790     }
5791
5792   /* Otherwise, ARG already has the proper type for the return value.  */
5793   return arg;
5794 }
5795
5796 /* Fold a call to __builtin_classify_type.  */
5797
5798 static tree
5799 fold_builtin_classify_type (tree arglist)
5800 {
5801   if (arglist == 0)
5802     return build_int_cst (NULL_TREE, no_type_class);
5803
5804   return build_int_cst (NULL_TREE,
5805                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
5806 }
5807
5808 /* Fold a call to __builtin_strlen.  */
5809
5810 static tree
5811 fold_builtin_strlen (tree arglist)
5812 {
5813   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5814     return NULL_TREE;
5815   else
5816     {
5817       tree len = c_strlen (TREE_VALUE (arglist), 0);
5818
5819       if (len)
5820         {
5821           /* Convert from the internal "sizetype" type to "size_t".  */
5822           if (size_type_node)
5823             len = fold_convert (size_type_node, len);
5824           return len;
5825         }
5826
5827       return NULL_TREE;
5828     }
5829 }
5830
5831 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5832
5833 static tree
5834 fold_builtin_inf (tree type, int warn)
5835 {
5836   REAL_VALUE_TYPE real;
5837
5838   /* __builtin_inff is intended to be usable to define INFINITY on all
5839      targets.  If an infinity is not available, INFINITY expands "to a
5840      positive constant of type float that overflows at translation
5841      time", footnote "In this case, using INFINITY will violate the
5842      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
5843      Thus we pedwarn to ensure this constraint violation is
5844      diagnosed.  */
5845   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5846     pedwarn ("target format does not support infinity");
5847
5848   real_inf (&real);
5849   return build_real (type, real);
5850 }
5851
5852 /* Fold a call to __builtin_nan or __builtin_nans.  */
5853
5854 static tree
5855 fold_builtin_nan (tree arglist, tree type, int quiet)
5856 {
5857   REAL_VALUE_TYPE real;
5858   const char *str;
5859
5860   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5861     return 0;
5862   str = c_getstr (TREE_VALUE (arglist));
5863   if (!str)
5864     return 0;
5865
5866   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5867     return 0;
5868
5869   return build_real (type, real);
5870 }
5871
5872 /* Return true if the floating point expression T has an integer value.
5873    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5874
5875 static bool
5876 integer_valued_real_p (tree t)
5877 {
5878   switch (TREE_CODE (t))
5879     {
5880     case FLOAT_EXPR:
5881       return true;
5882
5883     case ABS_EXPR:
5884     case SAVE_EXPR:
5885     case NON_LVALUE_EXPR:
5886       return integer_valued_real_p (TREE_OPERAND (t, 0));
5887
5888     case COMPOUND_EXPR:
5889     case MODIFY_EXPR:
5890     case BIND_EXPR:
5891       return integer_valued_real_p (TREE_OPERAND (t, 1));
5892
5893     case PLUS_EXPR:
5894     case MINUS_EXPR:
5895     case MULT_EXPR:
5896     case MIN_EXPR:
5897     case MAX_EXPR:
5898       return integer_valued_real_p (TREE_OPERAND (t, 0))
5899              && integer_valued_real_p (TREE_OPERAND (t, 1));
5900
5901     case COND_EXPR:
5902       return integer_valued_real_p (TREE_OPERAND (t, 1))
5903              && integer_valued_real_p (TREE_OPERAND (t, 2));
5904
5905     case REAL_CST:
5906       if (! TREE_CONSTANT_OVERFLOW (t))
5907       {
5908         REAL_VALUE_TYPE c, cint;
5909
5910         c = TREE_REAL_CST (t);
5911         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5912         return real_identical (&c, &cint);
5913       }
5914
5915     case NOP_EXPR:
5916       {
5917         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5918         if (TREE_CODE (type) == INTEGER_TYPE)
5919           return true;
5920         if (TREE_CODE (type) == REAL_TYPE)
5921           return integer_valued_real_p (TREE_OPERAND (t, 0));
5922         break;
5923       }
5924
5925     case CALL_EXPR:
5926       switch (builtin_mathfn_code (t))
5927         {
5928         case BUILT_IN_CEIL:
5929         case BUILT_IN_CEILF:
5930         case BUILT_IN_CEILL:
5931         case BUILT_IN_FLOOR:
5932         case BUILT_IN_FLOORF:
5933         case BUILT_IN_FLOORL:
5934         case BUILT_IN_NEARBYINT:
5935         case BUILT_IN_NEARBYINTF:
5936         case BUILT_IN_NEARBYINTL:
5937         case BUILT_IN_RINT:
5938         case BUILT_IN_RINTF:
5939         case BUILT_IN_RINTL:
5940         case BUILT_IN_ROUND:
5941         case BUILT_IN_ROUNDF:
5942         case BUILT_IN_ROUNDL:
5943         case BUILT_IN_TRUNC:
5944         case BUILT_IN_TRUNCF:
5945         case BUILT_IN_TRUNCL:
5946           return true;
5947
5948         default:
5949           break;
5950         }
5951       break;
5952
5953     default:
5954       break;
5955     }
5956   return false;
5957 }
5958
5959 /* EXP is assumed to be builtin call where truncation can be propagated
5960    across (for instance floor((double)f) == (double)floorf (f).
5961    Do the transformation.  */
5962
5963 static tree
5964 fold_trunc_transparent_mathfn (tree exp)
5965 {
5966   tree fndecl = get_callee_fndecl (exp);
5967   tree arglist = TREE_OPERAND (exp, 1);
5968   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5969   tree arg;
5970
5971   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5972     return 0;
5973
5974   arg = TREE_VALUE (arglist);
5975   /* Integer rounding functions are idempotent.  */
5976   if (fcode == builtin_mathfn_code (arg))
5977     return arg;
5978
5979   /* If argument is already integer valued, and we don't need to worry
5980      about setting errno, there's no need to perform rounding.  */
5981   if (! flag_errno_math && integer_valued_real_p (arg))
5982     return arg;
5983
5984   if (optimize)
5985     {
5986       tree arg0 = strip_float_extensions (arg);
5987       tree ftype = TREE_TYPE (exp);
5988       tree newtype = TREE_TYPE (arg0);
5989       tree decl;
5990
5991       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5992           && (decl = mathfn_built_in (newtype, fcode)))
5993         {
5994           arglist =
5995             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
5996           return fold_convert (ftype,
5997                                build_function_call_expr (decl, arglist));
5998         }
5999     }
6000   return 0;
6001 }
6002
6003 /* EXP is assumed to be builtin call which can narrow the FP type of
6004    the argument, for instance lround((double)f) -> lroundf (f).  */
6005
6006 static tree
6007 fold_fixed_mathfn (tree exp)
6008 {
6009   tree fndecl = get_callee_fndecl (exp);
6010   tree arglist = TREE_OPERAND (exp, 1);
6011   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6012   tree arg;
6013
6014   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6015     return 0;
6016
6017   arg = TREE_VALUE (arglist);
6018
6019   /* If argument is already integer valued, and we don't need to worry
6020      about setting errno, there's no need to perform rounding.  */
6021   if (! flag_errno_math && integer_valued_real_p (arg))
6022     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6023
6024   if (optimize)
6025     {
6026       tree ftype = TREE_TYPE (arg);
6027       tree arg0 = strip_float_extensions (arg);
6028       tree newtype = TREE_TYPE (arg0);
6029       tree decl;
6030
6031       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6032           && (decl = mathfn_built_in (newtype, fcode)))
6033         {
6034           arglist =
6035             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6036           return build_function_call_expr (decl, arglist);
6037         }
6038     }
6039   return 0;
6040 }
6041
6042 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6043    is the argument list and TYPE is the return type.  Return
6044    NULL_TREE if no if no simplification can be made.  */
6045
6046 static tree
6047 fold_builtin_cabs (tree arglist, tree type)
6048 {
6049   tree arg;
6050
6051   if (!arglist || TREE_CHAIN (arglist))
6052     return NULL_TREE;
6053
6054   arg = TREE_VALUE (arglist);
6055   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6056       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6057     return NULL_TREE;
6058
6059   /* Evaluate cabs of a constant at compile-time.  */
6060   if (flag_unsafe_math_optimizations
6061       && TREE_CODE (arg) == COMPLEX_CST
6062       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6063       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6064       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6065       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6066     {
6067       REAL_VALUE_TYPE r, i;
6068
6069       r = TREE_REAL_CST (TREE_REALPART (arg));
6070       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6071
6072       real_arithmetic (&r, MULT_EXPR, &r, &r);
6073       real_arithmetic (&i, MULT_EXPR, &i, &i);
6074       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6075       if (real_sqrt (&r, TYPE_MODE (type), &r)
6076           || ! flag_trapping_math)
6077         return build_real (type, r);
6078     }
6079
6080   /* If either part is zero, cabs is fabs of the other.  */
6081   if (TREE_CODE (arg) == COMPLEX_EXPR
6082       && real_zerop (TREE_OPERAND (arg, 0)))
6083     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6084   if (TREE_CODE (arg) == COMPLEX_EXPR
6085       && real_zerop (TREE_OPERAND (arg, 1)))
6086     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6087
6088   /* Don't do this when optimizing for size.  */
6089   if (flag_unsafe_math_optimizations
6090       && optimize && !optimize_size)
6091     {
6092       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6093
6094       if (sqrtfn != NULL_TREE)
6095         {
6096           tree rpart, ipart, result, arglist;
6097
6098           arg = builtin_save_expr (arg);
6099
6100           rpart = fold (build1 (REALPART_EXPR, type, arg));
6101           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6102
6103           rpart = builtin_save_expr (rpart);
6104           ipart = builtin_save_expr (ipart);
6105
6106           result = fold (build2 (PLUS_EXPR, type,
6107                                  fold (build2 (MULT_EXPR, type,
6108                                                rpart, rpart)),
6109                                  fold (build2 (MULT_EXPR, type,
6110                                                ipart, ipart))));
6111
6112           arglist = build_tree_list (NULL_TREE, result);
6113           return build_function_call_expr (sqrtfn, arglist);
6114         }
6115     }
6116
6117   return NULL_TREE;
6118 }
6119
6120 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6121    NULL_TREE if no simplification can be made.  */
6122
6123 static tree
6124 fold_builtin_sqrt (tree arglist, tree type)
6125 {
6126
6127   enum built_in_function fcode;
6128   tree arg = TREE_VALUE (arglist);
6129
6130   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6131     return NULL_TREE;
6132
6133   /* Optimize sqrt of constant value.  */
6134   if (TREE_CODE (arg) == REAL_CST
6135       && ! TREE_CONSTANT_OVERFLOW (arg))
6136     {
6137       REAL_VALUE_TYPE r, x;
6138
6139       x = TREE_REAL_CST (arg);
6140       if (real_sqrt (&r, TYPE_MODE (type), &x)
6141           || (!flag_trapping_math && !flag_errno_math))
6142         return build_real (type, r);
6143     }
6144
6145   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6146   fcode = builtin_mathfn_code (arg);
6147   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6148     {
6149       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6150       arg = fold (build2 (MULT_EXPR, type,
6151                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6152                           build_real (type, dconsthalf)));
6153       arglist = build_tree_list (NULL_TREE, arg);
6154       return build_function_call_expr (expfn, arglist);
6155     }
6156
6157   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6158   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6159     {
6160       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6161
6162       if (powfn)
6163         {
6164           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6165           tree tree_root;
6166           /* The inner root was either sqrt or cbrt.  */
6167           REAL_VALUE_TYPE dconstroot =
6168             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6169
6170           /* Adjust for the outer root.  */
6171           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6172           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6173           tree_root = build_real (type, dconstroot);
6174           arglist = tree_cons (NULL_TREE, arg0,
6175                                build_tree_list (NULL_TREE, tree_root));
6176           return build_function_call_expr (powfn, arglist);
6177         }
6178     }
6179
6180   /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6181   if (flag_unsafe_math_optimizations
6182       && (fcode == BUILT_IN_POW
6183           || fcode == BUILT_IN_POWF
6184           || fcode == BUILT_IN_POWL))
6185     {
6186       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6187       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6188       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6189       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6190                                  build_real (type, dconsthalf)));
6191       arglist = tree_cons (NULL_TREE, arg0,
6192                            build_tree_list (NULL_TREE, narg1));
6193       return build_function_call_expr (powfn, arglist);
6194     }
6195
6196   return NULL_TREE;
6197 }
6198
6199 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6200    NULL_TREE if no simplification can be made.  */
6201 static tree
6202 fold_builtin_cbrt (tree arglist, tree type)
6203 {
6204   tree arg = TREE_VALUE (arglist);
6205   const enum built_in_function fcode = builtin_mathfn_code (arg);
6206
6207   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6208     return NULL_TREE;
6209
6210   /* Optimize cbrt of constant value.  */
6211   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6212     return arg;
6213
6214   /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6215   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6216     {
6217       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6218       const REAL_VALUE_TYPE third_trunc =
6219         real_value_truncate (TYPE_MODE (type), dconstthird);
6220       arg = fold (build2 (MULT_EXPR, type,
6221                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6222                           build_real (type, third_trunc)));
6223       arglist = build_tree_list (NULL_TREE, arg);
6224       return build_function_call_expr (expfn, arglist);
6225     }
6226
6227   /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6228   /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6229      x is negative pow will error but cbrt won't.  */
6230   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6231     {
6232       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6233
6234       if (powfn)
6235         {
6236           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6237           tree tree_root;
6238           REAL_VALUE_TYPE dconstroot = dconstthird;
6239
6240           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6241           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6242           tree_root = build_real (type, dconstroot);
6243           arglist = tree_cons (NULL_TREE, arg0,
6244                                build_tree_list (NULL_TREE, tree_root));
6245           return build_function_call_expr (powfn, arglist);
6246         }
6247
6248     }
6249   return NULL_TREE;
6250 }
6251
6252 /* Fold function call to builtin sin, sinf, or sinl.  Return
6253    NULL_TREE if no simplification can be made.  */
6254 static tree
6255 fold_builtin_sin (tree arglist)
6256 {
6257   tree arg = TREE_VALUE (arglist);
6258
6259   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6260     return NULL_TREE;
6261
6262   /* Optimize sin (0.0) = 0.0.  */
6263   if (real_zerop (arg))
6264     return arg;
6265
6266   return NULL_TREE;
6267 }
6268
6269 /* Fold function call to builtin cos, cosf, or cosl.  Return
6270    NULL_TREE if no simplification can be made.  */
6271 static tree
6272 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6273 {
6274   tree arg = TREE_VALUE (arglist);
6275
6276   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6277     return NULL_TREE;
6278
6279   /* Optimize cos (0.0) = 1.0.  */
6280   if (real_zerop (arg))
6281     return build_real (type, dconst1);
6282
6283   /* Optimize cos(-x) into cos (x).  */
6284   if (TREE_CODE (arg) == NEGATE_EXPR)
6285     {
6286       tree args = build_tree_list (NULL_TREE,
6287                                    TREE_OPERAND (arg, 0));
6288       return build_function_call_expr (fndecl, args);
6289     }
6290
6291   return NULL_TREE;
6292 }
6293
6294 /* Fold function call to builtin tan, tanf, or tanl.  Return
6295    NULL_TREE if no simplification can be made.  */
6296 static tree
6297 fold_builtin_tan (tree arglist)
6298 {
6299   enum built_in_function fcode;
6300   tree arg = TREE_VALUE (arglist);
6301
6302   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6303     return NULL_TREE;
6304
6305   /* Optimize tan(0.0) = 0.0.  */
6306   if (real_zerop (arg))
6307     return arg;
6308
6309   /* Optimize tan(atan(x)) = x.  */
6310   fcode = builtin_mathfn_code (arg);
6311   if (flag_unsafe_math_optimizations
6312       && (fcode == BUILT_IN_ATAN
6313           || fcode == BUILT_IN_ATANF
6314           || fcode == BUILT_IN_ATANL))
6315     return TREE_VALUE (TREE_OPERAND (arg, 1));
6316
6317   return NULL_TREE;
6318 }
6319
6320 /* Fold function call to builtin atan, atanf, or atanl.  Return
6321    NULL_TREE if no simplification can be made.  */
6322
6323 static tree
6324 fold_builtin_atan (tree arglist, tree type)
6325 {
6326
6327   tree arg = TREE_VALUE (arglist);
6328
6329   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6330     return NULL_TREE;
6331
6332   /* Optimize atan(0.0) = 0.0.  */
6333   if (real_zerop (arg))
6334     return arg;
6335
6336   /* Optimize atan(1.0) = pi/4.  */
6337   if (real_onep (arg))
6338     {
6339       REAL_VALUE_TYPE cst;
6340
6341       real_convert (&cst, TYPE_MODE (type), &dconstpi);
6342       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6343       return build_real (type, cst);
6344     }
6345
6346   return NULL_TREE;
6347 }
6348
6349 /* Fold function call to builtin trunc, truncf or truncl.  Return
6350    NULL_TREE if no simplification can be made.  */
6351
6352 static tree
6353 fold_builtin_trunc (tree exp)
6354 {
6355   tree arglist = TREE_OPERAND (exp, 1);
6356   tree arg;
6357
6358   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6359     return 0;
6360
6361   /* Optimize trunc of constant value.  */
6362   arg = TREE_VALUE (arglist);
6363   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6364     {
6365       REAL_VALUE_TYPE r, x;
6366       tree type = TREE_TYPE (exp);
6367
6368       x = TREE_REAL_CST (arg);
6369       real_trunc (&r, TYPE_MODE (type), &x);
6370       return build_real (type, r);
6371     }
6372
6373   return fold_trunc_transparent_mathfn (exp);
6374 }
6375
6376 /* Fold function call to builtin floor, floorf or floorl.  Return
6377    NULL_TREE if no simplification can be made.  */
6378
6379 static tree
6380 fold_builtin_floor (tree exp)
6381 {
6382   tree arglist = TREE_OPERAND (exp, 1);
6383   tree arg;
6384
6385   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6386     return 0;
6387
6388   /* Optimize floor of constant value.  */
6389   arg = TREE_VALUE (arglist);
6390   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6391     {
6392       REAL_VALUE_TYPE x;
6393
6394       x = TREE_REAL_CST (arg);
6395       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6396         {
6397           tree type = TREE_TYPE (exp);
6398           REAL_VALUE_TYPE r;
6399
6400           real_floor (&r, TYPE_MODE (type), &x);
6401           return build_real (type, r);
6402         }
6403     }
6404
6405   return fold_trunc_transparent_mathfn (exp);
6406 }
6407
6408 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6409    NULL_TREE if no simplification can be made.  */
6410
6411 static tree
6412 fold_builtin_ceil (tree exp)
6413 {
6414   tree arglist = TREE_OPERAND (exp, 1);
6415   tree arg;
6416
6417   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6418     return 0;
6419
6420   /* Optimize ceil of constant value.  */
6421   arg = TREE_VALUE (arglist);
6422   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6423     {
6424       REAL_VALUE_TYPE x;
6425
6426       x = TREE_REAL_CST (arg);
6427       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6428         {
6429           tree type = TREE_TYPE (exp);
6430           REAL_VALUE_TYPE r;
6431
6432           real_ceil (&r, TYPE_MODE (type), &x);
6433           return build_real (type, r);
6434         }
6435     }
6436
6437   return fold_trunc_transparent_mathfn (exp);
6438 }
6439
6440 /* Fold function call to builtin round, roundf or roundl.  Return
6441    NULL_TREE if no simplification can be made.  */
6442
6443 static tree
6444 fold_builtin_round (tree exp)
6445 {
6446   tree arglist = TREE_OPERAND (exp, 1);
6447   tree arg;
6448
6449   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6450     return 0;
6451
6452   /* Optimize round of constant value.  */
6453   arg = TREE_VALUE (arglist);
6454   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6455     {
6456       REAL_VALUE_TYPE x;
6457
6458       x = TREE_REAL_CST (arg);
6459       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6460         {
6461           tree type = TREE_TYPE (exp);
6462           REAL_VALUE_TYPE r;
6463
6464           real_round (&r, TYPE_MODE (type), &x);
6465           return build_real (type, r);
6466         }
6467     }
6468
6469   return fold_trunc_transparent_mathfn (exp);
6470 }
6471
6472 /* Fold function call to builtin lround, lroundf or lroundl (or the
6473    corresponding long long versions).  Return NULL_TREE if no
6474    simplification can be made.  */
6475
6476 static tree
6477 fold_builtin_lround (tree exp)
6478 {
6479   tree arglist = TREE_OPERAND (exp, 1);
6480   tree arg;
6481
6482   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6483     return 0;
6484
6485   /* Optimize lround of constant value.  */
6486   arg = TREE_VALUE (arglist);
6487   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6488     {
6489       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6490
6491       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6492         {
6493           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6494           HOST_WIDE_INT hi, lo;
6495           REAL_VALUE_TYPE r;
6496
6497           real_round (&r, TYPE_MODE (ftype), &x);
6498           REAL_VALUE_TO_INT (&lo, &hi, r);
6499           result = build_int_cst_wide (NULL_TREE, lo, hi);
6500           if (int_fits_type_p (result, itype))
6501             return fold_convert (itype, result);
6502         }
6503     }
6504
6505   return fold_fixed_mathfn (exp);
6506 }
6507
6508 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6509    and their long and long long variants (i.e. ffsl and ffsll).
6510    Return NULL_TREE if no simplification can be made.  */
6511
6512 static tree
6513 fold_builtin_bitop (tree exp)
6514 {
6515   tree fndecl = get_callee_fndecl (exp);
6516   tree arglist = TREE_OPERAND (exp, 1);
6517   tree arg;
6518
6519   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6520     return NULL_TREE;
6521
6522   /* Optimize for constant argument.  */
6523   arg = TREE_VALUE (arglist);
6524   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6525     {
6526       HOST_WIDE_INT hi, width, result;
6527       unsigned HOST_WIDE_INT lo;
6528       tree type;
6529
6530       type = TREE_TYPE (arg);
6531       width = TYPE_PRECISION (type);
6532       lo = TREE_INT_CST_LOW (arg);
6533
6534       /* Clear all the bits that are beyond the type's precision.  */
6535       if (width > HOST_BITS_PER_WIDE_INT)
6536         {
6537           hi = TREE_INT_CST_HIGH (arg);
6538           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6539             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6540         }
6541       else
6542         {
6543           hi = 0;
6544           if (width < HOST_BITS_PER_WIDE_INT)
6545             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6546         }
6547
6548       switch (DECL_FUNCTION_CODE (fndecl))
6549         {
6550         case BUILT_IN_FFS:
6551         case BUILT_IN_FFSL:
6552         case BUILT_IN_FFSLL:
6553           if (lo != 0)
6554             result = exact_log2 (lo & -lo) + 1;
6555           else if (hi != 0)
6556             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6557           else
6558             result = 0;
6559           break;
6560
6561         case BUILT_IN_CLZ:
6562         case BUILT_IN_CLZL:
6563         case BUILT_IN_CLZLL:
6564           if (hi != 0)
6565             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6566           else if (lo != 0)
6567             result = width - floor_log2 (lo) - 1;
6568           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6569             result = width;
6570           break;
6571
6572         case BUILT_IN_CTZ:
6573         case BUILT_IN_CTZL:
6574         case BUILT_IN_CTZLL:
6575           if (lo != 0)
6576             result = exact_log2 (lo & -lo);
6577           else if (hi != 0)
6578             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6579           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6580             result = width;
6581           break;
6582
6583         case BUILT_IN_POPCOUNT:
6584         case BUILT_IN_POPCOUNTL:
6585         case BUILT_IN_POPCOUNTLL:
6586           result = 0;
6587           while (lo)
6588             result++, lo &= lo - 1;
6589           while (hi)
6590             result++, hi &= hi - 1;
6591           break;
6592
6593         case BUILT_IN_PARITY:
6594         case BUILT_IN_PARITYL:
6595         case BUILT_IN_PARITYLL:
6596           result = 0;
6597           while (lo)
6598             result++, lo &= lo - 1;
6599           while (hi)
6600             result++, hi &= hi - 1;
6601           result &= 1;
6602           break;
6603
6604         default:
6605           gcc_unreachable ();
6606         }
6607
6608       return build_int_cst (TREE_TYPE (exp), result);
6609     }
6610
6611   return NULL_TREE;
6612 }
6613
6614 /* Return true if EXPR is the real constant contained in VALUE.  */
6615
6616 static bool
6617 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6618 {
6619   STRIP_NOPS (expr);
6620
6621   return ((TREE_CODE (expr) == REAL_CST
6622            && ! TREE_CONSTANT_OVERFLOW (expr)
6623            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6624           || (TREE_CODE (expr) == COMPLEX_CST
6625               && real_dconstp (TREE_REALPART (expr), value)
6626               && real_zerop (TREE_IMAGPART (expr))));
6627 }
6628
6629 /* A subroutine of fold_builtin to fold the various logarithmic
6630    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6631    function.  VALUE is the base of the logN function.  */
6632
6633 static tree
6634 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6635 {
6636   tree arglist = TREE_OPERAND (exp, 1);
6637
6638   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6639     {
6640       tree fndecl = get_callee_fndecl (exp);
6641       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6642       tree arg = TREE_VALUE (arglist);
6643       const enum built_in_function fcode = builtin_mathfn_code (arg);
6644
6645       /* Optimize logN(1.0) = 0.0.  */
6646       if (real_onep (arg))
6647         return build_real (type, dconst0);
6648
6649       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6650          exactly, then only do this if flag_unsafe_math_optimizations.  */
6651       if (exact_real_truncate (TYPE_MODE (type), value)
6652           || flag_unsafe_math_optimizations)
6653         {
6654           const REAL_VALUE_TYPE value_truncate =
6655             real_value_truncate (TYPE_MODE (type), *value);
6656           if (real_dconstp (arg, &value_truncate))
6657             return build_real (type, dconst1);
6658         }
6659
6660       /* Special case, optimize logN(expN(x)) = x.  */
6661       if (flag_unsafe_math_optimizations
6662           && ((value == &dconste
6663                && (fcode == BUILT_IN_EXP
6664                    || fcode == BUILT_IN_EXPF
6665                    || fcode == BUILT_IN_EXPL))
6666               || (value == &dconst2
6667                   && (fcode == BUILT_IN_EXP2
6668                       || fcode == BUILT_IN_EXP2F
6669                       || fcode == BUILT_IN_EXP2L))
6670               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6671         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6672
6673       /* Optimize logN(func()) for various exponential functions.  We
6674          want to determine the value "x" and the power "exponent" in
6675          order to transform logN(x**exponent) into exponent*logN(x).  */
6676       if (flag_unsafe_math_optimizations)
6677         {
6678           tree exponent = 0, x = 0;
6679
6680           switch (fcode)
6681           {
6682           case BUILT_IN_EXP:
6683           case BUILT_IN_EXPF:
6684           case BUILT_IN_EXPL:
6685             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6686             x = build_real (type,
6687                             real_value_truncate (TYPE_MODE (type), dconste));
6688             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6689             break;
6690           case BUILT_IN_EXP2:
6691           case BUILT_IN_EXP2F:
6692           case BUILT_IN_EXP2L:
6693             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6694             x = build_real (type, dconst2);
6695             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6696             break;
6697           case BUILT_IN_EXP10:
6698           case BUILT_IN_EXP10F:
6699           case BUILT_IN_EXP10L:
6700           case BUILT_IN_POW10:
6701           case BUILT_IN_POW10F:
6702           case BUILT_IN_POW10L:
6703             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6704             x = build_real (type, dconst10);
6705             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6706             break;
6707           case BUILT_IN_SQRT:
6708           case BUILT_IN_SQRTF:
6709           case BUILT_IN_SQRTL:
6710             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6711             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6712             exponent = build_real (type, dconsthalf);
6713             break;
6714           case BUILT_IN_CBRT:
6715           case BUILT_IN_CBRTF:
6716           case BUILT_IN_CBRTL:
6717             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6718             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6719             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6720                                                               dconstthird));
6721             break;
6722           case BUILT_IN_POW:
6723           case BUILT_IN_POWF:
6724           case BUILT_IN_POWL:
6725             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6726             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6727             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6728             break;
6729           default:
6730             break;
6731           }
6732
6733           /* Now perform the optimization.  */
6734           if (x && exponent)
6735             {
6736               tree logfn;
6737               arglist = build_tree_list (NULL_TREE, x);
6738               logfn = build_function_call_expr (fndecl, arglist);
6739               return fold (build2 (MULT_EXPR, type, exponent, logfn));
6740             }
6741         }
6742     }
6743
6744   return 0;
6745 }
6746
6747 /* Fold a builtin function call to pow, powf, or powl.  Return
6748    NULL_TREE if no simplification can be made.  */
6749 static tree
6750 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6751 {
6752   enum built_in_function fcode;
6753   tree arg0 = TREE_VALUE (arglist);
6754   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6755
6756   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6757     return NULL_TREE;
6758
6759   /* Optimize pow(1.0,y) = 1.0.  */
6760   if (real_onep (arg0))
6761     return omit_one_operand (type, build_real (type, dconst1), arg1);
6762
6763   if (TREE_CODE (arg1) == REAL_CST
6764       && ! TREE_CONSTANT_OVERFLOW (arg1))
6765     {
6766       REAL_VALUE_TYPE c;
6767       c = TREE_REAL_CST (arg1);
6768
6769       /* Optimize pow(x,0.0) = 1.0.  */
6770       if (REAL_VALUES_EQUAL (c, dconst0))
6771         return omit_one_operand (type, build_real (type, dconst1),
6772                                  arg0);
6773
6774       /* Optimize pow(x,1.0) = x.  */
6775       if (REAL_VALUES_EQUAL (c, dconst1))
6776         return arg0;
6777
6778       /* Optimize pow(x,-1.0) = 1.0/x.  */
6779       if (REAL_VALUES_EQUAL (c, dconstm1))
6780         return fold (build2 (RDIV_EXPR, type,
6781                              build_real (type, dconst1), arg0));
6782
6783       /* Optimize pow(x,0.5) = sqrt(x).  */
6784       if (flag_unsafe_math_optimizations
6785           && REAL_VALUES_EQUAL (c, dconsthalf))
6786         {
6787           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6788
6789           if (sqrtfn != NULL_TREE)
6790             {
6791               tree arglist = build_tree_list (NULL_TREE, arg0);
6792               return build_function_call_expr (sqrtfn, arglist);
6793             }
6794         }
6795
6796       /* Attempt to evaluate pow at compile-time.  */
6797       if (TREE_CODE (arg0) == REAL_CST
6798           && ! TREE_CONSTANT_OVERFLOW (arg0))
6799         {
6800           REAL_VALUE_TYPE cint;
6801           HOST_WIDE_INT n;
6802
6803           n = real_to_integer (&c);
6804           real_from_integer (&cint, VOIDmode, n,
6805                              n < 0 ? -1 : 0, 0);
6806           if (real_identical (&c, &cint))
6807             {
6808               REAL_VALUE_TYPE x;
6809               bool inexact;
6810
6811               x = TREE_REAL_CST (arg0);
6812               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6813               if (flag_unsafe_math_optimizations || !inexact)
6814                 return build_real (type, x);
6815             }
6816         }
6817     }
6818
6819   /* Optimize pow(expN(x),y) = expN(x*y).  */
6820   fcode = builtin_mathfn_code (arg0);
6821   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6822     {
6823       tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6824       tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6825       arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6826       arglist = build_tree_list (NULL_TREE, arg);
6827       return build_function_call_expr (expfn, arglist);
6828     }
6829
6830   /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6831   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6832     {
6833       tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6834       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6835                                  build_real (type, dconsthalf)));
6836
6837       arglist = tree_cons (NULL_TREE, narg0,
6838                            build_tree_list (NULL_TREE, narg1));
6839       return build_function_call_expr (fndecl, arglist);
6840     }
6841
6842   /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6843   if (flag_unsafe_math_optimizations
6844       && (fcode == BUILT_IN_POW
6845           || fcode == BUILT_IN_POWF
6846           || fcode == BUILT_IN_POWL))
6847     {
6848       tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6849       tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6850       tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
6851       arglist = tree_cons (NULL_TREE, arg00,
6852                            build_tree_list (NULL_TREE, narg1));
6853       return build_function_call_expr (fndecl, arglist);
6854     }
6855   return NULL_TREE;
6856 }
6857
6858 /* A subroutine of fold_builtin to fold the various exponent
6859    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6860    VALUE is the value which will be raised to a power.  */
6861
6862 static tree
6863 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6864 {
6865   tree arglist = TREE_OPERAND (exp, 1);
6866
6867   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6868     {
6869       tree fndecl = get_callee_fndecl (exp);
6870       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6871       tree arg = TREE_VALUE (arglist);
6872
6873       /* Optimize exp*(0.0) = 1.0.  */
6874       if (real_zerop (arg))
6875         return build_real (type, dconst1);
6876
6877       /* Optimize expN(1.0) = N.  */
6878       if (real_onep (arg))
6879         {
6880           REAL_VALUE_TYPE cst;
6881
6882           real_convert (&cst, TYPE_MODE (type), value);
6883           return build_real (type, cst);
6884         }
6885
6886       /* Attempt to evaluate expN(integer) at compile-time.  */
6887       if (flag_unsafe_math_optimizations
6888           && TREE_CODE (arg) == REAL_CST
6889           && ! TREE_CONSTANT_OVERFLOW (arg))
6890         {
6891           REAL_VALUE_TYPE cint;
6892           REAL_VALUE_TYPE c;
6893           HOST_WIDE_INT n;
6894
6895           c = TREE_REAL_CST (arg);
6896           n = real_to_integer (&c);
6897           real_from_integer (&cint, VOIDmode, n,
6898                              n < 0 ? -1 : 0, 0);
6899           if (real_identical (&c, &cint))
6900             {
6901               REAL_VALUE_TYPE x;
6902
6903               real_powi (&x, TYPE_MODE (type), value, n);
6904               return build_real (type, x);
6905             }
6906         }
6907
6908       /* Optimize expN(logN(x)) = x.  */
6909       if (flag_unsafe_math_optimizations)
6910         {
6911           const enum built_in_function fcode = builtin_mathfn_code (arg);
6912
6913           if ((value == &dconste
6914                && (fcode == BUILT_IN_LOG
6915                    || fcode == BUILT_IN_LOGF
6916                    || fcode == BUILT_IN_LOGL))
6917               || (value == &dconst2
6918                   && (fcode == BUILT_IN_LOG2
6919                       || fcode == BUILT_IN_LOG2F
6920                       || fcode == BUILT_IN_LOG2L))
6921               || (value == &dconst10
6922                   && (fcode == BUILT_IN_LOG10
6923                       || fcode == BUILT_IN_LOG10F
6924                       || fcode == BUILT_IN_LOG10L)))
6925             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6926         }
6927     }
6928
6929   return 0;
6930 }
6931
6932 /* Fold function call to builtin memcpy.  Return
6933    NULL_TREE if no simplification can be made.  */
6934
6935 static tree
6936 fold_builtin_memcpy (tree exp)
6937 {
6938   tree arglist = TREE_OPERAND (exp, 1);
6939   tree dest, src, len;
6940
6941   if (!validate_arglist (arglist,
6942                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6943     return 0;
6944
6945   dest = TREE_VALUE (arglist);
6946   src = TREE_VALUE (TREE_CHAIN (arglist));
6947   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6948
6949   /* If the LEN parameter is zero, return DEST.  */
6950   if (integer_zerop (len))
6951     return omit_one_operand (TREE_TYPE (exp), dest, src);
6952
6953   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6954   if (operand_equal_p (src, dest, 0))
6955     return omit_one_operand (TREE_TYPE (exp), dest, len);
6956
6957   return 0;
6958 }
6959
6960 /* Fold function call to builtin mempcpy.  Return
6961    NULL_TREE if no simplification can be made.  */
6962
6963 static tree
6964 fold_builtin_mempcpy (tree arglist, tree type, int endp)
6965 {
6966   if (validate_arglist (arglist,
6967                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6968     {
6969       tree dest = TREE_VALUE (arglist);
6970       tree src = TREE_VALUE (TREE_CHAIN (arglist));
6971       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6972
6973       /* If the LEN parameter is zero, return DEST.  */
6974       if (integer_zerop (len))
6975         return omit_one_operand (type, dest, src);
6976
6977       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6978       if (operand_equal_p (src, dest, 0))
6979         {
6980           if (endp == 0)
6981             return omit_one_operand (type, dest, len);
6982
6983           if (endp == 2)
6984             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
6985                                 ssize_int (1)));
6986       
6987           len = fold_convert (TREE_TYPE (dest), len);
6988           len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6989           return fold_convert (type, len);
6990         }
6991     }
6992   return 0;
6993 }
6994
6995 /* Fold function call to builtin memmove.  Return
6996    NULL_TREE if no simplification can be made.  */
6997
6998 static tree
6999 fold_builtin_memmove (tree arglist, tree type)
7000 {
7001   tree dest, src, len;
7002
7003   if (!validate_arglist (arglist,
7004                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7005     return 0;
7006
7007   dest = TREE_VALUE (arglist);
7008   src = TREE_VALUE (TREE_CHAIN (arglist));
7009   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7010
7011   /* If the LEN parameter is zero, return DEST.  */
7012   if (integer_zerop (len))
7013     return omit_one_operand (type, dest, src);
7014
7015   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7016   if (operand_equal_p (src, dest, 0))
7017     return omit_one_operand (type, dest, len);
7018
7019   return 0;
7020 }
7021
7022 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7023    the length of the string to be copied.  Return NULL_TREE if no
7024    simplification can be made.  */
7025
7026 tree
7027 fold_builtin_strcpy (tree exp, tree len)
7028 {
7029   tree arglist = TREE_OPERAND (exp, 1);
7030   tree dest, src, fn;
7031
7032   if (!validate_arglist (arglist,
7033                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7034     return 0;
7035
7036   dest = TREE_VALUE (arglist);
7037   src = TREE_VALUE (TREE_CHAIN (arglist));
7038
7039   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7040   if (operand_equal_p (src, dest, 0))
7041     return fold_convert (TREE_TYPE (exp), dest);
7042
7043   if (optimize_size)
7044     return 0;
7045
7046   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7047   if (!fn)
7048     return 0;
7049
7050   if (!len)
7051     {
7052       len = c_strlen (src, 1);
7053       if (! len || TREE_SIDE_EFFECTS (len))
7054         return 0;
7055     }
7056
7057   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7058   arglist = build_tree_list (NULL_TREE, len);
7059   arglist = tree_cons (NULL_TREE, src, arglist);
7060   arglist = tree_cons (NULL_TREE, dest, arglist);
7061   return fold_convert (TREE_TYPE (exp),
7062                        build_function_call_expr (fn, arglist));
7063 }
7064
7065 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7066    the length of the source string.  Return NULL_TREE if no simplification
7067    can be made.  */
7068
7069 tree
7070 fold_builtin_strncpy (tree exp, tree slen)
7071 {
7072   tree arglist = TREE_OPERAND (exp, 1);
7073   tree dest, src, len, fn;
7074
7075   if (!validate_arglist (arglist,
7076                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7077     return 0;
7078
7079   dest = TREE_VALUE (arglist);
7080   src = TREE_VALUE (TREE_CHAIN (arglist));
7081   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7082
7083   /* If the LEN parameter is zero, return DEST.  */
7084   if (integer_zerop (len))
7085     return omit_one_operand (TREE_TYPE (exp), dest, src);
7086
7087   /* We can't compare slen with len as constants below if len is not a
7088      constant.  */
7089   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7090     return 0;
7091
7092   if (!slen)
7093     slen = c_strlen (src, 1);
7094
7095   /* Now, we must be passed a constant src ptr parameter.  */
7096   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7097     return 0;
7098
7099   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7100
7101   /* We do not support simplification of this case, though we do
7102      support it when expanding trees into RTL.  */
7103   /* FIXME: generate a call to __builtin_memset.  */
7104   if (tree_int_cst_lt (slen, len))
7105     return 0;
7106
7107   /* OK transform into builtin memcpy.  */
7108   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7109   if (!fn)
7110     return 0;
7111   return fold_convert (TREE_TYPE (exp),
7112                        build_function_call_expr (fn, arglist));
7113 }
7114
7115 /* Fold function call to builtin memcmp.  Return
7116    NULL_TREE if no simplification can be made.  */
7117
7118 static tree
7119 fold_builtin_memcmp (tree arglist)
7120 {
7121   tree arg1, arg2, len;
7122   const char *p1, *p2;
7123
7124   if (!validate_arglist (arglist,
7125                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7126     return 0;
7127
7128   arg1 = TREE_VALUE (arglist);
7129   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7130   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7131
7132   /* If the LEN parameter is zero, return zero.  */
7133   if (integer_zerop (len))
7134     return omit_two_operands (integer_type_node, integer_zero_node,
7135                               arg1, arg2);
7136
7137   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7138   if (operand_equal_p (arg1, arg2, 0))
7139     return omit_one_operand (integer_type_node, integer_zero_node, len);
7140
7141   p1 = c_getstr (arg1);
7142   p2 = c_getstr (arg2);
7143
7144   /* If all arguments are constant, and the value of len is not greater
7145      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7146   if (host_integerp (len, 1) && p1 && p2
7147       && compare_tree_int (len, strlen (p1) + 1) <= 0
7148       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7149     {
7150       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7151
7152       if (r > 0)
7153         return integer_one_node;
7154       else if (r < 0)
7155         return integer_minus_one_node;
7156       else
7157         return integer_zero_node;
7158     }
7159
7160   /* If len parameter is one, return an expression corresponding to
7161      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7162   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7163     {
7164       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7165       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7166       tree ind1 = fold_convert (integer_type_node,
7167                                 build1 (INDIRECT_REF, cst_uchar_node,
7168                                         fold_convert (cst_uchar_ptr_node,
7169                                                       arg1)));
7170       tree ind2 = fold_convert (integer_type_node,
7171                                 build1 (INDIRECT_REF, cst_uchar_node,
7172                                         fold_convert (cst_uchar_ptr_node,
7173                                                       arg2)));
7174       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7175     }
7176
7177   return 0;
7178 }
7179
7180 /* Fold function call to builtin strcmp.  Return
7181    NULL_TREE if no simplification can be made.  */
7182
7183 static tree
7184 fold_builtin_strcmp (tree arglist)
7185 {
7186   tree arg1, arg2;
7187   const char *p1, *p2;
7188
7189   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7190     return 0;
7191
7192   arg1 = TREE_VALUE (arglist);
7193   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7194
7195   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7196   if (operand_equal_p (arg1, arg2, 0))
7197     return integer_zero_node;
7198
7199   p1 = c_getstr (arg1);
7200   p2 = c_getstr (arg2);
7201
7202   if (p1 && p2)
7203     {
7204       const int i = strcmp (p1, p2);
7205       if (i < 0)
7206         return integer_minus_one_node;
7207       else if (i > 0)
7208         return integer_one_node;
7209       else
7210         return integer_zero_node;
7211     }
7212
7213   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7214   if (p2 && *p2 == '\0')
7215     {
7216       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7217       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7218       return fold_convert (integer_type_node,
7219                            build1 (INDIRECT_REF, cst_uchar_node,
7220                                    fold_convert (cst_uchar_ptr_node,
7221                                                  arg1)));
7222     }
7223
7224   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7225   if (p1 && *p1 == '\0')
7226     {
7227       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7228       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7229       tree temp = fold_convert (integer_type_node,
7230                                 build1 (INDIRECT_REF, cst_uchar_node,
7231                                         fold_convert (cst_uchar_ptr_node,
7232                                                       arg2)));
7233       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7234     }
7235
7236   return 0;
7237 }
7238
7239 /* Fold function call to builtin strncmp.  Return
7240    NULL_TREE if no simplification can be made.  */
7241
7242 static tree
7243 fold_builtin_strncmp (tree arglist)
7244 {
7245   tree arg1, arg2, len;
7246   const char *p1, *p2;
7247
7248   if (!validate_arglist (arglist,
7249                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7250     return 0;
7251
7252   arg1 = TREE_VALUE (arglist);
7253   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7254   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7255
7256   /* If the LEN parameter is zero, return zero.  */
7257   if (integer_zerop (len))
7258     return omit_two_operands (integer_type_node, integer_zero_node,
7259                               arg1, arg2);
7260
7261   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7262   if (operand_equal_p (arg1, arg2, 0))
7263     return omit_one_operand (integer_type_node, integer_zero_node, len);
7264
7265   p1 = c_getstr (arg1);
7266   p2 = c_getstr (arg2);
7267
7268   if (host_integerp (len, 1) && p1 && p2)
7269     {
7270       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7271       if (i > 0)
7272         return integer_one_node;
7273       else if (i < 0)
7274         return integer_minus_one_node;
7275       else
7276         return integer_zero_node;
7277     }
7278
7279   /* If the second arg is "", and the length is greater than zero,
7280      return *(const unsigned char*)arg1.  */
7281   if (p2 && *p2 == '\0'
7282       && TREE_CODE (len) == INTEGER_CST
7283       && tree_int_cst_sgn (len) == 1)
7284     {
7285       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7286       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7287       return fold_convert (integer_type_node,
7288                            build1 (INDIRECT_REF, cst_uchar_node,
7289                                    fold_convert (cst_uchar_ptr_node,
7290                                                  arg1)));
7291     }
7292
7293   /* If the first arg is "", and the length is greater than zero,
7294      return -*(const unsigned char*)arg2.  */
7295   if (p1 && *p1 == '\0'
7296       && TREE_CODE (len) == INTEGER_CST
7297       && tree_int_cst_sgn (len) == 1)
7298     {
7299       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7300       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7301       tree temp = fold_convert (integer_type_node,
7302                                 build1 (INDIRECT_REF, cst_uchar_node,
7303                                         fold_convert (cst_uchar_ptr_node,
7304                                                       arg2)));
7305       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7306     }
7307
7308   /* If len parameter is one, return an expression corresponding to
7309      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7310   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7311     {
7312       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7313       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7314       tree ind1 = fold_convert (integer_type_node,
7315                                 build1 (INDIRECT_REF, cst_uchar_node,
7316                                         fold_convert (cst_uchar_ptr_node,
7317                                                       arg1)));
7318       tree ind2 = fold_convert (integer_type_node,
7319                                 build1 (INDIRECT_REF, cst_uchar_node,
7320                                         fold_convert (cst_uchar_ptr_node,
7321                                                       arg2)));
7322       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7323     }
7324
7325   return 0;
7326 }
7327
7328 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7329    NULL_TREE if no simplification can be made.  */
7330
7331 static tree
7332 fold_builtin_signbit (tree exp)
7333 {
7334   tree arglist = TREE_OPERAND (exp, 1);
7335   tree arg, temp;
7336
7337   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7338     return NULL_TREE;
7339
7340   arg = TREE_VALUE (arglist);
7341
7342   /* If ARG is a compile-time constant, determine the result.  */
7343   if (TREE_CODE (arg) == REAL_CST
7344       && !TREE_CONSTANT_OVERFLOW (arg))
7345     {
7346       REAL_VALUE_TYPE c;
7347
7348       c = TREE_REAL_CST (arg);
7349       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7350       return fold_convert (TREE_TYPE (exp), temp);
7351     }
7352
7353   /* If ARG is non-negative, the result is always zero.  */
7354   if (tree_expr_nonnegative_p (arg))
7355     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7356
7357   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7358   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7359     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7360                          build_real (TREE_TYPE (arg), dconst0)));
7361
7362   return NULL_TREE;
7363 }
7364
7365 /* Fold function call to builtin copysign, copysignf or copysignl.
7366    Return NULL_TREE if no simplification can be made.  */
7367
7368 static tree
7369 fold_builtin_copysign (tree arglist, tree type)
7370 {
7371   tree arg1, arg2;
7372
7373   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7374     return NULL_TREE;
7375
7376   arg1 = TREE_VALUE (arglist);
7377   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7378
7379   /* copysign(X,X) is X.  */
7380   if (operand_equal_p (arg1, arg2, 0))
7381     return fold_convert (type, arg1);
7382
7383   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7384   if (TREE_CODE (arg1) == REAL_CST
7385       && TREE_CODE (arg2) == REAL_CST
7386       && !TREE_CONSTANT_OVERFLOW (arg1)
7387       && !TREE_CONSTANT_OVERFLOW (arg2))
7388     {
7389       REAL_VALUE_TYPE c1, c2;
7390
7391       c1 = TREE_REAL_CST (arg1);
7392       c2 = TREE_REAL_CST (arg2);
7393       real_copysign (&c1, &c2);
7394       return build_real (type, c1);
7395       c1.sign = c2.sign;
7396     }
7397
7398   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7399      Remember to evaluate Y for side-effects.  */
7400   if (tree_expr_nonnegative_p (arg2))
7401     return omit_one_operand (type,
7402                              fold (build1 (ABS_EXPR, type, arg1)),
7403                              arg2);
7404
7405   return NULL_TREE;
7406 }
7407
7408 /* Fold a call to builtin isascii.  */
7409
7410 static tree
7411 fold_builtin_isascii (tree arglist)
7412 {
7413   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7414     return 0;
7415   else
7416     {
7417       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7418       tree arg = TREE_VALUE (arglist);
7419
7420       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7421                     build_int_cst (NULL_TREE,
7422                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
7423       arg = fold (build2 (EQ_EXPR, integer_type_node,
7424                           arg, integer_zero_node));
7425
7426       if (in_gimple_form && !TREE_CONSTANT (arg))
7427         return NULL_TREE;
7428       else
7429         return arg;
7430     }
7431 }
7432
7433 /* Fold a call to builtin toascii.  */
7434
7435 static tree
7436 fold_builtin_toascii (tree arglist)
7437 {
7438   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7439     return 0;
7440   else
7441     {
7442       /* Transform toascii(c) -> (c & 0x7f).  */
7443       tree arg = TREE_VALUE (arglist);
7444
7445       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7446                            build_int_cst (NULL_TREE, 0x7f)));
7447     }
7448 }
7449
7450 /* Fold a call to builtin isdigit.  */
7451
7452 static tree
7453 fold_builtin_isdigit (tree arglist)
7454 {
7455   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7456     return 0;
7457   else
7458     {
7459       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7460       /* According to the C standard, isdigit is unaffected by locale.  */
7461       tree arg = TREE_VALUE (arglist);
7462       arg = fold_convert (unsigned_type_node, arg);
7463       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7464                     build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7465       arg = build2 (LE_EXPR, integer_type_node, arg,
7466                     build_int_cst (unsigned_type_node, 9));
7467       arg = fold (arg);
7468       if (in_gimple_form && !TREE_CONSTANT (arg))
7469         return NULL_TREE;
7470       else
7471         return arg;
7472     }
7473 }
7474
7475 /* Fold a call to fabs, fabsf or fabsl.  */
7476
7477 static tree
7478 fold_builtin_fabs (tree arglist, tree type)
7479 {
7480   tree arg;
7481
7482   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7483     return 0;
7484
7485   arg = TREE_VALUE (arglist);
7486   if (TREE_CODE (arg) == REAL_CST)
7487     return fold_abs_const (arg, type);
7488   return fold (build1 (ABS_EXPR, type, arg));
7489 }
7490
7491 /* Fold a call to abs, labs, llabs or imaxabs.  */
7492
7493 static tree
7494 fold_builtin_abs (tree arglist, tree type)
7495 {
7496   tree arg;
7497
7498   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7499     return 0;
7500
7501   arg = TREE_VALUE (arglist);
7502   if (TREE_CODE (arg) == INTEGER_CST)
7503     return fold_abs_const (arg, type);
7504   return fold (build1 (ABS_EXPR, type, arg));
7505 }
7506
7507 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7508    EXP is the CALL_EXPR for the call.  */
7509
7510 static tree
7511 fold_builtin_classify (tree exp, int builtin_index)
7512 {
7513   tree fndecl = get_callee_fndecl (exp);
7514   tree arglist = TREE_OPERAND (exp, 1);
7515   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7516   tree arg;
7517   REAL_VALUE_TYPE r;
7518
7519   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7520     {
7521       /* Check that we have exactly one argument.  */
7522       if (arglist == 0)
7523         {
7524           error ("too few arguments to function %qs",
7525                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7526           return error_mark_node;
7527         }
7528       else if (TREE_CHAIN (arglist) != 0)
7529         {
7530           error ("too many arguments to function %qs",
7531                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7532           return error_mark_node;
7533         }
7534       else
7535         {
7536           error ("non-floating-point argument to function %qs",
7537                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7538           return error_mark_node;
7539         }
7540     }
7541
7542   arg = TREE_VALUE (arglist);
7543   switch (builtin_index)
7544     {
7545     case BUILT_IN_ISINF:
7546       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7547         return omit_one_operand (type, integer_zero_node, arg);
7548
7549       if (TREE_CODE (arg) == REAL_CST)
7550         {
7551           r = TREE_REAL_CST (arg);
7552           if (real_isinf (&r))
7553             return real_compare (GT_EXPR, &r, &dconst0)
7554                    ? integer_one_node : integer_minus_one_node;
7555           else
7556             return integer_zero_node;
7557         }
7558
7559       return NULL_TREE;
7560
7561     case BUILT_IN_FINITE:
7562       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7563           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7564         return omit_one_operand (type, integer_zero_node, arg);
7565
7566       if (TREE_CODE (arg) == REAL_CST)
7567         {
7568           r = TREE_REAL_CST (arg);
7569           return real_isinf (&r) || real_isnan (&r)
7570                  ? integer_zero_node : integer_one_node;
7571         }
7572
7573       return NULL_TREE;
7574
7575     case BUILT_IN_ISNAN:
7576       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7577         return omit_one_operand (type, integer_zero_node, arg);
7578
7579       if (TREE_CODE (arg) == REAL_CST)
7580         {
7581           r = TREE_REAL_CST (arg);
7582           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7583         }
7584
7585       arg = builtin_save_expr (arg);
7586       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7587
7588     default:
7589       gcc_unreachable ();
7590     }
7591 }
7592
7593 /* Fold a call to an unordered comparison function such as
7594    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7595    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7596    the opposite of the desired result.  UNORDERED_CODE is used
7597    for modes that can hold NaNs and ORDERED_CODE is used for
7598    the rest.  */
7599
7600 static tree
7601 fold_builtin_unordered_cmp (tree exp,
7602                             enum tree_code unordered_code,
7603                             enum tree_code ordered_code)
7604 {
7605   tree fndecl = get_callee_fndecl (exp);
7606   tree arglist = TREE_OPERAND (exp, 1);
7607   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7608   enum tree_code code;
7609   tree arg0, arg1;
7610   tree type0, type1;
7611   enum tree_code code0, code1;
7612   tree cmp_type = NULL_TREE;
7613
7614   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7615     {
7616       /* Check that we have exactly two arguments.  */
7617       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7618         {
7619           error ("too few arguments to function %qs",
7620                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7621           return error_mark_node;
7622         }
7623       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7624         {
7625           error ("too many arguments to function %qs",
7626                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7627           return error_mark_node;
7628         }
7629     }
7630
7631   arg0 = TREE_VALUE (arglist);
7632   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7633   
7634   type0 = TREE_TYPE (arg0);
7635   type1 = TREE_TYPE (arg1);
7636   
7637   code0 = TREE_CODE (type0);
7638   code1 = TREE_CODE (type1);
7639   
7640   if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7641     /* Choose the wider of two real types.  */
7642     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7643       ? type0 : type1;
7644   else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7645     cmp_type = type0;
7646   else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7647     cmp_type = type1;
7648   else
7649     {
7650       error ("non-floating-point argument to function %qs",
7651                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7652       return error_mark_node;
7653     }
7654   
7655   arg0 = fold_convert (cmp_type, arg0);
7656   arg1 = fold_convert (cmp_type, arg1);
7657
7658   if (unordered_code == UNORDERED_EXPR)
7659     {
7660       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7661         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7662       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7663     }
7664
7665   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7666                                                       : ordered_code;
7667   return fold (build1 (TRUTH_NOT_EXPR, type,
7668                        fold (build2 (code, type, arg0, arg1))));
7669 }
7670
7671 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7672    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7673    result of the function call is ignored.  This function returns NULL_TREE
7674    if no simplification was possible.  */
7675
7676 static tree
7677 fold_builtin_1 (tree exp, bool ignore)
7678 {
7679   tree fndecl = get_callee_fndecl (exp);
7680   tree arglist = TREE_OPERAND (exp, 1);
7681   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7682
7683   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7684     return targetm.fold_builtin (exp, ignore);
7685
7686   switch (DECL_FUNCTION_CODE (fndecl))
7687     {
7688     case BUILT_IN_FPUTS:
7689       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7690
7691     case BUILT_IN_FPUTS_UNLOCKED:
7692       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7693
7694     case BUILT_IN_STRSTR:
7695       return fold_builtin_strstr (arglist);
7696
7697     case BUILT_IN_STRCAT:
7698       return fold_builtin_strcat (arglist);
7699
7700     case BUILT_IN_STRNCAT:
7701       return fold_builtin_strncat (arglist);
7702
7703     case BUILT_IN_STRSPN:
7704       return fold_builtin_strspn (arglist);
7705
7706     case BUILT_IN_STRCSPN:
7707       return fold_builtin_strcspn (arglist);
7708
7709     case BUILT_IN_STRCHR:
7710     case BUILT_IN_INDEX:
7711       return fold_builtin_strchr (arglist);
7712
7713     case BUILT_IN_STRRCHR:
7714     case BUILT_IN_RINDEX:
7715       return fold_builtin_strrchr (arglist);
7716
7717     case BUILT_IN_STRCPY:
7718       return fold_builtin_strcpy (exp, NULL_TREE);
7719
7720     case BUILT_IN_STRNCPY:
7721       return fold_builtin_strncpy (exp, NULL_TREE);
7722
7723     case BUILT_IN_STRCMP:
7724       return fold_builtin_strcmp (arglist);
7725
7726     case BUILT_IN_STRNCMP:
7727       return fold_builtin_strncmp (arglist);
7728
7729     case BUILT_IN_STRPBRK:
7730       return fold_builtin_strpbrk (arglist);
7731
7732     case BUILT_IN_BCMP:
7733     case BUILT_IN_MEMCMP:
7734       return fold_builtin_memcmp (arglist);
7735
7736     case BUILT_IN_SPRINTF:
7737       return fold_builtin_sprintf (arglist, ignore);
7738
7739     case BUILT_IN_CONSTANT_P:
7740       {
7741         tree val;
7742
7743         val = fold_builtin_constant_p (arglist);
7744         /* Gimplification will pull the CALL_EXPR for the builtin out of
7745            an if condition.  When not optimizing, we'll not CSE it back.
7746            To avoid link error types of regressions, return false now.  */
7747         if (!val && !optimize)
7748           val = integer_zero_node;
7749
7750         return val;
7751       }
7752
7753     case BUILT_IN_EXPECT:
7754       return fold_builtin_expect (arglist);
7755
7756     case BUILT_IN_CLASSIFY_TYPE:
7757       return fold_builtin_classify_type (arglist);
7758
7759     case BUILT_IN_STRLEN:
7760       return fold_builtin_strlen (arglist);
7761
7762     case BUILT_IN_FABS:
7763     case BUILT_IN_FABSF:
7764     case BUILT_IN_FABSL:
7765       return fold_builtin_fabs (arglist, type);
7766
7767     case BUILT_IN_ABS:
7768     case BUILT_IN_LABS:
7769     case BUILT_IN_LLABS:
7770     case BUILT_IN_IMAXABS:
7771       return fold_builtin_abs (arglist, type);
7772
7773     case BUILT_IN_CONJ:
7774     case BUILT_IN_CONJF:
7775     case BUILT_IN_CONJL:
7776       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7777         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7778       break;
7779
7780     case BUILT_IN_CREAL:
7781     case BUILT_IN_CREALF:
7782     case BUILT_IN_CREALL:
7783       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7784         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7785                                          TREE_VALUE (arglist))));
7786       break;
7787
7788     case BUILT_IN_CIMAG:
7789     case BUILT_IN_CIMAGF:
7790     case BUILT_IN_CIMAGL:
7791       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7792         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7793                                          TREE_VALUE (arglist))));
7794       break;
7795
7796     case BUILT_IN_CABS:
7797     case BUILT_IN_CABSF:
7798     case BUILT_IN_CABSL:
7799       return fold_builtin_cabs (arglist, type);
7800
7801     case BUILT_IN_SQRT:
7802     case BUILT_IN_SQRTF:
7803     case BUILT_IN_SQRTL:
7804       return fold_builtin_sqrt (arglist, type);
7805
7806     case BUILT_IN_CBRT:
7807     case BUILT_IN_CBRTF:
7808     case BUILT_IN_CBRTL:
7809       return fold_builtin_cbrt (arglist, type);
7810
7811     case BUILT_IN_SIN:
7812     case BUILT_IN_SINF:
7813     case BUILT_IN_SINL:
7814       return fold_builtin_sin (arglist);
7815
7816     case BUILT_IN_COS:
7817     case BUILT_IN_COSF:
7818     case BUILT_IN_COSL:
7819       return fold_builtin_cos (arglist, type, fndecl);
7820
7821     case BUILT_IN_EXP:
7822     case BUILT_IN_EXPF:
7823     case BUILT_IN_EXPL:
7824       return fold_builtin_exponent (exp, &dconste);
7825
7826     case BUILT_IN_EXP2:
7827     case BUILT_IN_EXP2F:
7828     case BUILT_IN_EXP2L:
7829       return fold_builtin_exponent (exp, &dconst2);
7830
7831     case BUILT_IN_EXP10:
7832     case BUILT_IN_EXP10F:
7833     case BUILT_IN_EXP10L:
7834     case BUILT_IN_POW10:
7835     case BUILT_IN_POW10F:
7836     case BUILT_IN_POW10L:
7837       return fold_builtin_exponent (exp, &dconst10);
7838
7839     case BUILT_IN_LOG:
7840     case BUILT_IN_LOGF:
7841     case BUILT_IN_LOGL:
7842       return fold_builtin_logarithm (exp, &dconste);
7843
7844     case BUILT_IN_LOG2:
7845     case BUILT_IN_LOG2F:
7846     case BUILT_IN_LOG2L:
7847       return fold_builtin_logarithm (exp, &dconst2);
7848
7849     case BUILT_IN_LOG10:
7850     case BUILT_IN_LOG10F:
7851     case BUILT_IN_LOG10L:
7852       return fold_builtin_logarithm (exp, &dconst10);
7853
7854     case BUILT_IN_TAN:
7855     case BUILT_IN_TANF:
7856     case BUILT_IN_TANL:
7857       return fold_builtin_tan (arglist);
7858
7859     case BUILT_IN_ATAN:
7860     case BUILT_IN_ATANF:
7861     case BUILT_IN_ATANL:
7862       return fold_builtin_atan (arglist, type);
7863
7864     case BUILT_IN_POW:
7865     case BUILT_IN_POWF:
7866     case BUILT_IN_POWL:
7867       return fold_builtin_pow (fndecl, arglist, type);
7868
7869     case BUILT_IN_INF:
7870     case BUILT_IN_INFF:
7871     case BUILT_IN_INFL:
7872       return fold_builtin_inf (type, true);
7873
7874     case BUILT_IN_HUGE_VAL:
7875     case BUILT_IN_HUGE_VALF:
7876     case BUILT_IN_HUGE_VALL:
7877       return fold_builtin_inf (type, false);
7878
7879     case BUILT_IN_NAN:
7880     case BUILT_IN_NANF:
7881     case BUILT_IN_NANL:
7882       return fold_builtin_nan (arglist, type, true);
7883
7884     case BUILT_IN_NANS:
7885     case BUILT_IN_NANSF:
7886     case BUILT_IN_NANSL:
7887       return fold_builtin_nan (arglist, type, false);
7888
7889     case BUILT_IN_FLOOR:
7890     case BUILT_IN_FLOORF:
7891     case BUILT_IN_FLOORL:
7892       return fold_builtin_floor (exp);
7893
7894     case BUILT_IN_CEIL:
7895     case BUILT_IN_CEILF:
7896     case BUILT_IN_CEILL:
7897       return fold_builtin_ceil (exp);
7898
7899     case BUILT_IN_TRUNC:
7900     case BUILT_IN_TRUNCF:
7901     case BUILT_IN_TRUNCL:
7902       return fold_builtin_trunc (exp);
7903
7904     case BUILT_IN_ROUND:
7905     case BUILT_IN_ROUNDF:
7906     case BUILT_IN_ROUNDL:
7907       return fold_builtin_round (exp);
7908
7909     case BUILT_IN_NEARBYINT:
7910     case BUILT_IN_NEARBYINTF:
7911     case BUILT_IN_NEARBYINTL:
7912     case BUILT_IN_RINT:
7913     case BUILT_IN_RINTF:
7914     case BUILT_IN_RINTL:
7915       return fold_trunc_transparent_mathfn (exp);
7916
7917     case BUILT_IN_LROUND:
7918     case BUILT_IN_LROUNDF:
7919     case BUILT_IN_LROUNDL:
7920     case BUILT_IN_LLROUND:
7921     case BUILT_IN_LLROUNDF:
7922     case BUILT_IN_LLROUNDL:
7923       return fold_builtin_lround (exp);
7924
7925     case BUILT_IN_LRINT:
7926     case BUILT_IN_LRINTF:
7927     case BUILT_IN_LRINTL:
7928     case BUILT_IN_LLRINT:
7929     case BUILT_IN_LLRINTF:
7930     case BUILT_IN_LLRINTL:
7931       return fold_fixed_mathfn (exp);
7932
7933     case BUILT_IN_FFS:
7934     case BUILT_IN_FFSL:
7935     case BUILT_IN_FFSLL:
7936     case BUILT_IN_CLZ:
7937     case BUILT_IN_CLZL:
7938     case BUILT_IN_CLZLL:
7939     case BUILT_IN_CTZ:
7940     case BUILT_IN_CTZL:
7941     case BUILT_IN_CTZLL:
7942     case BUILT_IN_POPCOUNT:
7943     case BUILT_IN_POPCOUNTL:
7944     case BUILT_IN_POPCOUNTLL:
7945     case BUILT_IN_PARITY:
7946     case BUILT_IN_PARITYL:
7947     case BUILT_IN_PARITYLL:
7948       return fold_builtin_bitop (exp);
7949
7950     case BUILT_IN_MEMCPY:
7951       return fold_builtin_memcpy (exp);
7952
7953     case BUILT_IN_MEMPCPY:
7954       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
7955
7956     case BUILT_IN_MEMMOVE:
7957       return fold_builtin_memmove (arglist, type);
7958
7959     case BUILT_IN_SIGNBIT:
7960     case BUILT_IN_SIGNBITF:
7961     case BUILT_IN_SIGNBITL:
7962       return fold_builtin_signbit (exp);
7963
7964     case BUILT_IN_ISASCII:
7965       return fold_builtin_isascii (arglist);
7966
7967     case BUILT_IN_TOASCII:
7968       return fold_builtin_toascii (arglist);
7969
7970     case BUILT_IN_ISDIGIT:
7971       return fold_builtin_isdigit (arglist);
7972
7973     case BUILT_IN_COPYSIGN:
7974     case BUILT_IN_COPYSIGNF:
7975     case BUILT_IN_COPYSIGNL:
7976       return fold_builtin_copysign (arglist, type);
7977
7978     case BUILT_IN_FINITE:
7979     case BUILT_IN_FINITEF:
7980     case BUILT_IN_FINITEL:
7981       return fold_builtin_classify (exp, BUILT_IN_FINITE);
7982
7983     case BUILT_IN_ISINF:
7984     case BUILT_IN_ISINFF:
7985     case BUILT_IN_ISINFL:
7986       return fold_builtin_classify (exp, BUILT_IN_ISINF);
7987
7988     case BUILT_IN_ISNAN:
7989     case BUILT_IN_ISNANF:
7990     case BUILT_IN_ISNANL:
7991       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
7992
7993     case BUILT_IN_ISGREATER:
7994       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
7995     case BUILT_IN_ISGREATEREQUAL:
7996       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
7997     case BUILT_IN_ISLESS:
7998       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
7999     case BUILT_IN_ISLESSEQUAL:
8000       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8001     case BUILT_IN_ISLESSGREATER:
8002       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8003     case BUILT_IN_ISUNORDERED:
8004       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8005
8006       /* We do the folding for va_start in the expander.  */
8007     case BUILT_IN_VA_START:
8008       break;
8009
8010     default:
8011       break;
8012     }
8013
8014   return 0;
8015 }
8016
8017 /* A wrapper function for builtin folding that prevents warnings for
8018    "statement without effect" and the like, caused by removing the
8019    call node earlier than the warning is generated.  */
8020
8021 tree
8022 fold_builtin (tree exp, bool ignore)
8023 {
8024   exp = fold_builtin_1 (exp, ignore);
8025   if (exp)
8026     {
8027       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8028       if (CONSTANT_CLASS_P (exp))
8029         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8030       TREE_NO_WARNING (exp) = 1;
8031     }
8032
8033   return exp;
8034 }
8035
8036 /* Conveniently construct a function call expression.  */
8037
8038 tree
8039 build_function_call_expr (tree fn, tree arglist)
8040 {
8041   tree call_expr;
8042
8043   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8044   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8045                       call_expr, arglist, NULL_TREE);
8046   return fold (call_expr);
8047 }
8048
8049 /* This function validates the types of a function call argument list
8050    represented as a tree chain of parameters against a specified list
8051    of tree_codes.  If the last specifier is a 0, that represents an
8052    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8053
8054 static int
8055 validate_arglist (tree arglist, ...)
8056 {
8057   enum tree_code code;
8058   int res = 0;
8059   va_list ap;
8060
8061   va_start (ap, arglist);
8062
8063   do
8064     {
8065       code = va_arg (ap, enum tree_code);
8066       switch (code)
8067         {
8068         case 0:
8069           /* This signifies an ellipses, any further arguments are all ok.  */
8070           res = 1;
8071           goto end;
8072         case VOID_TYPE:
8073           /* This signifies an endlink, if no arguments remain, return
8074              true, otherwise return false.  */
8075           res = arglist == 0;
8076           goto end;
8077         default:
8078           /* If no parameters remain or the parameter's code does not
8079              match the specified code, return false.  Otherwise continue
8080              checking any remaining arguments.  */
8081           if (arglist == 0
8082               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8083             goto end;
8084           break;
8085         }
8086       arglist = TREE_CHAIN (arglist);
8087     }
8088   while (1);
8089
8090   /* We need gotos here since we can only have one VA_CLOSE in a
8091      function.  */
8092  end: ;
8093   va_end (ap);
8094
8095   return res;
8096 }
8097
8098 /* Default target-specific builtin expander that does nothing.  */
8099
8100 rtx
8101 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8102                         rtx target ATTRIBUTE_UNUSED,
8103                         rtx subtarget ATTRIBUTE_UNUSED,
8104                         enum machine_mode mode ATTRIBUTE_UNUSED,
8105                         int ignore ATTRIBUTE_UNUSED)
8106 {
8107   return NULL_RTX;
8108 }
8109
8110 /* Returns true is EXP represents data that would potentially reside
8111    in a readonly section.  */
8112
8113 static bool
8114 readonly_data_expr (tree exp)
8115 {
8116   STRIP_NOPS (exp);
8117
8118   if (TREE_CODE (exp) != ADDR_EXPR)
8119     return false;
8120
8121   exp = get_base_address (TREE_OPERAND (exp, 0));
8122   if (!exp)
8123     return false;
8124
8125   /* Make sure we call decl_readonly_section only for trees it
8126      can handle (since it returns true for everything it doesn't
8127      understand).  */
8128   if (TREE_CODE (exp) == STRING_CST
8129       || TREE_CODE (exp) == CONSTRUCTOR
8130       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8131     return decl_readonly_section (exp, 0);
8132   else
8133     return false;
8134 }
8135
8136 /* Simplify a call to the strstr builtin.
8137
8138    Return 0 if no simplification was possible, otherwise return the
8139    simplified form of the call as a tree.
8140
8141    The simplified form may be a constant or other expression which
8142    computes the same value, but in a more efficient manner (including
8143    calls to other builtin functions).
8144
8145    The call may contain arguments which need to be evaluated, but
8146    which are not useful to determine the result of the call.  In
8147    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8148    COMPOUND_EXPR will be an argument which must be evaluated.
8149    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8150    COMPOUND_EXPR in the chain will contain the tree for the simplified
8151    form of the builtin function call.  */
8152
8153 static tree
8154 fold_builtin_strstr (tree arglist)
8155 {
8156   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8157     return 0;
8158   else
8159     {
8160       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8161       tree fn;
8162       const char *p1, *p2;
8163
8164       p2 = c_getstr (s2);
8165       if (p2 == NULL)
8166         return 0;
8167
8168       p1 = c_getstr (s1);
8169       if (p1 != NULL)
8170         {
8171           const char *r = strstr (p1, p2);
8172
8173           if (r == NULL)
8174             return build_int_cst (TREE_TYPE (s1), 0);
8175
8176           /* Return an offset into the constant string argument.  */
8177           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8178                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8179         }
8180
8181       if (p2[0] == '\0')
8182         return s1;
8183
8184       if (p2[1] != '\0')
8185         return 0;
8186
8187       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8188       if (!fn)
8189         return 0;
8190
8191       /* New argument list transforming strstr(s1, s2) to
8192          strchr(s1, s2[0]).  */
8193       arglist = build_tree_list (NULL_TREE,
8194                                  build_int_cst (NULL_TREE, p2[0]));
8195       arglist = tree_cons (NULL_TREE, s1, arglist);
8196       return build_function_call_expr (fn, arglist);
8197     }
8198 }
8199
8200 /* Simplify a call to the strchr builtin.
8201
8202    Return 0 if no simplification was possible, otherwise return the
8203    simplified form of the call as a tree.
8204
8205    The simplified form may be a constant or other expression which
8206    computes the same value, but in a more efficient manner (including
8207    calls to other builtin functions).
8208
8209    The call may contain arguments which need to be evaluated, but
8210    which are not useful to determine the result of the call.  In
8211    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8212    COMPOUND_EXPR will be an argument which must be evaluated.
8213    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8214    COMPOUND_EXPR in the chain will contain the tree for the simplified
8215    form of the builtin function call.  */
8216
8217 static tree
8218 fold_builtin_strchr (tree arglist)
8219 {
8220   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8221     return 0;
8222   else
8223     {
8224       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8225       const char *p1;
8226
8227       if (TREE_CODE (s2) != INTEGER_CST)
8228         return 0;
8229
8230       p1 = c_getstr (s1);
8231       if (p1 != NULL)
8232         {
8233           char c;
8234           const char *r;
8235
8236           if (target_char_cast (s2, &c))
8237             return 0;
8238
8239           r = strchr (p1, c);
8240
8241           if (r == NULL)
8242             return build_int_cst (TREE_TYPE (s1), 0);
8243
8244           /* Return an offset into the constant string argument.  */
8245           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8246                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8247         }
8248       return 0;
8249     }
8250 }
8251
8252 /* Simplify a call to the strrchr builtin.
8253
8254    Return 0 if no simplification was possible, otherwise return the
8255    simplified form of the call as a tree.
8256
8257    The simplified form may be a constant or other expression which
8258    computes the same value, but in a more efficient manner (including
8259    calls to other builtin functions).
8260
8261    The call may contain arguments which need to be evaluated, but
8262    which are not useful to determine the result of the call.  In
8263    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8264    COMPOUND_EXPR will be an argument which must be evaluated.
8265    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8266    COMPOUND_EXPR in the chain will contain the tree for the simplified
8267    form of the builtin function call.  */
8268
8269 static tree
8270 fold_builtin_strrchr (tree arglist)
8271 {
8272   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8273     return 0;
8274   else
8275     {
8276       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8277       tree fn;
8278       const char *p1;
8279
8280       if (TREE_CODE (s2) != INTEGER_CST)
8281         return 0;
8282
8283       p1 = c_getstr (s1);
8284       if (p1 != NULL)
8285         {
8286           char c;
8287           const char *r;
8288
8289           if (target_char_cast (s2, &c))
8290             return 0;
8291
8292           r = strrchr (p1, c);
8293
8294           if (r == NULL)
8295             return build_int_cst (TREE_TYPE (s1), 0);
8296
8297           /* Return an offset into the constant string argument.  */
8298           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8299                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8300         }
8301
8302       if (! integer_zerop (s2))
8303         return 0;
8304
8305       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8306       if (!fn)
8307         return 0;
8308
8309       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8310       return build_function_call_expr (fn, arglist);
8311     }
8312 }
8313
8314 /* Simplify a call to the strpbrk builtin.
8315
8316    Return 0 if no simplification was possible, otherwise return the
8317    simplified form of the call as a tree.
8318
8319    The simplified form may be a constant or other expression which
8320    computes the same value, but in a more efficient manner (including
8321    calls to other builtin functions).
8322
8323    The call may contain arguments which need to be evaluated, but
8324    which are not useful to determine the result of the call.  In
8325    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8326    COMPOUND_EXPR will be an argument which must be evaluated.
8327    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8328    COMPOUND_EXPR in the chain will contain the tree for the simplified
8329    form of the builtin function call.  */
8330
8331 static tree
8332 fold_builtin_strpbrk (tree arglist)
8333 {
8334   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8335     return 0;
8336   else
8337     {
8338       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8339       tree fn;
8340       const char *p1, *p2;
8341
8342       p2 = c_getstr (s2);
8343       if (p2 == NULL)
8344         return 0;
8345
8346       p1 = c_getstr (s1);
8347       if (p1 != NULL)
8348         {
8349           const char *r = strpbrk (p1, p2);
8350
8351           if (r == NULL)
8352             return build_int_cst (TREE_TYPE (s1), 0);
8353
8354           /* Return an offset into the constant string argument.  */
8355           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8356                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8357         }
8358
8359       if (p2[0] == '\0')
8360         /* strpbrk(x, "") == NULL.
8361            Evaluate and ignore s1 in case it had side-effects.  */
8362         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8363
8364       if (p2[1] != '\0')
8365         return 0;  /* Really call strpbrk.  */
8366
8367       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8368       if (!fn)
8369         return 0;
8370
8371       /* New argument list transforming strpbrk(s1, s2) to
8372          strchr(s1, s2[0]).  */
8373       arglist = build_tree_list (NULL_TREE,
8374                                  build_int_cst (NULL_TREE, p2[0]));
8375       arglist = tree_cons (NULL_TREE, s1, arglist);
8376       return build_function_call_expr (fn, arglist);
8377     }
8378 }
8379
8380 /* Simplify a call to the strcat builtin.
8381
8382    Return 0 if no simplification was possible, otherwise return the
8383    simplified form of the call as a tree.
8384
8385    The simplified form may be a constant or other expression which
8386    computes the same value, but in a more efficient manner (including
8387    calls to other builtin functions).
8388
8389    The call may contain arguments which need to be evaluated, but
8390    which are not useful to determine the result of the call.  In
8391    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8392    COMPOUND_EXPR will be an argument which must be evaluated.
8393    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8394    COMPOUND_EXPR in the chain will contain the tree for the simplified
8395    form of the builtin function call.  */
8396
8397 static tree
8398 fold_builtin_strcat (tree arglist)
8399 {
8400   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8401     return 0;
8402   else
8403     {
8404       tree dst = TREE_VALUE (arglist),
8405         src = TREE_VALUE (TREE_CHAIN (arglist));
8406       const char *p = c_getstr (src);
8407
8408       /* If the string length is zero, return the dst parameter.  */
8409       if (p && *p == '\0')
8410         return dst;
8411
8412       return 0;
8413     }
8414 }
8415
8416 /* Simplify a call to the strncat builtin.
8417
8418    Return 0 if no simplification was possible, otherwise return the
8419    simplified form of the call as a tree.
8420
8421    The simplified form may be a constant or other expression which
8422    computes the same value, but in a more efficient manner (including
8423    calls to other builtin functions).
8424
8425    The call may contain arguments which need to be evaluated, but
8426    which are not useful to determine the result of the call.  In
8427    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8428    COMPOUND_EXPR will be an argument which must be evaluated.
8429    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8430    COMPOUND_EXPR in the chain will contain the tree for the simplified
8431    form of the builtin function call.  */
8432
8433 static tree
8434 fold_builtin_strncat (tree arglist)
8435 {
8436   if (!validate_arglist (arglist,
8437                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8438     return 0;
8439   else
8440     {
8441       tree dst = TREE_VALUE (arglist);
8442       tree src = TREE_VALUE (TREE_CHAIN (arglist));
8443       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8444       const char *p = c_getstr (src);
8445
8446       /* If the requested length is zero, or the src parameter string
8447           length is zero, return the dst parameter.  */
8448       if (integer_zerop (len) || (p && *p == '\0'))
8449         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8450
8451       /* If the requested len is greater than or equal to the string
8452          length, call strcat.  */
8453       if (TREE_CODE (len) == INTEGER_CST && p
8454           && compare_tree_int (len, strlen (p)) >= 0)
8455         {
8456           tree newarglist
8457             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8458           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8459
8460           /* If the replacement _DECL isn't initialized, don't do the
8461              transformation.  */
8462           if (!fn)
8463             return 0;
8464
8465           return build_function_call_expr (fn, newarglist);
8466         }
8467       return 0;
8468     }
8469 }
8470
8471 /* Simplify a call to the strspn builtin.
8472
8473    Return 0 if no simplification was possible, otherwise return the
8474    simplified form of the call as a tree.
8475
8476    The simplified form may be a constant or other expression which
8477    computes the same value, but in a more efficient manner (including
8478    calls to other builtin functions).
8479
8480    The call may contain arguments which need to be evaluated, but
8481    which are not useful to determine the result of the call.  In
8482    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8483    COMPOUND_EXPR will be an argument which must be evaluated.
8484    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8485    COMPOUND_EXPR in the chain will contain the tree for the simplified
8486    form of the builtin function call.  */
8487
8488 static tree
8489 fold_builtin_strspn (tree arglist)
8490 {
8491   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8492     return 0;
8493   else
8494     {
8495       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8496       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8497
8498       /* If both arguments are constants, evaluate at compile-time.  */
8499       if (p1 && p2)
8500         {
8501           const size_t r = strspn (p1, p2);
8502           return size_int (r);
8503         }
8504
8505       /* If either argument is "", return 0.  */
8506       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8507         /* Evaluate and ignore both arguments in case either one has
8508            side-effects.  */
8509         return omit_two_operands (integer_type_node, integer_zero_node,
8510                                   s1, s2);
8511       return 0;
8512     }
8513 }
8514
8515 /* Simplify a call to the strcspn builtin.
8516
8517    Return 0 if no simplification was possible, otherwise return the
8518    simplified form of the call as a tree.
8519
8520    The simplified form may be a constant or other expression which
8521    computes the same value, but in a more efficient manner (including
8522    calls to other builtin functions).
8523
8524    The call may contain arguments which need to be evaluated, but
8525    which are not useful to determine the result of the call.  In
8526    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8527    COMPOUND_EXPR will be an argument which must be evaluated.
8528    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8529    COMPOUND_EXPR in the chain will contain the tree for the simplified
8530    form of the builtin function call.  */
8531
8532 static tree
8533 fold_builtin_strcspn (tree arglist)
8534 {
8535   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8536     return 0;
8537   else
8538     {
8539       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8540       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8541
8542       /* If both arguments are constants, evaluate at compile-time.  */
8543       if (p1 && p2)
8544         {
8545           const size_t r = strcspn (p1, p2);
8546           return size_int (r);
8547         }
8548
8549       /* If the first argument is "", return 0.  */
8550       if (p1 && *p1 == '\0')
8551         {
8552           /* Evaluate and ignore argument s2 in case it has
8553              side-effects.  */
8554           return omit_one_operand (integer_type_node,
8555                                    integer_zero_node, s2);
8556         }
8557
8558       /* If the second argument is "", return __builtin_strlen(s1).  */
8559       if (p2 && *p2 == '\0')
8560         {
8561           tree newarglist = build_tree_list (NULL_TREE, s1),
8562             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8563
8564           /* If the replacement _DECL isn't initialized, don't do the
8565              transformation.  */
8566           if (!fn)
8567             return 0;
8568
8569           return build_function_call_expr (fn, newarglist);
8570         }
8571       return 0;
8572     }
8573 }
8574
8575 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
8576    by the builtin will be ignored.  UNLOCKED is true is true if this
8577    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
8578    the known length of the string.  Return NULL_TREE if no simplification
8579    was possible.  */
8580
8581 tree
8582 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8583 {
8584   tree fn;
8585   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8586     : implicit_built_in_decls[BUILT_IN_FPUTC];
8587   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8588     : implicit_built_in_decls[BUILT_IN_FWRITE];
8589
8590   /* If the return value is used, or the replacement _DECL isn't
8591      initialized, don't do the transformation.  */
8592   if (!ignore || !fn_fputc || !fn_fwrite)
8593     return 0;
8594
8595   /* Verify the arguments in the original call.  */
8596   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8597     return 0;
8598
8599   if (! len)
8600     len = c_strlen (TREE_VALUE (arglist), 0);
8601
8602   /* Get the length of the string passed to fputs.  If the length
8603      can't be determined, punt.  */
8604   if (!len
8605       || TREE_CODE (len) != INTEGER_CST)
8606     return 0;
8607
8608   switch (compare_tree_int (len, 1))
8609     {
8610     case -1: /* length is 0, delete the call entirely .  */
8611       return omit_one_operand (integer_type_node, integer_zero_node,
8612                                TREE_VALUE (TREE_CHAIN (arglist)));
8613
8614     case 0: /* length is 1, call fputc.  */
8615       {
8616         const char *p = c_getstr (TREE_VALUE (arglist));
8617
8618         if (p != NULL)
8619           {
8620             /* New argument list transforming fputs(string, stream) to
8621                fputc(string[0], stream).  */
8622             arglist = build_tree_list (NULL_TREE,
8623                                        TREE_VALUE (TREE_CHAIN (arglist)));
8624             arglist = tree_cons (NULL_TREE,
8625                                  build_int_cst (NULL_TREE, p[0]),
8626                                  arglist);
8627             fn = fn_fputc;
8628             break;
8629           }
8630       }
8631       /* FALLTHROUGH */
8632     case 1: /* length is greater than 1, call fwrite.  */
8633       {
8634         tree string_arg;
8635
8636         /* If optimizing for size keep fputs.  */
8637         if (optimize_size)
8638           return 0;
8639         string_arg = TREE_VALUE (arglist);
8640         /* New argument list transforming fputs(string, stream) to
8641            fwrite(string, 1, len, stream).  */
8642         arglist = build_tree_list (NULL_TREE,
8643                                    TREE_VALUE (TREE_CHAIN (arglist)));
8644         arglist = tree_cons (NULL_TREE, len, arglist);
8645         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8646         arglist = tree_cons (NULL_TREE, string_arg, arglist);
8647         fn = fn_fwrite;
8648         break;
8649       }
8650     default:
8651       gcc_unreachable ();
8652     }
8653
8654   /* These optimizations are only performed when the result is ignored,
8655      hence there's no need to cast the result to integer_type_node.  */
8656   return build_function_call_expr (fn, arglist);
8657 }
8658
8659 /* Fold the new_arg's arguments (ARGLIST). Returns true if there was an error
8660    produced.  False otherwise.  This is done so that we don't output the error
8661    or warning twice or three times.  */
8662 bool
8663 fold_builtin_next_arg (tree arglist)
8664 {
8665   tree fntype = TREE_TYPE (current_function_decl);
8666
8667   if (TYPE_ARG_TYPES (fntype) == 0
8668       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8669           == void_type_node))
8670     {
8671       error ("%<va_start%> used in function with fixed args");
8672       return true;
8673     }
8674   else if (arglist)
8675     {
8676       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8677       tree arg = TREE_VALUE (arglist);
8678
8679       /* Strip off all nops for the sake of the comparison.  This
8680          is not quite the same as STRIP_NOPS.  It does more.
8681          We must also strip off INDIRECT_EXPR for C++ reference
8682          parameters.  */
8683       while (TREE_CODE (arg) == NOP_EXPR
8684              || TREE_CODE (arg) == CONVERT_EXPR
8685              || TREE_CODE (arg) == NON_LVALUE_EXPR
8686              || TREE_CODE (arg) == INDIRECT_REF)
8687         arg = TREE_OPERAND (arg, 0);
8688       if (arg != last_parm)
8689         {
8690           /* FIXME: Sometimes with the tree optimizers we can get the
8691              not the last argument even though the user used the last
8692              argument.  We just warn and set the arg to be the last
8693              argument so that we will get wrong-code because of
8694              it.  */
8695           arg = last_parm;
8696           warning ("second parameter of %<va_start%> not last named argument");
8697         }
8698       TREE_VALUE (arglist) = arg;
8699     }
8700   else
8701     {
8702       /* Evidently an out of date version of <stdarg.h>; can't validate
8703          va_start's second argument, but can still work as intended.  */
8704       warning ("%<__builtin_next_arg%> called without an argument");
8705       return true;
8706     }
8707   return false;
8708 }
8709
8710
8711 /* Simplify a call to the sprintf builtin.
8712
8713    Return 0 if no simplification was possible, otherwise return the
8714    simplified form of the call as a tree.  If IGNORED is true, it means that
8715    the caller does not use the returned value of the function.  */
8716
8717 static tree
8718 fold_builtin_sprintf (tree arglist, int ignored)
8719 {
8720   tree call, retval, dest, fmt;
8721   const char *fmt_str = NULL;
8722
8723   /* Verify the required arguments in the original call.  We deal with two
8724      types of sprintf() calls: 'sprintf (str, fmt)' and
8725      'sprintf (dest, "%s", orig)'.  */
8726   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8727       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8728                             VOID_TYPE))
8729     return NULL_TREE;
8730
8731   /* Get the destination string and the format specifier.  */
8732   dest = TREE_VALUE (arglist);
8733   fmt = TREE_VALUE (TREE_CHAIN (arglist));
8734
8735   /* Check whether the format is a literal string constant.  */
8736   fmt_str = c_getstr (fmt);
8737   if (fmt_str == NULL)
8738     return NULL_TREE;
8739
8740   call = NULL_TREE;
8741   retval = NULL_TREE;
8742
8743   /* If the format doesn't contain % args or %%, use strcpy.  */
8744   if (strchr (fmt_str, '%') == NULL)
8745     {
8746       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8747
8748       if (!fn)
8749         return NULL_TREE;
8750
8751       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8752          'format' is known to contain no % formats.  */
8753       arglist = build_tree_list (NULL_TREE, fmt);
8754       arglist = tree_cons (NULL_TREE, dest, arglist);
8755       call = build_function_call_expr (fn, arglist);
8756       if (!ignored)
8757         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
8758     }
8759
8760   /* If the format is "%s", use strcpy if the result isn't used.  */
8761   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
8762     {
8763       tree fn, orig;
8764       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8765
8766       if (!fn)
8767         return NULL_TREE;
8768
8769       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
8770       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8771       arglist = build_tree_list (NULL_TREE, orig);
8772       arglist = tree_cons (NULL_TREE, dest, arglist);
8773       if (!ignored)
8774         {
8775           retval = c_strlen (orig, 1);
8776           if (!retval || TREE_CODE (retval) != INTEGER_CST)
8777             return NULL_TREE;
8778         }
8779       call = build_function_call_expr (fn, arglist);
8780     }
8781
8782   if (call && retval)
8783     {
8784       retval = convert
8785         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
8786          retval);
8787       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
8788     }
8789   else
8790     return call;
8791 }