OSDN Git Service

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