OSDN Git Service

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