OSDN Git Service

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