OSDN Git Service

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