OSDN Git Service

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