OSDN Git Service

2d3d440ea678003cfc047758f9bdaf175237aaba
[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_2 (3, 0);
907     }
908   else
909     {
910       arg1 = integer_zero_node;
911       arg2 = build_int_2 (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 =
2494         build_tree_list (NULL_TREE, build_int_2 (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 =
2651         build_tree_list (NULL_TREE, build_int_2 (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, arg3));
3834
3835     /* If we don't have POINTER_TYPE, call the function.  */
3836     if (arg1_align == 0 || arg2_align == 0)
3837       return 0;
3838
3839     /* Make a place to write the result of the instruction.  */
3840     result = target;
3841     if (! (result != 0
3842            && REG_P (result) && GET_MODE (result) == insn_mode
3843            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3844       result = gen_reg_rtx (insn_mode);
3845
3846     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3847     arg1 = builtin_save_expr (arg1);
3848     arg2 = builtin_save_expr (arg2);
3849     len = builtin_save_expr (len);
3850
3851     arg1_rtx = get_memory_rtx (arg1);
3852     arg2_rtx = get_memory_rtx (arg2);
3853     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3854     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3855                          GEN_INT (MIN (arg1_align, arg2_align)));
3856     if (insn)
3857       {
3858         emit_insn (insn);
3859
3860         /* Return the value in the proper mode for this function.  */
3861         mode = TYPE_MODE (TREE_TYPE (exp));
3862         if (GET_MODE (result) == mode)
3863           return result;
3864         if (target == 0)
3865           return convert_to_mode (mode, result, 0);
3866         convert_move (target, result, 0);
3867         return target;
3868       }
3869
3870     /* Expand the library call ourselves using a stabilized argument
3871        list to avoid re-evaluating the function's arguments twice.  */
3872     arglist = build_tree_list (NULL_TREE, len);
3873     arglist = tree_cons (NULL_TREE, arg2, arglist);
3874     arglist = tree_cons (NULL_TREE, arg1, arglist);
3875     fndecl = get_callee_fndecl (exp);
3876     exp = build_function_call_expr (fndecl, arglist);
3877     return expand_call (exp, target, target == const0_rtx);
3878   }
3879 #endif
3880   return 0;
3881 }
3882
3883 /* Expand expression EXP, which is a call to the strcat builtin.
3884    Return 0 if we failed the caller should emit a normal call,
3885    otherwise try to get the result in TARGET, if convenient.  */
3886
3887 static rtx
3888 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3889 {
3890   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3891     return 0;
3892   else
3893     {
3894       tree dst = TREE_VALUE (arglist),
3895         src = TREE_VALUE (TREE_CHAIN (arglist));
3896       const char *p = c_getstr (src);
3897
3898       if (p)
3899         {
3900           /* If the string length is zero, return the dst parameter.  */
3901           if (*p == '\0')
3902             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3903           else if (!optimize_size)
3904             {
3905               /* Otherwise if !optimize_size, see if we can store by
3906                  pieces into (dst + strlen(dst)).  */
3907               tree newdst, arglist,
3908                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3909
3910               /* This is the length argument.  */
3911               arglist = build_tree_list (NULL_TREE,
3912                                          fold (size_binop (PLUS_EXPR,
3913                                                            c_strlen (src, 0),
3914                                                            ssize_int (1))));
3915               /* Prepend src argument.  */
3916               arglist = tree_cons (NULL_TREE, src, arglist);
3917
3918               /* We're going to use dst more than once.  */
3919               dst = builtin_save_expr (dst);
3920
3921               /* Create strlen (dst).  */
3922               newdst =
3923                 fold (build_function_call_expr (strlen_fn,
3924                                                 build_tree_list (NULL_TREE,
3925                                                                  dst)));
3926               /* Create (dst + strlen (dst)).  */
3927               newdst = fold (build2 (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3928
3929               /* Prepend the new dst argument.  */
3930               arglist = tree_cons (NULL_TREE, newdst, arglist);
3931
3932               /* We don't want to get turned into a memcpy if the
3933                  target is const0_rtx, i.e. when the return value
3934                  isn't used.  That would produce pessimized code so
3935                  pass in a target of zero, it should never actually be
3936                  used.  If this was successful return the original
3937                  dst, not the result of mempcpy.  */
3938               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3939                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3940               else
3941                 return 0;
3942             }
3943         }
3944
3945       return 0;
3946     }
3947 }
3948
3949 /* Expand expression EXP, which is a call to the strncat builtin.
3950    Return 0 if we failed the caller should emit a normal call,
3951    otherwise try to get the result in TARGET, if convenient.  */
3952
3953 static rtx
3954 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3955 {
3956   if (!validate_arglist (arglist,
3957                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3958     return 0;
3959   else
3960     {
3961       tree dst = TREE_VALUE (arglist),
3962         src = TREE_VALUE (TREE_CHAIN (arglist)),
3963         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3964       const char *p = c_getstr (src);
3965
3966       /* If the requested length is zero, or the src parameter string
3967           length is zero, return the dst parameter.  */
3968       if (integer_zerop (len) || (p && *p == '\0'))
3969         {
3970           /* Evaluate and ignore the src and len parameters in case
3971              they have side-effects.  */
3972           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3973           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3974           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3975         }
3976
3977       /* If the requested len is greater than or equal to the string
3978          length, call strcat.  */
3979       if (TREE_CODE (len) == INTEGER_CST && p
3980           && compare_tree_int (len, strlen (p)) >= 0)
3981         {
3982           tree newarglist
3983             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3984           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3985
3986           /* If the replacement _DECL isn't initialized, don't do the
3987              transformation.  */
3988           if (!fn)
3989             return 0;
3990
3991           return expand_expr (build_function_call_expr (fn, newarglist),
3992                               target, mode, EXPAND_NORMAL);
3993         }
3994       return 0;
3995     }
3996 }
3997
3998 /* Expand expression EXP, which is a call to the strspn builtin.
3999    Return 0 if we failed the caller should emit a normal call,
4000    otherwise try to get the result in TARGET, if convenient.  */
4001
4002 static rtx
4003 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
4004 {
4005   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4006     return 0;
4007   else
4008     {
4009       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4010       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4011
4012       /* If both arguments are constants, evaluate at compile-time.  */
4013       if (p1 && p2)
4014         {
4015           const size_t r = strspn (p1, p2);
4016           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4017         }
4018
4019       /* If either argument is "", return 0.  */
4020       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
4021         {
4022           /* Evaluate and ignore both arguments in case either one has
4023              side-effects.  */
4024           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
4025           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4026           return const0_rtx;
4027         }
4028       return 0;
4029     }
4030 }
4031
4032 /* Expand expression EXP, which is a call to the strcspn builtin.
4033    Return 0 if we failed the caller should emit a normal call,
4034    otherwise try to get the result in TARGET, if convenient.  */
4035
4036 static rtx
4037 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
4038 {
4039   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4040     return 0;
4041   else
4042     {
4043       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
4044       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
4045
4046       /* If both arguments are constants, evaluate at compile-time.  */
4047       if (p1 && p2)
4048         {
4049           const size_t r = strcspn (p1, p2);
4050           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
4051         }
4052
4053       /* If the first argument is "", return 0.  */
4054       if (p1 && *p1 == '\0')
4055         {
4056           /* Evaluate and ignore argument s2 in case it has
4057              side-effects.  */
4058           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
4059           return const0_rtx;
4060         }
4061
4062       /* If the second argument is "", return __builtin_strlen(s1).  */
4063       if (p2 && *p2 == '\0')
4064         {
4065           tree newarglist = build_tree_list (NULL_TREE, s1),
4066             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
4067
4068           /* If the replacement _DECL isn't initialized, don't do the
4069              transformation.  */
4070           if (!fn)
4071             return 0;
4072
4073           return expand_expr (build_function_call_expr (fn, newarglist),
4074                               target, mode, EXPAND_NORMAL);
4075         }
4076       return 0;
4077     }
4078 }
4079
4080 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
4081    if that's convenient.  */
4082
4083 rtx
4084 expand_builtin_saveregs (void)
4085 {
4086   rtx val, seq;
4087
4088   /* Don't do __builtin_saveregs more than once in a function.
4089      Save the result of the first call and reuse it.  */
4090   if (saveregs_value != 0)
4091     return saveregs_value;
4092
4093   /* When this function is called, it means that registers must be
4094      saved on entry to this function.  So we migrate the call to the
4095      first insn of this function.  */
4096
4097   start_sequence ();
4098
4099   /* Do whatever the machine needs done in this case.  */
4100   val = targetm.calls.expand_builtin_saveregs ();
4101
4102   seq = get_insns ();
4103   end_sequence ();
4104
4105   saveregs_value = val;
4106
4107   /* Put the insns after the NOTE that starts the function.  If this
4108      is inside a start_sequence, make the outer-level insn chain current, so
4109      the code is placed at the start of the function.  */
4110   push_topmost_sequence ();
4111   emit_insn_after (seq, entry_of_function ());
4112   pop_topmost_sequence ();
4113
4114   return val;
4115 }
4116
4117 /* __builtin_args_info (N) returns word N of the arg space info
4118    for the current function.  The number and meanings of words
4119    is controlled by the definition of CUMULATIVE_ARGS.  */
4120
4121 static rtx
4122 expand_builtin_args_info (tree arglist)
4123 {
4124   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
4125   int *word_ptr = (int *) &current_function_args_info;
4126
4127   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
4128     abort ();
4129
4130   if (arglist != 0)
4131     {
4132       if (!host_integerp (TREE_VALUE (arglist), 0))
4133         error ("argument of `__builtin_args_info' must be constant");
4134       else
4135         {
4136           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
4137
4138           if (wordnum < 0 || wordnum >= nwords)
4139             error ("argument of `__builtin_args_info' out of range");
4140           else
4141             return GEN_INT (word_ptr[wordnum]);
4142         }
4143     }
4144   else
4145     error ("missing argument in `__builtin_args_info'");
4146
4147   return const0_rtx;
4148 }
4149
4150 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
4151
4152 static rtx
4153 expand_builtin_next_arg (tree arglist)
4154 {
4155   tree fntype = TREE_TYPE (current_function_decl);
4156
4157   if (TYPE_ARG_TYPES (fntype) == 0
4158       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4159           == void_type_node))
4160     {
4161       error ("`va_start' used in function with fixed args");
4162       return const0_rtx;
4163     }
4164
4165   if (arglist)
4166     {
4167       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
4168       tree arg = TREE_VALUE (arglist);
4169
4170       /* Strip off all nops for the sake of the comparison.  This
4171          is not quite the same as STRIP_NOPS.  It does more.
4172          We must also strip off INDIRECT_EXPR for C++ reference
4173          parameters.  */
4174       while (TREE_CODE (arg) == NOP_EXPR
4175              || TREE_CODE (arg) == CONVERT_EXPR
4176              || TREE_CODE (arg) == NON_LVALUE_EXPR
4177              || TREE_CODE (arg) == INDIRECT_REF)
4178         arg = TREE_OPERAND (arg, 0);
4179       if (arg != last_parm)
4180         warning ("second parameter of `va_start' not last named argument");
4181     }
4182   else
4183     /* Evidently an out of date version of <stdarg.h>; can't validate
4184        va_start's second argument, but can still work as intended.  */
4185     warning ("`__builtin_next_arg' called without an argument");
4186
4187   return expand_binop (Pmode, add_optab,
4188                        current_function_internal_arg_pointer,
4189                        current_function_arg_offset_rtx,
4190                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
4191 }
4192
4193 /* Make it easier for the backends by protecting the valist argument
4194    from multiple evaluations.  */
4195
4196 static tree
4197 stabilize_va_list (tree valist, int needs_lvalue)
4198 {
4199   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4200     {
4201       if (TREE_SIDE_EFFECTS (valist))
4202         valist = save_expr (valist);
4203
4204       /* For this case, the backends will be expecting a pointer to
4205          TREE_TYPE (va_list_type_node), but it's possible we've
4206          actually been given an array (an actual va_list_type_node).
4207          So fix it.  */
4208       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4209         {
4210           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4211           valist = build_fold_addr_expr_with_type (valist, p1);
4212         }
4213     }
4214   else
4215     {
4216       tree pt;
4217
4218       if (! needs_lvalue)
4219         {
4220           if (! TREE_SIDE_EFFECTS (valist))
4221             return valist;
4222
4223           pt = build_pointer_type (va_list_type_node);
4224           valist = fold (build1 (ADDR_EXPR, pt, valist));
4225           TREE_SIDE_EFFECTS (valist) = 1;
4226         }
4227
4228       if (TREE_SIDE_EFFECTS (valist))
4229         valist = save_expr (valist);
4230       valist = build_fold_indirect_ref (valist);
4231     }
4232
4233   return valist;
4234 }
4235
4236 /* The "standard" definition of va_list is void*.  */
4237
4238 tree
4239 std_build_builtin_va_list (void)
4240 {
4241   return ptr_type_node;
4242 }
4243
4244 /* The "standard" implementation of va_start: just assign `nextarg' to
4245    the variable.  */
4246
4247 void
4248 std_expand_builtin_va_start (tree valist, rtx nextarg)
4249 {
4250   tree t;
4251
4252   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
4253               make_tree (ptr_type_node, nextarg));
4254   TREE_SIDE_EFFECTS (t) = 1;
4255
4256   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4257 }
4258
4259 /* Expand ARGLIST, from a call to __builtin_va_start.  */
4260
4261 static rtx
4262 expand_builtin_va_start (tree arglist)
4263 {
4264   rtx nextarg;
4265   tree chain, valist;
4266
4267   chain = TREE_CHAIN (arglist);
4268
4269   if (TREE_CHAIN (chain))
4270     error ("too many arguments to function `va_start'");
4271
4272   nextarg = expand_builtin_next_arg (chain);
4273   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
4274
4275 #ifdef EXPAND_BUILTIN_VA_START
4276   EXPAND_BUILTIN_VA_START (valist, nextarg);
4277 #else
4278   std_expand_builtin_va_start (valist, nextarg);
4279 #endif
4280
4281   return const0_rtx;
4282 }
4283
4284 /* The "standard" implementation of va_arg: read the value from the
4285    current (padded) address and increment by the (padded) size.  */
4286
4287 tree
4288 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
4289 {
4290   tree addr, t, type_size, rounded_size, valist_tmp;
4291   unsigned HOST_WIDE_INT align, boundary;
4292   bool indirect;
4293
4294 #ifdef ARGS_GROW_DOWNWARD
4295   /* All of the alignment and movement below is for args-grow-up machines.
4296      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
4297      implement their own specialized gimplify_va_arg_expr routines.  */
4298   abort ();
4299 #endif
4300
4301   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
4302   if (indirect)
4303     type = build_pointer_type (type);
4304
4305   align = PARM_BOUNDARY / BITS_PER_UNIT;
4306   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
4307
4308   /* Hoist the valist value into a temporary for the moment.  */
4309   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
4310
4311   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
4312      requires greater alignment, we must perform dynamic alignment.  */
4313   if (boundary > align)
4314     {
4315       t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
4316       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4317                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
4318       gimplify_and_add (t, pre_p);
4319
4320       t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
4321       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
4322                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
4323       gimplify_and_add (t, pre_p);
4324     }
4325
4326   /* Compute the rounded size of the type.  */
4327   type_size = size_in_bytes (type);
4328   rounded_size = round_up (type_size, align);
4329
4330   /* Reduce rounded_size so it's sharable with the postqueue.  */
4331   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
4332
4333   /* Get AP.  */
4334   addr = valist_tmp;
4335   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
4336     {
4337       /* Small args are padded downward.  */
4338       t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
4339       t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
4340                         size_binop (MINUS_EXPR, rounded_size, type_size)));
4341       t = fold_convert (TREE_TYPE (addr), t);
4342       addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
4343     }
4344
4345   /* Compute new value for AP.  */
4346   t = fold_convert (TREE_TYPE (valist), rounded_size);
4347   t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
4348   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
4349   gimplify_and_add (t, pre_p);
4350
4351   addr = fold_convert (build_pointer_type (type), addr);
4352
4353   if (indirect)
4354     addr = build_fold_indirect_ref (addr);
4355
4356   return build_fold_indirect_ref (addr);
4357 }
4358
4359 /* Return a dummy expression of type TYPE in order to keep going after an
4360    error.  */
4361
4362 static tree
4363 dummy_object (tree type)
4364 {
4365   tree t = convert (build_pointer_type (type), null_pointer_node);
4366   return build1 (INDIRECT_REF, type, t);
4367 }
4368
4369 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
4370    builtin function, but a very special sort of operator.  */
4371
4372 enum gimplify_status
4373 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
4374 {
4375   tree promoted_type, want_va_type, have_va_type;
4376   tree valist = TREE_OPERAND (*expr_p, 0);
4377   tree type = TREE_TYPE (*expr_p);
4378   tree t;
4379
4380   /* Verify that valist is of the proper type.  */
4381   want_va_type = va_list_type_node;
4382   have_va_type = TREE_TYPE (valist);
4383
4384   if (have_va_type == error_mark_node)
4385     return GS_ERROR;
4386
4387   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4388     {
4389       /* If va_list is an array type, the argument may have decayed
4390          to a pointer type, e.g. by being passed to another function.
4391          In that case, unwrap both types so that we can compare the
4392          underlying records.  */
4393       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4394           || TREE_CODE (have_va_type) == POINTER_TYPE)
4395         {
4396           want_va_type = TREE_TYPE (want_va_type);
4397           have_va_type = TREE_TYPE (have_va_type);
4398         }
4399     }
4400
4401   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4402     {
4403       error ("first argument to `va_arg' not of type `va_list'");
4404       return GS_ERROR;
4405     }
4406
4407   /* Generate a diagnostic for requesting data of a type that cannot
4408      be passed through `...' due to type promotion at the call site.  */
4409   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4410            != type)
4411     {
4412       static bool gave_help;
4413
4414       /* Unfortunately, this is merely undefined, rather than a constraint
4415          violation, so we cannot make this an error.  If this call is never
4416          executed, the program is still strictly conforming.  */
4417       warning ("`%T' is promoted to `%T' when passed through `...'",
4418                type, promoted_type);
4419       if (! gave_help)
4420         {
4421           gave_help = true;
4422           warning ("(so you should pass `%T' not `%T' to `va_arg')",
4423                    promoted_type, type);
4424         }
4425
4426       /* We can, however, treat "undefined" any way we please.
4427          Call abort to encourage the user to fix the program.  */
4428       inform ("if this code is reached, the program will abort");
4429       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4430                                     NULL);
4431       append_to_statement_list (t, pre_p);
4432
4433       /* This is dead code, but go ahead and finish so that the
4434          mode of the result comes out right.  */
4435       *expr_p = dummy_object (type);
4436       return GS_ALL_DONE;
4437     }
4438   else
4439     {
4440       /* Make it easier for the backends by protecting the valist argument
4441          from multiple evaluations.  */
4442       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4443         {
4444           /* For this case, the backends will be expecting a pointer to
4445              TREE_TYPE (va_list_type_node), but it's possible we've
4446              actually been given an array (an actual va_list_type_node).
4447              So fix it.  */
4448           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4449             {
4450               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4451               valist = build_fold_addr_expr_with_type (valist, p1);
4452             }
4453           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4454         }
4455       else
4456         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4457
4458       if (!targetm.gimplify_va_arg_expr)
4459         /* Once most targets are converted this should abort.  */
4460         return GS_ALL_DONE;
4461
4462       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4463       return GS_OK;
4464     }
4465 }
4466
4467 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4468
4469 static rtx
4470 expand_builtin_va_end (tree arglist)
4471 {
4472   tree valist = TREE_VALUE (arglist);
4473
4474   /* Evaluate for side effects, if needed.  I hate macros that don't
4475      do that.  */
4476   if (TREE_SIDE_EFFECTS (valist))
4477     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4478
4479   return const0_rtx;
4480 }
4481
4482 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4483    builtin rather than just as an assignment in stdarg.h because of the
4484    nastiness of array-type va_list types.  */
4485
4486 static rtx
4487 expand_builtin_va_copy (tree arglist)
4488 {
4489   tree dst, src, t;
4490
4491   dst = TREE_VALUE (arglist);
4492   src = TREE_VALUE (TREE_CHAIN (arglist));
4493
4494   dst = stabilize_va_list (dst, 1);
4495   src = stabilize_va_list (src, 0);
4496
4497   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4498     {
4499       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4500       TREE_SIDE_EFFECTS (t) = 1;
4501       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4502     }
4503   else
4504     {
4505       rtx dstb, srcb, size;
4506
4507       /* Evaluate to pointers.  */
4508       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4509       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4510       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4511                           VOIDmode, EXPAND_NORMAL);
4512
4513       dstb = convert_memory_address (Pmode, dstb);
4514       srcb = convert_memory_address (Pmode, srcb);
4515
4516       /* "Dereference" to BLKmode memories.  */
4517       dstb = gen_rtx_MEM (BLKmode, dstb);
4518       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4519       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4520       srcb = gen_rtx_MEM (BLKmode, srcb);
4521       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4522       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4523
4524       /* Copy.  */
4525       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4526     }
4527
4528   return const0_rtx;
4529 }
4530
4531 /* Expand a call to one of the builtin functions __builtin_frame_address or
4532    __builtin_return_address.  */
4533
4534 static rtx
4535 expand_builtin_frame_address (tree fndecl, tree arglist)
4536 {
4537   /* The argument must be a nonnegative integer constant.
4538      It counts the number of frames to scan up the stack.
4539      The value is the return address saved in that frame.  */
4540   if (arglist == 0)
4541     /* Warning about missing arg was already issued.  */
4542     return const0_rtx;
4543   else if (! host_integerp (TREE_VALUE (arglist), 1))
4544     {
4545       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4546         error ("invalid arg to `__builtin_frame_address'");
4547       else
4548         error ("invalid arg to `__builtin_return_address'");
4549       return const0_rtx;
4550     }
4551   else
4552     {
4553       rtx tem
4554         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4555                                       tree_low_cst (TREE_VALUE (arglist), 1),
4556                                       hard_frame_pointer_rtx);
4557
4558       /* Some ports cannot access arbitrary stack frames.  */
4559       if (tem == NULL)
4560         {
4561           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4562             warning ("unsupported arg to `__builtin_frame_address'");
4563           else
4564             warning ("unsupported arg to `__builtin_return_address'");
4565           return const0_rtx;
4566         }
4567
4568       /* For __builtin_frame_address, return what we've got.  */
4569       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4570         return tem;
4571
4572       if (!REG_P (tem)
4573           && ! CONSTANT_P (tem))
4574         tem = copy_to_mode_reg (Pmode, tem);
4575       return tem;
4576     }
4577 }
4578
4579 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4580    we failed and the caller should emit a normal call, otherwise try to get
4581    the result in TARGET, if convenient.  */
4582
4583 static rtx
4584 expand_builtin_alloca (tree arglist, rtx target)
4585 {
4586   rtx op0;
4587   rtx result;
4588
4589   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4590      should always expand to function calls.  These can be intercepted
4591      in libmudflap.  */
4592   if (flag_mudflap)
4593     return 0;
4594
4595   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4596     return 0;
4597
4598   /* Compute the argument.  */
4599   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4600
4601   /* Allocate the desired space.  */
4602   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4603   result = convert_memory_address (ptr_mode, result);
4604
4605   return result;
4606 }
4607
4608 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4609    Return 0 if a normal call should be emitted rather than expanding the
4610    function in-line.  If convenient, the result should be placed in TARGET.
4611    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4612
4613 static rtx
4614 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4615                      rtx subtarget, optab op_optab)
4616 {
4617   rtx op0;
4618   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4619     return 0;
4620
4621   /* Compute the argument.  */
4622   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4623   /* Compute op, into TARGET if possible.
4624      Set TARGET to wherever the result comes back.  */
4625   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4626                         op_optab, op0, target, 1);
4627   if (target == 0)
4628     abort ();
4629
4630   return convert_to_mode (target_mode, target, 0);
4631 }
4632
4633 /* If the string passed to fputs is a constant and is one character
4634    long, we attempt to transform this call into __builtin_fputc().  */
4635
4636 static rtx
4637 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4638 {
4639   tree len, fn;
4640   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4641     : implicit_built_in_decls[BUILT_IN_FPUTC];
4642   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4643     : implicit_built_in_decls[BUILT_IN_FWRITE];
4644
4645   /* If the return value is used, or the replacement _DECL isn't
4646      initialized, don't do the transformation.  */
4647   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4648     return 0;
4649
4650   /* Verify the arguments in the original call.  */
4651   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4652     return 0;
4653
4654   /* Get the length of the string passed to fputs.  If the length
4655      can't be determined, punt.  */
4656   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4657       || TREE_CODE (len) != INTEGER_CST)
4658     return 0;
4659
4660   switch (compare_tree_int (len, 1))
4661     {
4662     case -1: /* length is 0, delete the call entirely .  */
4663       {
4664         /* Evaluate and ignore the argument in case it has
4665            side-effects.  */
4666         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4667                      VOIDmode, EXPAND_NORMAL);
4668         return const0_rtx;
4669       }
4670     case 0: /* length is 1, call fputc.  */
4671       {
4672         const char *p = c_getstr (TREE_VALUE (arglist));
4673
4674         if (p != NULL)
4675           {
4676             /* New argument list transforming fputs(string, stream) to
4677                fputc(string[0], stream).  */
4678             arglist =
4679               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4680             arglist =
4681               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4682             fn = fn_fputc;
4683             break;
4684           }
4685       }
4686       /* Fall through.  */
4687     case 1: /* length is greater than 1, call fwrite.  */
4688       {
4689         tree string_arg;
4690
4691         /* If optimizing for size keep fputs.  */
4692         if (optimize_size)
4693           return 0;
4694         string_arg = TREE_VALUE (arglist);
4695         /* New argument list transforming fputs(string, stream) to
4696            fwrite(string, 1, len, stream).  */
4697         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4698         arglist = tree_cons (NULL_TREE, len, arglist);
4699         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4700         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4701         fn = fn_fwrite;
4702         break;
4703       }
4704     default:
4705       abort ();
4706     }
4707
4708   return expand_expr (build_function_call_expr (fn, arglist),
4709                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4710 }
4711
4712 /* Expand a call to __builtin_expect.  We return our argument and emit a
4713    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4714    a non-jump context.  */
4715
4716 static rtx
4717 expand_builtin_expect (tree arglist, rtx target)
4718 {
4719   tree exp, c;
4720   rtx note, rtx_c;
4721
4722   if (arglist == NULL_TREE
4723       || TREE_CHAIN (arglist) == NULL_TREE)
4724     return const0_rtx;
4725   exp = TREE_VALUE (arglist);
4726   c = TREE_VALUE (TREE_CHAIN (arglist));
4727
4728   if (TREE_CODE (c) != INTEGER_CST)
4729     {
4730       error ("second arg to `__builtin_expect' must be a constant");
4731       c = integer_zero_node;
4732     }
4733
4734   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4735
4736   /* Don't bother with expected value notes for integral constants.  */
4737   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4738     {
4739       /* We do need to force this into a register so that we can be
4740          moderately sure to be able to correctly interpret the branch
4741          condition later.  */
4742       target = force_reg (GET_MODE (target), target);
4743
4744       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4745
4746       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4747       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4748     }
4749
4750   return target;
4751 }
4752
4753 /* Like expand_builtin_expect, except do this in a jump context.  This is
4754    called from do_jump if the conditional is a __builtin_expect.  Return either
4755    a list of insns to emit the jump or NULL if we cannot optimize
4756    __builtin_expect.  We need to optimize this at jump time so that machines
4757    like the PowerPC don't turn the test into a SCC operation, and then jump
4758    based on the test being 0/1.  */
4759
4760 rtx
4761 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4762 {
4763   tree arglist = TREE_OPERAND (exp, 1);
4764   tree arg0 = TREE_VALUE (arglist);
4765   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4766   rtx ret = NULL_RTX;
4767
4768   /* Only handle __builtin_expect (test, 0) and
4769      __builtin_expect (test, 1).  */
4770   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4771       && (integer_zerop (arg1) || integer_onep (arg1)))
4772     {
4773       rtx insn, drop_through_label, temp;
4774
4775       /* Expand the jump insns.  */
4776       start_sequence ();
4777       do_jump (arg0, if_false_label, if_true_label);
4778       ret = get_insns ();
4779
4780       drop_through_label = get_last_insn ();
4781       if (drop_through_label && NOTE_P (drop_through_label))
4782         drop_through_label = prev_nonnote_insn (drop_through_label);
4783       if (drop_through_label && !LABEL_P (drop_through_label))
4784         drop_through_label = NULL_RTX;
4785       end_sequence ();
4786
4787       if (! if_true_label)
4788         if_true_label = drop_through_label;
4789       if (! if_false_label)
4790         if_false_label = drop_through_label;
4791
4792       /* Go through and add the expect's to each of the conditional jumps.  */
4793       insn = ret;
4794       while (insn != NULL_RTX)
4795         {
4796           rtx next = NEXT_INSN (insn);
4797
4798           if (JUMP_P (insn) && any_condjump_p (insn))
4799             {
4800               rtx ifelse = SET_SRC (pc_set (insn));
4801               rtx then_dest = XEXP (ifelse, 1);
4802               rtx else_dest = XEXP (ifelse, 2);
4803               int taken = -1;
4804
4805               /* First check if we recognize any of the labels.  */
4806               if (GET_CODE (then_dest) == LABEL_REF
4807                   && XEXP (then_dest, 0) == if_true_label)
4808                 taken = 1;
4809               else if (GET_CODE (then_dest) == LABEL_REF
4810                        && XEXP (then_dest, 0) == if_false_label)
4811                 taken = 0;
4812               else if (GET_CODE (else_dest) == LABEL_REF
4813                        && XEXP (else_dest, 0) == if_false_label)
4814                 taken = 1;
4815               else if (GET_CODE (else_dest) == LABEL_REF
4816                        && XEXP (else_dest, 0) == if_true_label)
4817                 taken = 0;
4818               /* Otherwise check where we drop through.  */
4819               else if (else_dest == pc_rtx)
4820                 {
4821                   if (next && NOTE_P (next))
4822                     next = next_nonnote_insn (next);
4823
4824                   if (next && JUMP_P (next)
4825                       && any_uncondjump_p (next))
4826                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4827                   else
4828                     temp = next;
4829
4830                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4831                      else that can't possibly match either target label.  */
4832                   if (temp == if_false_label)
4833                     taken = 1;
4834                   else if (temp == if_true_label)
4835                     taken = 0;
4836                 }
4837               else if (then_dest == pc_rtx)
4838                 {
4839                   if (next && NOTE_P (next))
4840                     next = next_nonnote_insn (next);
4841
4842                   if (next && JUMP_P (next)
4843                       && any_uncondjump_p (next))
4844                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4845                   else
4846                     temp = next;
4847
4848                   if (temp == if_false_label)
4849                     taken = 0;
4850                   else if (temp == if_true_label)
4851                     taken = 1;
4852                 }
4853
4854               if (taken != -1)
4855                 {
4856                   /* If the test is expected to fail, reverse the
4857                      probabilities.  */
4858                   if (integer_zerop (arg1))
4859                     taken = 1 - taken;
4860                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4861                 }
4862             }
4863
4864           insn = next;
4865         }
4866     }
4867
4868   return ret;
4869 }
4870
4871 void
4872 expand_builtin_trap (void)
4873 {
4874 #ifdef HAVE_trap
4875   if (HAVE_trap)
4876     emit_insn (gen_trap ());
4877   else
4878 #endif
4879     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4880   emit_barrier ();
4881 }
4882
4883 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4884    Return 0 if a normal call should be emitted rather than expanding
4885    the function inline.  If convenient, the result should be placed
4886    in TARGET.  SUBTARGET may be used as the target for computing
4887    the operand.  */
4888
4889 static rtx
4890 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4891 {
4892   enum machine_mode mode;
4893   tree arg;
4894   rtx op0;
4895
4896   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4897     return 0;
4898
4899   arg = TREE_VALUE (arglist);
4900   mode = TYPE_MODE (TREE_TYPE (arg));
4901   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4902   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4903 }
4904
4905 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4906    Return 0 if a normal call should be emitted rather than expanding
4907    the function inline.  If convenient, the result should be placed
4908    in target.  */
4909
4910 static rtx
4911 expand_builtin_cabs (tree arglist, rtx target)
4912 {
4913   enum machine_mode mode;
4914   tree arg;
4915   rtx op0;
4916
4917   if (arglist == 0 || TREE_CHAIN (arglist))
4918     return 0;
4919   arg = TREE_VALUE (arglist);
4920   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4921       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4922     return 0;
4923
4924   mode = TYPE_MODE (TREE_TYPE (arg));
4925   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4926   return expand_complex_abs (mode, op0, target, 0);
4927 }
4928
4929 /* Create a new constant string literal and return a char* pointer to it.
4930    The STRING_CST value is the LEN characters at STR.  */
4931 static tree
4932 build_string_literal (int len, const char *str)
4933 {
4934   tree t, elem, index, type;
4935
4936   t = build_string (len, str);
4937   elem = build_type_variant (char_type_node, 1, 0);
4938   index = build_index_type (build_int_2 (len - 1, 0));
4939   type = build_array_type (elem, index);
4940   TREE_TYPE (t) = type;
4941   TREE_CONSTANT (t) = 1;
4942   TREE_INVARIANT (t) = 1;
4943   TREE_READONLY (t) = 1;
4944   TREE_STATIC (t) = 1;
4945
4946   type = build_pointer_type (type);
4947   t = build1 (ADDR_EXPR, type, t);
4948
4949   type = build_pointer_type (elem);
4950   t = build1 (NOP_EXPR, type, t);
4951   return t;
4952 }
4953
4954 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4955    Return 0 if a normal call should be emitted rather than transforming
4956    the function inline.  If convenient, the result should be placed in
4957    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4958    call.  */
4959 static rtx
4960 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4961                        bool unlocked)
4962 {
4963   tree fn_putchar = unlocked
4964                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4965                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4966   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4967                           : implicit_built_in_decls[BUILT_IN_PUTS];
4968   const char *fmt_str;
4969   tree fn, fmt, arg;
4970
4971   /* If the return value is used, don't do the transformation.  */
4972   if (target != const0_rtx)
4973     return 0;
4974
4975   /* Verify the required arguments in the original call.  */
4976   if (! arglist)
4977     return 0;
4978   fmt = TREE_VALUE (arglist);
4979   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4980     return 0;
4981   arglist = TREE_CHAIN (arglist);
4982
4983   /* Check whether the format is a literal string constant.  */
4984   fmt_str = c_getstr (fmt);
4985   if (fmt_str == NULL)
4986     return 0;
4987
4988   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4989   if (strcmp (fmt_str, "%s\n") == 0)
4990     {
4991       if (! arglist
4992           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4993           || TREE_CHAIN (arglist))
4994         return 0;
4995       fn = fn_puts;
4996     }
4997   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4998   else if (strcmp (fmt_str, "%c") == 0)
4999     {
5000       if (! arglist
5001           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5002           || TREE_CHAIN (arglist))
5003         return 0;
5004       fn = fn_putchar;
5005     }
5006   else
5007     {
5008       /* We can't handle anything else with % args or %% ... yet.  */
5009       if (strchr (fmt_str, '%'))
5010         return 0;
5011
5012       if (arglist)
5013         return 0;
5014
5015       /* If the format specifier was "", printf does nothing.  */
5016       if (fmt_str[0] == '\0')
5017         return const0_rtx;
5018       /* If the format specifier has length of 1, call putchar.  */
5019       if (fmt_str[1] == '\0')
5020         {
5021           /* Given printf("c"), (where c is any one character,)
5022              convert "c"[0] to an int and pass that to the replacement
5023              function.  */
5024           arg = build_int_2 (fmt_str[0], 0);
5025           arglist = build_tree_list (NULL_TREE, arg);
5026           fn = fn_putchar;
5027         }
5028       else
5029         {
5030           /* If the format specifier was "string\n", call puts("string").  */
5031           size_t len = strlen (fmt_str);
5032           if (fmt_str[len - 1] == '\n')
5033             {
5034               /* Create a NUL-terminated string that's one char shorter
5035                  than the original, stripping off the trailing '\n'.  */
5036               char *newstr = alloca (len);
5037               memcpy (newstr, fmt_str, len - 1);
5038               newstr[len - 1] = 0;
5039
5040               arg = build_string_literal (len, newstr);
5041               arglist = build_tree_list (NULL_TREE, arg);
5042               fn = fn_puts;
5043             }
5044           else
5045             /* We'd like to arrange to call fputs(string,stdout) here,
5046                but we need stdout and don't have a way to get it yet.  */
5047             return 0;
5048         }
5049     }
5050
5051   if (!fn)
5052     return 0;
5053   return expand_expr (build_function_call_expr (fn, arglist),
5054                       target, mode, EXPAND_NORMAL);
5055 }
5056
5057 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
5058    Return 0 if a normal call should be emitted rather than transforming
5059    the function inline.  If convenient, the result should be placed in
5060    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
5061    call.  */
5062 static rtx
5063 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
5064                         bool unlocked)
5065 {
5066   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
5067                            : implicit_built_in_decls[BUILT_IN_FPUTC];
5068   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
5069                            : implicit_built_in_decls[BUILT_IN_FPUTS];
5070   const char *fmt_str;
5071   tree fn, fmt, fp, arg;
5072
5073   /* If the return value is used, don't do the transformation.  */
5074   if (target != const0_rtx)
5075     return 0;
5076
5077   /* Verify the required arguments in the original call.  */
5078   if (! arglist)
5079     return 0;
5080   fp = TREE_VALUE (arglist);
5081   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
5082     return 0;
5083   arglist = TREE_CHAIN (arglist);
5084   if (! arglist)
5085     return 0;
5086   fmt = TREE_VALUE (arglist);
5087   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5088     return 0;
5089   arglist = TREE_CHAIN (arglist);
5090
5091   /* Check whether the format is a literal string constant.  */
5092   fmt_str = c_getstr (fmt);
5093   if (fmt_str == NULL)
5094     return 0;
5095
5096   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
5097   if (strcmp (fmt_str, "%s") == 0)
5098     {
5099       if (! arglist
5100           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
5101           || TREE_CHAIN (arglist))
5102         return 0;
5103       arg = TREE_VALUE (arglist);
5104       arglist = build_tree_list (NULL_TREE, fp);
5105       arglist = tree_cons (NULL_TREE, arg, arglist);
5106       fn = fn_fputs;
5107     }
5108   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
5109   else if (strcmp (fmt_str, "%c") == 0)
5110     {
5111       if (! arglist
5112           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
5113           || TREE_CHAIN (arglist))
5114         return 0;
5115       arg = TREE_VALUE (arglist);
5116       arglist = build_tree_list (NULL_TREE, fp);
5117       arglist = tree_cons (NULL_TREE, arg, arglist);
5118       fn = fn_fputc;
5119     }
5120   else
5121     {
5122       /* We can't handle anything else with % args or %% ... yet.  */
5123       if (strchr (fmt_str, '%'))
5124         return 0;
5125
5126       if (arglist)
5127         return 0;
5128
5129       /* If the format specifier was "", fprintf does nothing.  */
5130       if (fmt_str[0] == '\0')
5131         {
5132           /* Evaluate and ignore FILE* argument for side-effects.  */
5133           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
5134           return const0_rtx;
5135         }
5136
5137       /* When "string" doesn't contain %, replace all cases of
5138          fprintf(stream,string) with fputs(string,stream).  The fputs
5139          builtin will take care of special cases like length == 1.  */
5140       arglist = build_tree_list (NULL_TREE, fp);
5141       arglist = tree_cons (NULL_TREE, fmt, arglist);
5142       fn = fn_fputs;
5143     }
5144
5145   if (!fn)
5146     return 0;
5147   return expand_expr (build_function_call_expr (fn, arglist),
5148                       target, mode, EXPAND_NORMAL);
5149 }
5150
5151 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
5152    a normal call should be emitted rather than expanding the function
5153    inline.  If convenient, the result should be placed in TARGET with
5154    mode MODE.  */
5155
5156 static rtx
5157 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
5158 {
5159   tree orig_arglist, dest, fmt;
5160   const char *fmt_str;
5161
5162   orig_arglist = arglist;
5163
5164   /* Verify the required arguments in the original call.  */
5165   if (! arglist)
5166     return 0;
5167   dest = TREE_VALUE (arglist);
5168   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
5169     return 0;
5170   arglist = TREE_CHAIN (arglist);
5171   if (! arglist)
5172     return 0;
5173   fmt = TREE_VALUE (arglist);
5174   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
5175     return 0;
5176   arglist = TREE_CHAIN (arglist);
5177
5178   /* Check whether the format is a literal string constant.  */
5179   fmt_str = c_getstr (fmt);
5180   if (fmt_str == NULL)
5181     return 0;
5182
5183   /* If the format doesn't contain % args or %%, use strcpy.  */
5184   if (strchr (fmt_str, '%') == 0)
5185     {
5186       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5187       tree exp;
5188
5189       if (arglist || ! fn)
5190         return 0;
5191       expand_expr (build_function_call_expr (fn, orig_arglist),
5192                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5193       if (target == const0_rtx)
5194         return const0_rtx;
5195       exp = build_int_2 (strlen (fmt_str), 0);
5196       exp = fold_convert (integer_type_node, exp);
5197       return expand_expr (exp, target, mode, EXPAND_NORMAL);
5198     }
5199   /* If the format is "%s", use strcpy if the result isn't used.  */
5200   else if (strcmp (fmt_str, "%s") == 0)
5201     {
5202       tree fn, arg, len;
5203       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
5204
5205       if (! fn)
5206         return 0;
5207
5208       if (! arglist || TREE_CHAIN (arglist))
5209         return 0;
5210       arg = TREE_VALUE (arglist);
5211       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
5212         return 0;
5213
5214       if (target != const0_rtx)
5215         {
5216           len = c_strlen (arg, 1);
5217           if (! len || TREE_CODE (len) != INTEGER_CST)
5218             return 0;
5219         }
5220       else
5221         len = NULL_TREE;
5222
5223       arglist = build_tree_list (NULL_TREE, arg);
5224       arglist = tree_cons (NULL_TREE, dest, arglist);
5225       expand_expr (build_function_call_expr (fn, arglist),
5226                    const0_rtx, VOIDmode, EXPAND_NORMAL);
5227
5228       if (target == const0_rtx)
5229         return const0_rtx;
5230       return expand_expr (len, target, mode, EXPAND_NORMAL);
5231     }
5232
5233   return 0;
5234 }
5235
5236 /* Expand a call to either the entry or exit function profiler.  */
5237
5238 static rtx
5239 expand_builtin_profile_func (bool exitp)
5240 {
5241   rtx this, which;
5242
5243   this = DECL_RTL (current_function_decl);
5244   if (MEM_P (this))
5245     this = XEXP (this, 0);
5246   else
5247     abort ();
5248
5249   if (exitp)
5250     which = profile_function_exit_libfunc;
5251   else
5252     which = profile_function_entry_libfunc;
5253
5254   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
5255                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
5256                                                  0, hard_frame_pointer_rtx),
5257                      Pmode);
5258
5259   return const0_rtx;
5260 }
5261
5262 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
5263
5264 static rtx
5265 round_trampoline_addr (rtx tramp)
5266 {
5267   rtx temp, addend, mask;
5268
5269   /* If we don't need too much alignment, we'll have been guaranteed
5270      proper alignment by get_trampoline_type.  */
5271   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
5272     return tramp;
5273
5274   /* Round address up to desired boundary.  */
5275   temp = gen_reg_rtx (Pmode);
5276   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
5277   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
5278
5279   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
5280                                temp, 0, OPTAB_LIB_WIDEN);
5281   tramp = expand_simple_binop (Pmode, AND, temp, mask,
5282                                temp, 0, OPTAB_LIB_WIDEN);
5283
5284   return tramp;
5285 }
5286
5287 static rtx
5288 expand_builtin_init_trampoline (tree arglist)
5289 {
5290   tree t_tramp, t_func, t_chain;
5291   rtx r_tramp, r_func, r_chain;
5292 #ifdef TRAMPOLINE_TEMPLATE
5293   rtx blktramp;
5294 #endif
5295
5296   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
5297                          POINTER_TYPE, VOID_TYPE))
5298     return NULL_RTX;
5299
5300   t_tramp = TREE_VALUE (arglist);
5301   arglist = TREE_CHAIN (arglist);
5302   t_func = TREE_VALUE (arglist);
5303   arglist = TREE_CHAIN (arglist);
5304   t_chain = TREE_VALUE (arglist);
5305
5306   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
5307   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
5308   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
5309
5310   /* Generate insns to initialize the trampoline.  */
5311   r_tramp = round_trampoline_addr (r_tramp);
5312 #ifdef TRAMPOLINE_TEMPLATE
5313   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
5314   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
5315   emit_block_move (blktramp, assemble_trampoline_template (),
5316                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
5317 #endif
5318   trampolines_created = 1;
5319   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
5320
5321   return const0_rtx;
5322 }
5323
5324 static rtx
5325 expand_builtin_adjust_trampoline (tree arglist)
5326 {
5327   rtx tramp;
5328
5329   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5330     return NULL_RTX;
5331
5332   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5333   tramp = round_trampoline_addr (tramp);
5334 #ifdef TRAMPOLINE_ADJUST_ADDRESS
5335   TRAMPOLINE_ADJUST_ADDRESS (tramp);
5336 #endif
5337
5338   return tramp;
5339 }
5340
5341 /* Expand a call to the built-in signbit, signbitf or signbitl function.
5342    Return NULL_RTX if a normal call should be emitted rather than expanding
5343    the function in-line.  EXP is the expression that is a call to the builtin
5344    function; if convenient, the result should be placed in TARGET.  */
5345
5346 static rtx
5347 expand_builtin_signbit (tree exp, rtx target)
5348 {
5349   const struct real_format *fmt;
5350   enum machine_mode fmode, imode, rmode;
5351   HOST_WIDE_INT hi, lo;
5352   tree arg, arglist;
5353   int bitpos;
5354   rtx temp;
5355
5356   arglist = TREE_OPERAND (exp, 1);
5357   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5358     return 0;
5359
5360   arg = TREE_VALUE (arglist);
5361   fmode = TYPE_MODE (TREE_TYPE (arg));
5362   rmode = TYPE_MODE (TREE_TYPE (exp));
5363   fmt = REAL_MODE_FORMAT (fmode);
5364
5365   /* For floating point formats without a sign bit, implement signbit
5366      as "ARG < 0.0".  */
5367   if (fmt->signbit < 0)
5368   {
5369     /* But we can't do this if the format supports signed zero.  */
5370     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
5371       return 0;
5372
5373     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
5374                         build_real (TREE_TYPE (arg), dconst0)));
5375     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
5376   }
5377
5378   imode = int_mode_for_mode (fmode);
5379   if (imode == BLKmode)
5380     return 0;
5381
5382   bitpos = fmt->signbit;
5383   /* Handle targets with different FP word orders.  */
5384   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
5385     {
5386       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
5387       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
5388       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
5389     }
5390
5391   /* If the sign bit is not in the lowpart and the floating point format
5392      is wider than an integer, check that is twice the size of an integer
5393      so that we can use gen_highpart below.  */
5394   if (bitpos >= GET_MODE_BITSIZE (rmode)
5395       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
5396     return 0;
5397
5398   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
5399   temp = gen_lowpart (imode, temp);
5400
5401   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
5402     {
5403       if (BYTES_BIG_ENDIAN)
5404         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
5405       temp = copy_to_mode_reg (imode, temp);
5406       temp = extract_bit_field (temp, 1, bitpos, 1,
5407                                 NULL_RTX, rmode, rmode);
5408     }
5409   else
5410     {
5411       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
5412         temp = gen_lowpart (rmode, temp);
5413       if (bitpos < HOST_BITS_PER_WIDE_INT)
5414         {
5415           hi = 0;
5416           lo = (HOST_WIDE_INT) 1 << bitpos;
5417         }
5418       else
5419         {
5420           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
5421           lo = 0;
5422         }
5423
5424       temp = force_reg (rmode, temp);
5425       temp = expand_binop (rmode, and_optab, temp,
5426                            immed_double_const (lo, hi, rmode),
5427                            target, 1, OPTAB_LIB_WIDEN);
5428     }
5429   return temp;
5430 }
5431
5432 /* Expand fork or exec calls.  TARGET is the desired target of the
5433    call.  ARGLIST is the list of arguments of the call.  FN is the
5434    identificator of the actual function.  IGNORE is nonzero if the
5435    value is to be ignored.  */
5436
5437 static rtx
5438 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
5439 {
5440   tree id, decl;
5441   tree call;
5442
5443   /* If we are not profiling, just call the function.  */
5444   if (!profile_arc_flag)
5445     return NULL_RTX;
5446
5447   /* Otherwise call the wrapper.  This should be equivalent for the rest of
5448      compiler, so the code does not diverge, and the wrapper may run the
5449      code necessary for keeping the profiling sane.  */
5450
5451   switch (DECL_FUNCTION_CODE (fn))
5452     {
5453     case BUILT_IN_FORK:
5454       id = get_identifier ("__gcov_fork");
5455       break;
5456
5457     case BUILT_IN_EXECL:
5458       id = get_identifier ("__gcov_execl");
5459       break;
5460
5461     case BUILT_IN_EXECV:
5462       id = get_identifier ("__gcov_execv");
5463       break;
5464
5465     case BUILT_IN_EXECLP:
5466       id = get_identifier ("__gcov_execlp");
5467       break;
5468
5469     case BUILT_IN_EXECLE:
5470       id = get_identifier ("__gcov_execle");
5471       break;
5472
5473     case BUILT_IN_EXECVP:
5474       id = get_identifier ("__gcov_execvp");
5475       break;
5476
5477     case BUILT_IN_EXECVE:
5478       id = get_identifier ("__gcov_execve");
5479       break;
5480
5481     default:
5482       abort ();
5483     }
5484
5485   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5486   DECL_EXTERNAL (decl) = 1;
5487   TREE_PUBLIC (decl) = 1;
5488   DECL_ARTIFICIAL (decl) = 1;
5489   TREE_NOTHROW (decl) = 1;
5490   call = build_function_call_expr (decl, arglist);
5491
5492   return expand_call (call, target, ignore);
5493 }
5494 \f
5495 /* Expand an expression EXP that calls a built-in function,
5496    with result going to TARGET if that's convenient
5497    (and in mode MODE if that's convenient).
5498    SUBTARGET may be used as the target for computing one of EXP's operands.
5499    IGNORE is nonzero if the value is to be ignored.  */
5500
5501 rtx
5502 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5503                 int ignore)
5504 {
5505   tree fndecl = get_callee_fndecl (exp);
5506   tree arglist = TREE_OPERAND (exp, 1);
5507   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5508   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5509
5510   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5511     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5512
5513   /* When not optimizing, generate calls to library functions for a certain
5514      set of builtins.  */
5515   if (!optimize
5516       && !CALLED_AS_BUILT_IN (fndecl)
5517       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5518       && fcode != BUILT_IN_ALLOCA)
5519     return expand_call (exp, target, ignore);
5520
5521   /* The built-in function expanders test for target == const0_rtx
5522      to determine whether the function's result will be ignored.  */
5523   if (ignore)
5524     target = const0_rtx;
5525
5526   /* If the result of a pure or const built-in function is ignored, and
5527      none of its arguments are volatile, we can avoid expanding the
5528      built-in call and just evaluate the arguments for side-effects.  */
5529   if (target == const0_rtx
5530       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5531     {
5532       bool volatilep = false;
5533       tree arg;
5534
5535       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5536         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5537           {
5538             volatilep = true;
5539             break;
5540           }
5541
5542       if (! volatilep)
5543         {
5544           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5545             expand_expr (TREE_VALUE (arg), const0_rtx,
5546                          VOIDmode, EXPAND_NORMAL);
5547           return const0_rtx;
5548         }
5549     }
5550
5551   switch (fcode)
5552     {
5553     case BUILT_IN_FABS:
5554     case BUILT_IN_FABSF:
5555     case BUILT_IN_FABSL:
5556       target = expand_builtin_fabs (arglist, target, subtarget);
5557       if (target)
5558         return target;
5559       break;
5560
5561     case BUILT_IN_CABS:
5562     case BUILT_IN_CABSF:
5563     case BUILT_IN_CABSL:
5564       if (flag_unsafe_math_optimizations)
5565         {
5566           target = expand_builtin_cabs (arglist, target);
5567           if (target)
5568             return target;
5569         }
5570       break;
5571
5572     case BUILT_IN_EXP:
5573     case BUILT_IN_EXPF:
5574     case BUILT_IN_EXPL:
5575     case BUILT_IN_EXP10:
5576     case BUILT_IN_EXP10F:
5577     case BUILT_IN_EXP10L:
5578     case BUILT_IN_POW10:
5579     case BUILT_IN_POW10F:
5580     case BUILT_IN_POW10L:
5581     case BUILT_IN_EXP2:
5582     case BUILT_IN_EXP2F:
5583     case BUILT_IN_EXP2L:
5584     case BUILT_IN_EXPM1:
5585     case BUILT_IN_EXPM1F:
5586     case BUILT_IN_EXPM1L:
5587     case BUILT_IN_LOGB:
5588     case BUILT_IN_LOGBF:
5589     case BUILT_IN_LOGBL:
5590     case BUILT_IN_ILOGB:
5591     case BUILT_IN_ILOGBF:
5592     case BUILT_IN_ILOGBL:
5593     case BUILT_IN_LOG:
5594     case BUILT_IN_LOGF:
5595     case BUILT_IN_LOGL:
5596     case BUILT_IN_LOG10:
5597     case BUILT_IN_LOG10F:
5598     case BUILT_IN_LOG10L:
5599     case BUILT_IN_LOG2:
5600     case BUILT_IN_LOG2F:
5601     case BUILT_IN_LOG2L:
5602     case BUILT_IN_LOG1P:
5603     case BUILT_IN_LOG1PF:
5604     case BUILT_IN_LOG1PL:
5605     case BUILT_IN_TAN:
5606     case BUILT_IN_TANF:
5607     case BUILT_IN_TANL:
5608     case BUILT_IN_ASIN:
5609     case BUILT_IN_ASINF:
5610     case BUILT_IN_ASINL:
5611     case BUILT_IN_ACOS:
5612     case BUILT_IN_ACOSF:
5613     case BUILT_IN_ACOSL:
5614     case BUILT_IN_ATAN:
5615     case BUILT_IN_ATANF:
5616     case BUILT_IN_ATANL:
5617       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5618          because of possible accuracy problems.  */
5619       if (! flag_unsafe_math_optimizations)
5620         break;
5621     case BUILT_IN_SQRT:
5622     case BUILT_IN_SQRTF:
5623     case BUILT_IN_SQRTL:
5624     case BUILT_IN_FLOOR:
5625     case BUILT_IN_FLOORF:
5626     case BUILT_IN_FLOORL:
5627     case BUILT_IN_CEIL:
5628     case BUILT_IN_CEILF:
5629     case BUILT_IN_CEILL:
5630     case BUILT_IN_TRUNC:
5631     case BUILT_IN_TRUNCF:
5632     case BUILT_IN_TRUNCL:
5633     case BUILT_IN_ROUND:
5634     case BUILT_IN_ROUNDF:
5635     case BUILT_IN_ROUNDL:
5636     case BUILT_IN_NEARBYINT:
5637     case BUILT_IN_NEARBYINTF:
5638     case BUILT_IN_NEARBYINTL:
5639       target = expand_builtin_mathfn (exp, target, subtarget);
5640       if (target)
5641         return target;
5642       break;
5643
5644     case BUILT_IN_POW:
5645     case BUILT_IN_POWF:
5646     case BUILT_IN_POWL:
5647       target = expand_builtin_pow (exp, target, subtarget);
5648       if (target)
5649         return target;
5650       break;
5651
5652     case BUILT_IN_ATAN2:
5653     case BUILT_IN_ATAN2F:
5654     case BUILT_IN_ATAN2L:
5655     case BUILT_IN_FMOD:
5656     case BUILT_IN_FMODF:
5657     case BUILT_IN_FMODL:
5658     case BUILT_IN_DREM:
5659     case BUILT_IN_DREMF:
5660     case BUILT_IN_DREML:
5661       if (! flag_unsafe_math_optimizations)
5662         break;
5663       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5664       if (target)
5665         return target;
5666       break;
5667
5668     case BUILT_IN_SIN:
5669     case BUILT_IN_SINF:
5670     case BUILT_IN_SINL:
5671     case BUILT_IN_COS:
5672     case BUILT_IN_COSF:
5673     case BUILT_IN_COSL:
5674       if (! flag_unsafe_math_optimizations)
5675         break;
5676       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5677       if (target)
5678         return target;
5679       break;
5680
5681     case BUILT_IN_APPLY_ARGS:
5682       return expand_builtin_apply_args ();
5683
5684       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5685          FUNCTION with a copy of the parameters described by
5686          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5687          allocated on the stack into which is stored all the registers
5688          that might possibly be used for returning the result of a
5689          function.  ARGUMENTS is the value returned by
5690          __builtin_apply_args.  ARGSIZE is the number of bytes of
5691          arguments that must be copied.  ??? How should this value be
5692          computed?  We'll also need a safe worst case value for varargs
5693          functions.  */
5694     case BUILT_IN_APPLY:
5695       if (!validate_arglist (arglist, POINTER_TYPE,
5696                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5697           && !validate_arglist (arglist, REFERENCE_TYPE,
5698                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5699         return const0_rtx;
5700       else
5701         {
5702           int i;
5703           tree t;
5704           rtx ops[3];
5705
5706           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5707             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5708
5709           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5710         }
5711
5712       /* __builtin_return (RESULT) causes the function to return the
5713          value described by RESULT.  RESULT is address of the block of
5714          memory returned by __builtin_apply.  */
5715     case BUILT_IN_RETURN:
5716       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5717         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5718                                             NULL_RTX, VOIDmode, 0));
5719       return const0_rtx;
5720
5721     case BUILT_IN_SAVEREGS:
5722       return expand_builtin_saveregs ();
5723
5724     case BUILT_IN_ARGS_INFO:
5725       return expand_builtin_args_info (arglist);
5726
5727       /* Return the address of the first anonymous stack arg.  */
5728     case BUILT_IN_NEXT_ARG:
5729       simplify_builtin_next_arg (arglist);
5730       return expand_builtin_next_arg (arglist);
5731
5732     case BUILT_IN_CLASSIFY_TYPE:
5733       return expand_builtin_classify_type (arglist);
5734
5735     case BUILT_IN_CONSTANT_P:
5736       return const0_rtx;
5737
5738     case BUILT_IN_FRAME_ADDRESS:
5739     case BUILT_IN_RETURN_ADDRESS:
5740       return expand_builtin_frame_address (fndecl, arglist);
5741
5742     /* Returns the address of the area where the structure is returned.
5743        0 otherwise.  */
5744     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5745       if (arglist != 0
5746           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5747           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5748         return const0_rtx;
5749       else
5750         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5751
5752     case BUILT_IN_ALLOCA:
5753       target = expand_builtin_alloca (arglist, target);
5754       if (target)
5755         return target;
5756       break;
5757
5758     case BUILT_IN_STACK_ALLOC:
5759       expand_stack_alloc (TREE_VALUE (arglist),
5760                           TREE_VALUE (TREE_CHAIN (arglist)));
5761       return const0_rtx;
5762
5763     case BUILT_IN_STACK_SAVE:
5764       return expand_stack_save ();
5765
5766     case BUILT_IN_STACK_RESTORE:
5767       expand_stack_restore (TREE_VALUE (arglist));
5768       return const0_rtx;
5769
5770     case BUILT_IN_FFS:
5771     case BUILT_IN_FFSL:
5772     case BUILT_IN_FFSLL:
5773     case BUILT_IN_FFSIMAX:
5774       target = expand_builtin_unop (target_mode, arglist, target,
5775                                     subtarget, ffs_optab);
5776       if (target)
5777         return target;
5778       break;
5779
5780     case BUILT_IN_CLZ:
5781     case BUILT_IN_CLZL:
5782     case BUILT_IN_CLZLL:
5783     case BUILT_IN_CLZIMAX:
5784       target = expand_builtin_unop (target_mode, arglist, target,
5785                                     subtarget, clz_optab);
5786       if (target)
5787         return target;
5788       break;
5789
5790     case BUILT_IN_CTZ:
5791     case BUILT_IN_CTZL:
5792     case BUILT_IN_CTZLL:
5793     case BUILT_IN_CTZIMAX:
5794       target = expand_builtin_unop (target_mode, arglist, target,
5795                                     subtarget, ctz_optab);
5796       if (target)
5797         return target;
5798       break;
5799
5800     case BUILT_IN_POPCOUNT:
5801     case BUILT_IN_POPCOUNTL:
5802     case BUILT_IN_POPCOUNTLL:
5803     case BUILT_IN_POPCOUNTIMAX:
5804       target = expand_builtin_unop (target_mode, arglist, target,
5805                                     subtarget, popcount_optab);
5806       if (target)
5807         return target;
5808       break;
5809
5810     case BUILT_IN_PARITY:
5811     case BUILT_IN_PARITYL:
5812     case BUILT_IN_PARITYLL:
5813     case BUILT_IN_PARITYIMAX:
5814       target = expand_builtin_unop (target_mode, arglist, target,
5815                                     subtarget, parity_optab);
5816       if (target)
5817         return target;
5818       break;
5819
5820     case BUILT_IN_STRLEN:
5821       target = expand_builtin_strlen (arglist, target, target_mode);
5822       if (target)
5823         return target;
5824       break;
5825
5826     case BUILT_IN_STRCPY:
5827       target = expand_builtin_strcpy (arglist, target, mode);
5828       if (target)
5829         return target;
5830       break;
5831
5832     case BUILT_IN_STRNCPY:
5833       target = expand_builtin_strncpy (arglist, target, mode);
5834       if (target)
5835         return target;
5836       break;
5837
5838     case BUILT_IN_STPCPY:
5839       target = expand_builtin_stpcpy (arglist, target, mode);
5840       if (target)
5841         return target;
5842       break;
5843
5844     case BUILT_IN_STRCAT:
5845       target = expand_builtin_strcat (arglist, target, mode);
5846       if (target)
5847         return target;
5848       break;
5849
5850     case BUILT_IN_STRNCAT:
5851       target = expand_builtin_strncat (arglist, target, mode);
5852       if (target)
5853         return target;
5854       break;
5855
5856     case BUILT_IN_STRSPN:
5857       target = expand_builtin_strspn (arglist, target, mode);
5858       if (target)
5859         return target;
5860       break;
5861
5862     case BUILT_IN_STRCSPN:
5863       target = expand_builtin_strcspn (arglist, target, mode);
5864       if (target)
5865         return target;
5866       break;
5867
5868     case BUILT_IN_STRSTR:
5869       target = expand_builtin_strstr (arglist, target, mode);
5870       if (target)
5871         return target;
5872       break;
5873
5874     case BUILT_IN_STRPBRK:
5875       target = expand_builtin_strpbrk (arglist, target, mode);
5876       if (target)
5877         return target;
5878       break;
5879
5880     case BUILT_IN_INDEX:
5881     case BUILT_IN_STRCHR:
5882       target = expand_builtin_strchr (arglist, target, mode);
5883       if (target)
5884         return target;
5885       break;
5886
5887     case BUILT_IN_RINDEX:
5888     case BUILT_IN_STRRCHR:
5889       target = expand_builtin_strrchr (arglist, target, mode);
5890       if (target)
5891         return target;
5892       break;
5893
5894     case BUILT_IN_MEMCPY:
5895       target = expand_builtin_memcpy (arglist, target, mode);
5896       if (target)
5897         return target;
5898       break;
5899
5900     case BUILT_IN_MEMPCPY:
5901       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5902       if (target)
5903         return target;
5904       break;
5905
5906     case BUILT_IN_MEMMOVE:
5907       target = expand_builtin_memmove (arglist, target, mode);
5908       if (target)
5909         return target;
5910       break;
5911
5912     case BUILT_IN_BCOPY:
5913       target = expand_builtin_bcopy (arglist);
5914       if (target)
5915         return target;
5916       break;
5917
5918     case BUILT_IN_MEMSET:
5919       target = expand_builtin_memset (arglist, target, mode);
5920       if (target)
5921         return target;
5922       break;
5923
5924     case BUILT_IN_BZERO:
5925       target = expand_builtin_bzero (arglist);
5926       if (target)
5927         return target;
5928       break;
5929
5930     case BUILT_IN_STRCMP:
5931       target = expand_builtin_strcmp (exp, target, mode);
5932       if (target)
5933         return target;
5934       break;
5935
5936     case BUILT_IN_STRNCMP:
5937       target = expand_builtin_strncmp (exp, target, mode);
5938       if (target)
5939         return target;
5940       break;
5941
5942     case BUILT_IN_BCMP:
5943     case BUILT_IN_MEMCMP:
5944       target = expand_builtin_memcmp (exp, arglist, target, mode);
5945       if (target)
5946         return target;
5947       break;
5948
5949     case BUILT_IN_SETJMP:
5950       target = expand_builtin_setjmp (arglist, target);
5951       if (target)
5952         return target;
5953       break;
5954
5955       /* __builtin_longjmp is passed a pointer to an array of five words.
5956          It's similar to the C library longjmp function but works with
5957          __builtin_setjmp above.  */
5958     case BUILT_IN_LONGJMP:
5959       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5960         break;
5961       else
5962         {
5963           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5964                                       VOIDmode, 0);
5965           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5966                                    NULL_RTX, VOIDmode, 0);
5967
5968           if (value != const1_rtx)
5969             {
5970               error ("__builtin_longjmp second argument must be 1");
5971               return const0_rtx;
5972             }
5973
5974           expand_builtin_longjmp (buf_addr, value);
5975           return const0_rtx;
5976         }
5977
5978     case BUILT_IN_NONLOCAL_GOTO:
5979       target = expand_builtin_nonlocal_goto (arglist);
5980       if (target)
5981         return target;
5982       break;
5983
5984       /* This updates the setjmp buffer that is its argument with the value
5985          of the current stack pointer.  */
5986     case BUILT_IN_UPDATE_SETJMP_BUF:
5987       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5988         {
5989           rtx buf_addr
5990             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5991
5992           expand_builtin_update_setjmp_buf (buf_addr);
5993           return const0_rtx;
5994         }
5995       break;
5996
5997     case BUILT_IN_TRAP:
5998       expand_builtin_trap ();
5999       return const0_rtx;
6000
6001     case BUILT_IN_PRINTF:
6002       target = expand_builtin_printf (arglist, target, mode, false);
6003       if (target)
6004         return target;
6005       break;
6006
6007     case BUILT_IN_PRINTF_UNLOCKED:
6008       target = expand_builtin_printf (arglist, target, mode, true);
6009       if (target)
6010         return target;
6011       break;
6012
6013     case BUILT_IN_FPUTS:
6014       target = expand_builtin_fputs (arglist, target, false);
6015       if (target)
6016         return target;
6017       break;
6018     case BUILT_IN_FPUTS_UNLOCKED:
6019       target = expand_builtin_fputs (arglist, target, true);
6020       if (target)
6021         return target;
6022       break;
6023
6024     case BUILT_IN_FPRINTF:
6025       target = expand_builtin_fprintf (arglist, target, mode, false);
6026       if (target)
6027         return target;
6028       break;
6029
6030     case BUILT_IN_FPRINTF_UNLOCKED:
6031       target = expand_builtin_fprintf (arglist, target, mode, true);
6032       if (target)
6033         return target;
6034       break;
6035
6036     case BUILT_IN_SPRINTF:
6037       target = expand_builtin_sprintf (arglist, target, mode);
6038       if (target)
6039         return target;
6040       break;
6041
6042     case BUILT_IN_SIGNBIT:
6043     case BUILT_IN_SIGNBITF:
6044     case BUILT_IN_SIGNBITL:
6045       target = expand_builtin_signbit (exp, target);
6046       if (target)
6047         return target;
6048       break;
6049
6050       /* Various hooks for the DWARF 2 __throw routine.  */
6051     case BUILT_IN_UNWIND_INIT:
6052       expand_builtin_unwind_init ();
6053       return const0_rtx;
6054     case BUILT_IN_DWARF_CFA:
6055       return virtual_cfa_rtx;
6056 #ifdef DWARF2_UNWIND_INFO
6057     case BUILT_IN_DWARF_SP_COLUMN:
6058       return expand_builtin_dwarf_sp_column ();
6059     case BUILT_IN_INIT_DWARF_REG_SIZES:
6060       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
6061       return const0_rtx;
6062 #endif
6063     case BUILT_IN_FROB_RETURN_ADDR:
6064       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
6065     case BUILT_IN_EXTRACT_RETURN_ADDR:
6066       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
6067     case BUILT_IN_EH_RETURN:
6068       expand_builtin_eh_return (TREE_VALUE (arglist),
6069                                 TREE_VALUE (TREE_CHAIN (arglist)));
6070       return const0_rtx;
6071 #ifdef EH_RETURN_DATA_REGNO
6072     case BUILT_IN_EH_RETURN_DATA_REGNO:
6073       return expand_builtin_eh_return_data_regno (arglist);
6074 #endif
6075     case BUILT_IN_EXTEND_POINTER:
6076       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
6077
6078     case BUILT_IN_VA_START:
6079     case BUILT_IN_STDARG_START:
6080       return expand_builtin_va_start (arglist);
6081     case BUILT_IN_VA_END:
6082       return expand_builtin_va_end (arglist);
6083     case BUILT_IN_VA_COPY:
6084       return expand_builtin_va_copy (arglist);
6085     case BUILT_IN_EXPECT:
6086       return expand_builtin_expect (arglist, target);
6087     case BUILT_IN_PREFETCH:
6088       expand_builtin_prefetch (arglist);
6089       return const0_rtx;
6090
6091     case BUILT_IN_PROFILE_FUNC_ENTER:
6092       return expand_builtin_profile_func (false);
6093     case BUILT_IN_PROFILE_FUNC_EXIT:
6094       return expand_builtin_profile_func (true);
6095
6096     case BUILT_IN_INIT_TRAMPOLINE:
6097       return expand_builtin_init_trampoline (arglist);
6098     case BUILT_IN_ADJUST_TRAMPOLINE:
6099       return expand_builtin_adjust_trampoline (arglist);
6100
6101     case BUILT_IN_FORK:
6102     case BUILT_IN_EXECL:
6103     case BUILT_IN_EXECV:
6104     case BUILT_IN_EXECLP:
6105     case BUILT_IN_EXECLE:
6106     case BUILT_IN_EXECVP:
6107     case BUILT_IN_EXECVE:
6108       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
6109       if (target)
6110         return target;
6111       break;
6112
6113     default:    /* just do library call, if unknown builtin */
6114       break;
6115     }
6116
6117   /* The switch statement above can drop through to cause the function
6118      to be called normally.  */
6119   return expand_call (exp, target, ignore);
6120 }
6121
6122 /* Determine whether a tree node represents a call to a built-in
6123    function.  If the tree T is a call to a built-in function with
6124    the right number of arguments of the appropriate types, return
6125    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
6126    Otherwise the return value is END_BUILTINS.  */
6127
6128 enum built_in_function
6129 builtin_mathfn_code (tree t)
6130 {
6131   tree fndecl, arglist, parmlist;
6132   tree argtype, parmtype;
6133
6134   if (TREE_CODE (t) != CALL_EXPR
6135       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
6136     return END_BUILTINS;
6137
6138   fndecl = get_callee_fndecl (t);
6139   if (fndecl == NULL_TREE
6140       || TREE_CODE (fndecl) != FUNCTION_DECL
6141       || ! DECL_BUILT_IN (fndecl)
6142       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6143     return END_BUILTINS;
6144
6145   arglist = TREE_OPERAND (t, 1);
6146   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
6147   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
6148     {
6149       /* If a function doesn't take a variable number of arguments,
6150          the last element in the list will have type `void'.  */
6151       parmtype = TREE_VALUE (parmlist);
6152       if (VOID_TYPE_P (parmtype))
6153         {
6154           if (arglist)
6155             return END_BUILTINS;
6156           return DECL_FUNCTION_CODE (fndecl);
6157         }
6158
6159       if (! arglist)
6160         return END_BUILTINS;
6161
6162       argtype = TREE_TYPE (TREE_VALUE (arglist));
6163
6164       if (SCALAR_FLOAT_TYPE_P (parmtype))
6165         {
6166           if (! SCALAR_FLOAT_TYPE_P (argtype))
6167             return END_BUILTINS;
6168         }
6169       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
6170         {
6171           if (! COMPLEX_FLOAT_TYPE_P (argtype))
6172             return END_BUILTINS;
6173         }
6174       else if (POINTER_TYPE_P (parmtype))
6175         {
6176           if (! POINTER_TYPE_P (argtype))
6177             return END_BUILTINS;
6178         }
6179       else if (INTEGRAL_TYPE_P (parmtype))
6180         {
6181           if (! INTEGRAL_TYPE_P (argtype))
6182             return END_BUILTINS;
6183         }
6184       else
6185         return END_BUILTINS;
6186
6187       arglist = TREE_CHAIN (arglist);
6188     }
6189
6190   /* Variable-length argument list.  */
6191   return DECL_FUNCTION_CODE (fndecl);
6192 }
6193
6194 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
6195    constant.  ARGLIST is the argument list of the call.  */
6196
6197 static tree
6198 fold_builtin_constant_p (tree arglist)
6199 {
6200   if (arglist == 0)
6201     return 0;
6202
6203   arglist = TREE_VALUE (arglist);
6204
6205   /* We return 1 for a numeric type that's known to be a constant
6206      value at compile-time or for an aggregate type that's a
6207      literal constant.  */
6208   STRIP_NOPS (arglist);
6209
6210   /* If we know this is a constant, emit the constant of one.  */
6211   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
6212       || (TREE_CODE (arglist) == CONSTRUCTOR
6213           && TREE_CONSTANT (arglist))
6214       || (TREE_CODE (arglist) == ADDR_EXPR
6215           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
6216     return integer_one_node;
6217
6218   /* If this expression has side effects, show we don't know it to be a
6219      constant.  Likewise if it's a pointer or aggregate type since in
6220      those case we only want literals, since those are only optimized
6221      when generating RTL, not later.
6222      And finally, if we are compiling an initializer, not code, we
6223      need to return a definite result now; there's not going to be any
6224      more optimization done.  */
6225   if (TREE_SIDE_EFFECTS (arglist)
6226       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
6227       || POINTER_TYPE_P (TREE_TYPE (arglist))
6228       || cfun == 0)
6229     return integer_zero_node;
6230
6231   return 0;
6232 }
6233
6234 /* Fold a call to __builtin_expect, if we expect that a comparison against
6235    the argument will fold to a constant.  In practice, this means a true
6236    constant or the address of a non-weak symbol.  ARGLIST is the argument
6237    list of the call.  */
6238
6239 static tree
6240 fold_builtin_expect (tree arglist)
6241 {
6242   tree arg, inner;
6243
6244   if (arglist == 0)
6245     return 0;
6246
6247   arg = TREE_VALUE (arglist);
6248
6249   /* If the argument isn't invariant, then there's nothing we can do.  */
6250   if (!TREE_INVARIANT (arg))
6251     return 0;
6252
6253   /* If we're looking at an address of a weak decl, then do not fold.  */
6254   inner = arg;
6255   STRIP_NOPS (inner);
6256   if (TREE_CODE (inner) == ADDR_EXPR)
6257     {
6258       do
6259         {
6260           inner = TREE_OPERAND (inner, 0);
6261         }
6262       while (TREE_CODE (inner) == COMPONENT_REF
6263              || TREE_CODE (inner) == ARRAY_REF);
6264       if (DECL_P (inner) && DECL_WEAK (inner))
6265         return 0;
6266     }
6267
6268   /* Otherwise, ARG already has the proper type for the return value.  */
6269   return arg;
6270 }
6271
6272 /* Fold a call to __builtin_classify_type.  */
6273
6274 static tree
6275 fold_builtin_classify_type (tree arglist)
6276 {
6277   if (arglist == 0)
6278     return build_int_2 (no_type_class, 0);
6279
6280   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
6281 }
6282
6283 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
6284
6285 static tree
6286 fold_builtin_inf (tree type, int warn)
6287 {
6288   REAL_VALUE_TYPE real;
6289
6290   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
6291     warning ("target format does not support infinity");
6292
6293   real_inf (&real);
6294   return build_real (type, real);
6295 }
6296
6297 /* Fold a call to __builtin_nan or __builtin_nans.  */
6298
6299 static tree
6300 fold_builtin_nan (tree arglist, tree type, int quiet)
6301 {
6302   REAL_VALUE_TYPE real;
6303   const char *str;
6304
6305   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6306     return 0;
6307   str = c_getstr (TREE_VALUE (arglist));
6308   if (!str)
6309     return 0;
6310
6311   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
6312     return 0;
6313
6314   return build_real (type, real);
6315 }
6316
6317 /* Return true if the floating point expression T has an integer value.
6318    We also allow +Inf, -Inf and NaN to be considered integer values.  */
6319
6320 static bool
6321 integer_valued_real_p (tree t)
6322 {
6323   switch (TREE_CODE (t))
6324     {
6325     case FLOAT_EXPR:
6326       return true;
6327
6328     case ABS_EXPR:
6329     case SAVE_EXPR:
6330     case NON_LVALUE_EXPR:
6331       return integer_valued_real_p (TREE_OPERAND (t, 0));
6332
6333     case COMPOUND_EXPR:
6334     case MODIFY_EXPR:
6335     case BIND_EXPR:
6336       return integer_valued_real_p (TREE_OPERAND (t, 1));
6337
6338     case PLUS_EXPR:
6339     case MINUS_EXPR:
6340     case MULT_EXPR:
6341     case MIN_EXPR:
6342     case MAX_EXPR:
6343       return integer_valued_real_p (TREE_OPERAND (t, 0))
6344              && integer_valued_real_p (TREE_OPERAND (t, 1));
6345
6346     case COND_EXPR:
6347       return integer_valued_real_p (TREE_OPERAND (t, 1))
6348              && integer_valued_real_p (TREE_OPERAND (t, 2));
6349
6350     case REAL_CST:
6351       if (! TREE_CONSTANT_OVERFLOW (t))
6352       {
6353         REAL_VALUE_TYPE c, cint;
6354
6355         c = TREE_REAL_CST (t);
6356         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
6357         return real_identical (&c, &cint);
6358       }
6359
6360     case NOP_EXPR:
6361       {
6362         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
6363         if (TREE_CODE (type) == INTEGER_TYPE)
6364           return true;
6365         if (TREE_CODE (type) == REAL_TYPE)
6366           return integer_valued_real_p (TREE_OPERAND (t, 0));
6367         break;
6368       }
6369
6370     case CALL_EXPR:
6371       switch (builtin_mathfn_code (t))
6372         {
6373         case BUILT_IN_CEIL:
6374         case BUILT_IN_CEILF:
6375         case BUILT_IN_CEILL:
6376         case BUILT_IN_FLOOR:
6377         case BUILT_IN_FLOORF:
6378         case BUILT_IN_FLOORL:
6379         case BUILT_IN_NEARBYINT:
6380         case BUILT_IN_NEARBYINTF:
6381         case BUILT_IN_NEARBYINTL:
6382         case BUILT_IN_RINT:
6383         case BUILT_IN_RINTF:
6384         case BUILT_IN_RINTL:
6385         case BUILT_IN_ROUND:
6386         case BUILT_IN_ROUNDF:
6387         case BUILT_IN_ROUNDL:
6388         case BUILT_IN_TRUNC:
6389         case BUILT_IN_TRUNCF:
6390         case BUILT_IN_TRUNCL:
6391           return true;
6392
6393         default:
6394           break;
6395         }
6396       break;
6397
6398     default:
6399       break;
6400     }
6401   return false;
6402 }
6403
6404 /* EXP is assumed to be builtin call where truncation can be propagated
6405    across (for instance floor((double)f) == (double)floorf (f).
6406    Do the transformation.  */
6407
6408 static tree
6409 fold_trunc_transparent_mathfn (tree exp)
6410 {
6411   tree fndecl = get_callee_fndecl (exp);
6412   tree arglist = TREE_OPERAND (exp, 1);
6413   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6414   tree arg;
6415
6416   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6417     return 0;
6418
6419   arg = TREE_VALUE (arglist);
6420   /* Integer rounding functions are idempotent.  */
6421   if (fcode == builtin_mathfn_code (arg))
6422     return arg;
6423
6424   /* If argument is already integer valued, and we don't need to worry
6425      about setting errno, there's no need to perform rounding.  */
6426   if (! flag_errno_math && integer_valued_real_p (arg))
6427     return arg;
6428
6429   if (optimize)
6430     {
6431       tree arg0 = strip_float_extensions (arg);
6432       tree ftype = TREE_TYPE (exp);
6433       tree newtype = TREE_TYPE (arg0);
6434       tree decl;
6435
6436       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6437           && (decl = mathfn_built_in (newtype, fcode)))
6438         {
6439           arglist =
6440             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6441           return fold_convert (ftype,
6442                                build_function_call_expr (decl, arglist));
6443         }
6444     }
6445   return 0;
6446 }
6447
6448 /* EXP is assumed to be builtin call which can narrow the FP type of
6449    the argument, for instance lround((double)f) -> lroundf (f).  */
6450
6451 static tree
6452 fold_fixed_mathfn (tree exp)
6453 {
6454   tree fndecl = get_callee_fndecl (exp);
6455   tree arglist = TREE_OPERAND (exp, 1);
6456   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6457   tree arg;
6458
6459   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6460     return 0;
6461
6462   arg = TREE_VALUE (arglist);
6463
6464   /* If argument is already integer valued, and we don't need to worry
6465      about setting errno, there's no need to perform rounding.  */
6466   if (! flag_errno_math && integer_valued_real_p (arg))
6467     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6468
6469   if (optimize)
6470     {
6471       tree ftype = TREE_TYPE (arg);
6472       tree arg0 = strip_float_extensions (arg);
6473       tree newtype = TREE_TYPE (arg0);
6474       tree decl;
6475
6476       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6477           && (decl = mathfn_built_in (newtype, fcode)))
6478         {
6479           arglist =
6480             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6481           return build_function_call_expr (decl, arglist);
6482         }
6483     }
6484   return 0;
6485 }
6486
6487 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6488    is the argument list and TYPE is the return type.  Return
6489    NULL_TREE if no if no simplification can be made.  */
6490
6491 static tree
6492 fold_builtin_cabs (tree arglist, tree type)
6493 {
6494   tree arg;
6495
6496   if (!arglist || TREE_CHAIN (arglist))
6497     return NULL_TREE;
6498
6499   arg = TREE_VALUE (arglist);
6500   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6501       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6502     return NULL_TREE;
6503
6504   /* Evaluate cabs of a constant at compile-time.  */
6505   if (flag_unsafe_math_optimizations
6506       && TREE_CODE (arg) == COMPLEX_CST
6507       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6508       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6509       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6510       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6511     {
6512       REAL_VALUE_TYPE r, i;
6513
6514       r = TREE_REAL_CST (TREE_REALPART (arg));
6515       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6516
6517       real_arithmetic (&r, MULT_EXPR, &r, &r);
6518       real_arithmetic (&i, MULT_EXPR, &i, &i);
6519       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6520       if (real_sqrt (&r, TYPE_MODE (type), &r)
6521           || ! flag_trapping_math)
6522         return build_real (type, r);
6523     }
6524
6525   /* If either part is zero, cabs is fabs of the other.  */
6526   if (TREE_CODE (arg) == COMPLEX_EXPR
6527       && real_zerop (TREE_OPERAND (arg, 0)))
6528     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6529   if (TREE_CODE (arg) == COMPLEX_EXPR
6530       && real_zerop (TREE_OPERAND (arg, 1)))
6531     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6532
6533   if (flag_unsafe_math_optimizations)
6534     {
6535       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6536
6537       if (sqrtfn != NULL_TREE)
6538         {
6539           tree rpart, ipart, result, arglist;
6540
6541           arg = builtin_save_expr (arg);
6542
6543           rpart = fold (build1 (REALPART_EXPR, type, arg));
6544           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6545
6546           rpart = builtin_save_expr (rpart);
6547           ipart = builtin_save_expr (ipart);
6548
6549           result = fold (build2 (PLUS_EXPR, type,
6550                                  fold (build2 (MULT_EXPR, type,
6551                                                rpart, rpart)),
6552                                  fold (build2 (MULT_EXPR, type,
6553                                                ipart, ipart))));
6554
6555           arglist = build_tree_list (NULL_TREE, result);
6556           return build_function_call_expr (sqrtfn, arglist);
6557         }
6558     }
6559
6560   return NULL_TREE;
6561 }
6562
6563 /* Fold function call to builtin trunc, truncf or truncl.  Return
6564    NULL_TREE if no simplification can be made.  */
6565
6566 static tree
6567 fold_builtin_trunc (tree exp)
6568 {
6569   tree arglist = TREE_OPERAND (exp, 1);
6570   tree arg;
6571
6572   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6573     return 0;
6574
6575   /* Optimize trunc of constant value.  */
6576   arg = TREE_VALUE (arglist);
6577   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6578     {
6579       REAL_VALUE_TYPE r, x;
6580       tree type = TREE_TYPE (exp);
6581
6582       x = TREE_REAL_CST (arg);
6583       real_trunc (&r, TYPE_MODE (type), &x);
6584       return build_real (type, r);
6585     }
6586
6587   return fold_trunc_transparent_mathfn (exp);
6588 }
6589
6590 /* Fold function call to builtin floor, floorf or floorl.  Return
6591    NULL_TREE if no simplification can be made.  */
6592
6593 static tree
6594 fold_builtin_floor (tree exp)
6595 {
6596   tree arglist = TREE_OPERAND (exp, 1);
6597   tree arg;
6598
6599   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6600     return 0;
6601
6602   /* Optimize floor of constant value.  */
6603   arg = TREE_VALUE (arglist);
6604   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6605     {
6606       REAL_VALUE_TYPE x;
6607
6608       x = TREE_REAL_CST (arg);
6609       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6610         {
6611           tree type = TREE_TYPE (exp);
6612           REAL_VALUE_TYPE r;
6613
6614           real_floor (&r, TYPE_MODE (type), &x);
6615           return build_real (type, r);
6616         }
6617     }
6618
6619   return fold_trunc_transparent_mathfn (exp);
6620 }
6621
6622 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6623    NULL_TREE if no simplification can be made.  */
6624
6625 static tree
6626 fold_builtin_ceil (tree exp)
6627 {
6628   tree arglist = TREE_OPERAND (exp, 1);
6629   tree arg;
6630
6631   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6632     return 0;
6633
6634   /* Optimize ceil of constant value.  */
6635   arg = TREE_VALUE (arglist);
6636   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6637     {
6638       REAL_VALUE_TYPE x;
6639
6640       x = TREE_REAL_CST (arg);
6641       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6642         {
6643           tree type = TREE_TYPE (exp);
6644           REAL_VALUE_TYPE r;
6645
6646           real_ceil (&r, TYPE_MODE (type), &x);
6647           return build_real (type, r);
6648         }
6649     }
6650
6651   return fold_trunc_transparent_mathfn (exp);
6652 }
6653
6654 /* Fold function call to builtin round, roundf or roundl.  Return
6655    NULL_TREE if no simplification can be made.  */
6656
6657 static tree
6658 fold_builtin_round (tree exp)
6659 {
6660   tree arglist = TREE_OPERAND (exp, 1);
6661   tree arg;
6662
6663   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6664     return 0;
6665
6666   /* Optimize round of constant value.  */
6667   arg = TREE_VALUE (arglist);
6668   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6669     {
6670       REAL_VALUE_TYPE x;
6671
6672       x = TREE_REAL_CST (arg);
6673       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6674         {
6675           tree type = TREE_TYPE (exp);
6676           REAL_VALUE_TYPE r;
6677
6678           real_round (&r, TYPE_MODE (type), &x);
6679           return build_real (type, r);
6680         }
6681     }
6682
6683   return fold_trunc_transparent_mathfn (exp);
6684 }
6685
6686 /* Fold function call to builtin lround, lroundf or lroundl (or the
6687    corresponding long long versions).  Return NULL_TREE if no
6688    simplification can be made.  */
6689
6690 static tree
6691 fold_builtin_lround (tree exp)
6692 {
6693   tree arglist = TREE_OPERAND (exp, 1);
6694   tree arg;
6695
6696   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6697     return 0;
6698
6699   /* Optimize lround of constant value.  */
6700   arg = TREE_VALUE (arglist);
6701   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6702     {
6703       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6704
6705       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6706         {
6707           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6708           HOST_WIDE_INT hi, lo;
6709           REAL_VALUE_TYPE r;
6710
6711           real_round (&r, TYPE_MODE (ftype), &x);
6712           REAL_VALUE_TO_INT (&lo, &hi, r);
6713           result = build_int_2 (lo, hi);
6714           if (int_fits_type_p (result, itype))
6715             return fold_convert (itype, result);
6716         }
6717     }
6718
6719   return fold_fixed_mathfn (exp);
6720 }
6721
6722 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6723    and their long and long long variants (i.e. ffsl and ffsll).
6724    Return NULL_TREE if no simplification can be made.  */
6725
6726 static tree
6727 fold_builtin_bitop (tree exp)
6728 {
6729   tree fndecl = get_callee_fndecl (exp);
6730   tree arglist = TREE_OPERAND (exp, 1);
6731   tree arg;
6732
6733   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6734     return NULL_TREE;
6735
6736   /* Optimize for constant argument.  */
6737   arg = TREE_VALUE (arglist);
6738   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6739     {
6740       HOST_WIDE_INT hi, width, result;
6741       unsigned HOST_WIDE_INT lo;
6742       tree type, t;
6743
6744       type = TREE_TYPE (arg);
6745       width = TYPE_PRECISION (type);
6746       lo = TREE_INT_CST_LOW (arg);
6747
6748       /* Clear all the bits that are beyond the type's precision.  */
6749       if (width > HOST_BITS_PER_WIDE_INT)
6750         {
6751           hi = TREE_INT_CST_HIGH (arg);
6752           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6753             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6754         }
6755       else
6756         {
6757           hi = 0;
6758           if (width < HOST_BITS_PER_WIDE_INT)
6759             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6760         }
6761
6762       switch (DECL_FUNCTION_CODE (fndecl))
6763         {
6764         case BUILT_IN_FFS:
6765         case BUILT_IN_FFSL:
6766         case BUILT_IN_FFSLL:
6767           if (lo != 0)
6768             result = exact_log2 (lo & -lo) + 1;
6769           else if (hi != 0)
6770             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6771           else
6772             result = 0;
6773           break;
6774
6775         case BUILT_IN_CLZ:
6776         case BUILT_IN_CLZL:
6777         case BUILT_IN_CLZLL:
6778           if (hi != 0)
6779             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6780           else if (lo != 0)
6781             result = width - floor_log2 (lo) - 1;
6782           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6783             result = width;
6784           break;
6785
6786         case BUILT_IN_CTZ:
6787         case BUILT_IN_CTZL:
6788         case BUILT_IN_CTZLL:
6789           if (lo != 0)
6790             result = exact_log2 (lo & -lo);
6791           else if (hi != 0)
6792             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6793           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6794             result = width;
6795           break;
6796
6797         case BUILT_IN_POPCOUNT:
6798         case BUILT_IN_POPCOUNTL:
6799         case BUILT_IN_POPCOUNTLL:
6800           result = 0;
6801           while (lo)
6802             result++, lo &= lo - 1;
6803           while (hi)
6804             result++, hi &= hi - 1;
6805           break;
6806
6807         case BUILT_IN_PARITY:
6808         case BUILT_IN_PARITYL:
6809         case BUILT_IN_PARITYLL:
6810           result = 0;
6811           while (lo)
6812             result++, lo &= lo - 1;
6813           while (hi)
6814             result++, hi &= hi - 1;
6815           result &= 1;
6816           break;
6817
6818         default:
6819           abort();
6820         }
6821
6822       t = build_int_2 (result, 0);
6823       TREE_TYPE (t) = TREE_TYPE (exp);
6824       return t;
6825     }
6826
6827   return NULL_TREE;
6828 }
6829
6830 /* Return true if EXPR is the real constant contained in VALUE.  */
6831
6832 static bool
6833 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6834 {
6835   STRIP_NOPS (expr);
6836
6837   return ((TREE_CODE (expr) == REAL_CST
6838            && ! TREE_CONSTANT_OVERFLOW (expr)
6839            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6840           || (TREE_CODE (expr) == COMPLEX_CST
6841               && real_dconstp (TREE_REALPART (expr), value)
6842               && real_zerop (TREE_IMAGPART (expr))));
6843 }
6844
6845 /* A subroutine of fold_builtin to fold the various logarithmic
6846    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6847    function.  VALUE is the base of the logN function.  */
6848
6849 static tree
6850 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6851 {
6852   tree arglist = TREE_OPERAND (exp, 1);
6853
6854   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6855     {
6856       tree fndecl = get_callee_fndecl (exp);
6857       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6858       tree arg = TREE_VALUE (arglist);
6859       const enum built_in_function fcode = builtin_mathfn_code (arg);
6860
6861       /* Optimize logN(1.0) = 0.0.  */
6862       if (real_onep (arg))
6863         return build_real (type, dconst0);
6864
6865       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6866          exactly, then only do this if flag_unsafe_math_optimizations.  */
6867       if (exact_real_truncate (TYPE_MODE (type), value)
6868           || flag_unsafe_math_optimizations)
6869         {
6870           const REAL_VALUE_TYPE value_truncate =
6871             real_value_truncate (TYPE_MODE (type), *value);
6872           if (real_dconstp (arg, &value_truncate))
6873             return build_real (type, dconst1);
6874         }
6875
6876       /* Special case, optimize logN(expN(x)) = x.  */
6877       if (flag_unsafe_math_optimizations
6878           && ((value == &dconste
6879                && (fcode == BUILT_IN_EXP
6880                    || fcode == BUILT_IN_EXPF
6881                    || fcode == BUILT_IN_EXPL))
6882               || (value == &dconst2
6883                   && (fcode == BUILT_IN_EXP2
6884                       || fcode == BUILT_IN_EXP2F
6885                       || fcode == BUILT_IN_EXP2L))
6886               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6887         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6888
6889       /* Optimize logN(func()) for various exponential functions.  We
6890          want to determine the value "x" and the power "exponent" in
6891          order to transform logN(x**exponent) into exponent*logN(x).  */
6892       if (flag_unsafe_math_optimizations)
6893         {
6894           tree exponent = 0, x = 0;
6895
6896           switch (fcode)
6897           {
6898           case BUILT_IN_EXP:
6899           case BUILT_IN_EXPF:
6900           case BUILT_IN_EXPL:
6901             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6902             x = build_real (type,
6903                             real_value_truncate (TYPE_MODE (type), dconste));
6904             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6905             break;
6906           case BUILT_IN_EXP2:
6907           case BUILT_IN_EXP2F:
6908           case BUILT_IN_EXP2L:
6909             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6910             x = build_real (type, dconst2);
6911             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6912             break;
6913           case BUILT_IN_EXP10:
6914           case BUILT_IN_EXP10F:
6915           case BUILT_IN_EXP10L:
6916           case BUILT_IN_POW10:
6917           case BUILT_IN_POW10F:
6918           case BUILT_IN_POW10L:
6919             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6920             x = build_real (type, dconst10);
6921             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6922             break;
6923           case BUILT_IN_SQRT:
6924           case BUILT_IN_SQRTF:
6925           case BUILT_IN_SQRTL:
6926             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6927             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6928             exponent = build_real (type, dconsthalf);
6929             break;
6930           case BUILT_IN_CBRT:
6931           case BUILT_IN_CBRTF:
6932           case BUILT_IN_CBRTL:
6933             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6934             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6935             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6936                                                               dconstthird));
6937             break;
6938           case BUILT_IN_POW:
6939           case BUILT_IN_POWF:
6940           case BUILT_IN_POWL:
6941             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6942             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6943             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6944             break;
6945           default:
6946             break;
6947           }
6948
6949           /* Now perform the optimization.  */
6950           if (x && exponent)
6951             {
6952               tree logfn;
6953               arglist = build_tree_list (NULL_TREE, x);
6954               logfn = build_function_call_expr (fndecl, arglist);
6955               return fold (build2 (MULT_EXPR, type, exponent, logfn));
6956             }
6957         }
6958     }
6959
6960   return 0;
6961 }
6962
6963 /* A subroutine of fold_builtin to fold the various exponent
6964    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6965    VALUE is the value which will be raised to a power.  */
6966
6967 static tree
6968 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6969 {
6970   tree arglist = TREE_OPERAND (exp, 1);
6971
6972   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6973     {
6974       tree fndecl = get_callee_fndecl (exp);
6975       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6976       tree arg = TREE_VALUE (arglist);
6977
6978       /* Optimize exp*(0.0) = 1.0.  */
6979       if (real_zerop (arg))
6980         return build_real (type, dconst1);
6981
6982       /* Optimize expN(1.0) = N.  */
6983       if (real_onep (arg))
6984         {
6985           REAL_VALUE_TYPE cst;
6986
6987           real_convert (&cst, TYPE_MODE (type), value);
6988           return build_real (type, cst);
6989         }
6990
6991       /* Attempt to evaluate expN(integer) at compile-time.  */
6992       if (flag_unsafe_math_optimizations
6993           && TREE_CODE (arg) == REAL_CST
6994           && ! TREE_CONSTANT_OVERFLOW (arg))
6995         {
6996           REAL_VALUE_TYPE cint;
6997           REAL_VALUE_TYPE c;
6998           HOST_WIDE_INT n;
6999
7000           c = TREE_REAL_CST (arg);
7001           n = real_to_integer (&c);
7002           real_from_integer (&cint, VOIDmode, n,
7003                              n < 0 ? -1 : 0, 0);
7004           if (real_identical (&c, &cint))
7005             {
7006               REAL_VALUE_TYPE x;
7007
7008               real_powi (&x, TYPE_MODE (type), value, n);
7009               return build_real (type, x);
7010             }
7011         }
7012
7013       /* Optimize expN(logN(x)) = x.  */
7014       if (flag_unsafe_math_optimizations)
7015         {
7016           const enum built_in_function fcode = builtin_mathfn_code (arg);
7017
7018           if ((value == &dconste
7019                && (fcode == BUILT_IN_LOG
7020                    || fcode == BUILT_IN_LOGF
7021                    || fcode == BUILT_IN_LOGL))
7022               || (value == &dconst2
7023                   && (fcode == BUILT_IN_LOG2
7024                       || fcode == BUILT_IN_LOG2F
7025                       || fcode == BUILT_IN_LOG2L))
7026               || (value == &dconst10
7027                   && (fcode == BUILT_IN_LOG10
7028                       || fcode == BUILT_IN_LOG10F
7029                       || fcode == BUILT_IN_LOG10L)))
7030             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
7031         }
7032     }
7033
7034   return 0;
7035 }
7036
7037 /* Fold function call to builtin memcpy.  Return
7038    NULL_TREE if no simplification can be made.  */
7039
7040 static tree
7041 fold_builtin_memcpy (tree exp)
7042 {
7043   tree arglist = TREE_OPERAND (exp, 1);
7044   tree dest, src, len;
7045
7046   if (!validate_arglist (arglist,
7047                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7048     return 0;
7049
7050   dest = TREE_VALUE (arglist);
7051   src = TREE_VALUE (TREE_CHAIN (arglist));
7052   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7053
7054   /* If the LEN parameter is zero, return DEST.  */
7055   if (integer_zerop (len))
7056     return omit_one_operand (TREE_TYPE (exp), dest, src);
7057
7058   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7059   if (operand_equal_p (src, dest, 0))
7060     return omit_one_operand (TREE_TYPE (exp), dest, len);
7061
7062   return 0;
7063 }
7064
7065 /* Fold function call to builtin mempcpy.  Return
7066    NULL_TREE if no simplification can be made.  */
7067
7068 static tree
7069 fold_builtin_mempcpy (tree exp)
7070 {
7071   tree arglist = TREE_OPERAND (exp, 1);
7072   tree dest, src, len;
7073
7074   if (!validate_arglist (arglist,
7075                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7076     return 0;
7077
7078   dest = TREE_VALUE (arglist);
7079   src = TREE_VALUE (TREE_CHAIN (arglist));
7080   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7081
7082   /* If the LEN parameter is zero, return DEST.  */
7083   if (integer_zerop (len))
7084     return omit_one_operand (TREE_TYPE (exp), dest, src);
7085
7086   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
7087   if (operand_equal_p (src, dest, 0))
7088     {
7089       tree temp = fold_convert (TREE_TYPE (dest), len);
7090       temp = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, temp));
7091       return fold_convert (TREE_TYPE (exp), temp);
7092     }
7093
7094   return 0;
7095 }
7096
7097 /* Fold function call to builtin memmove.  Return
7098    NULL_TREE if no simplification can be made.  */
7099
7100 static tree
7101 fold_builtin_memmove (tree exp)
7102 {
7103   tree arglist = TREE_OPERAND (exp, 1);
7104   tree dest, src, len;
7105
7106   if (!validate_arglist (arglist,
7107                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7108     return 0;
7109
7110   dest = TREE_VALUE (arglist);
7111   src = TREE_VALUE (TREE_CHAIN (arglist));
7112   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7113
7114   /* If the LEN parameter is zero, return DEST.  */
7115   if (integer_zerop (len))
7116     return omit_one_operand (TREE_TYPE (exp), dest, src);
7117
7118   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7119   if (operand_equal_p (src, dest, 0))
7120     return omit_one_operand (TREE_TYPE (exp), dest, len);
7121
7122   return 0;
7123 }
7124
7125 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7126    the length of the string to be copied.  Return NULL_TREE if no
7127    simplification can be made.  */
7128
7129 tree
7130 fold_builtin_strcpy (tree exp, tree len)
7131 {
7132   tree arglist = TREE_OPERAND (exp, 1);
7133   tree dest, src, fn;
7134
7135   if (!validate_arglist (arglist,
7136                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7137     return 0;
7138
7139   dest = TREE_VALUE (arglist);
7140   src = TREE_VALUE (TREE_CHAIN (arglist));
7141
7142   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7143   if (operand_equal_p (src, dest, 0))
7144     return fold_convert (TREE_TYPE (exp), dest);
7145
7146   if (optimize_size)
7147     return 0;
7148
7149   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7150   if (!fn)
7151     return 0;
7152
7153   if (!len)
7154     {
7155       len = c_strlen (src, 1);
7156       if (! len || TREE_SIDE_EFFECTS (len))
7157         return 0;
7158     }
7159
7160   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7161   arglist = build_tree_list (NULL_TREE, len);
7162   arglist = tree_cons (NULL_TREE, src, arglist);
7163   arglist = tree_cons (NULL_TREE, dest, arglist);
7164   return fold_convert (TREE_TYPE (exp),
7165                        build_function_call_expr (fn, arglist));
7166 }
7167
7168 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7169    the length of the source string.  Return NULL_TREE if no simplification
7170    can be made.  */
7171
7172 tree
7173 fold_builtin_strncpy (tree exp, tree slen)
7174 {
7175   tree arglist = TREE_OPERAND (exp, 1);
7176   tree dest, src, len, fn;
7177
7178   if (!validate_arglist (arglist,
7179                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7180     return 0;
7181
7182   dest = TREE_VALUE (arglist);
7183   src = TREE_VALUE (TREE_CHAIN (arglist));
7184   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7185
7186   /* If the LEN parameter is zero, return DEST.  */
7187   if (integer_zerop (len))
7188     return omit_one_operand (TREE_TYPE (exp), dest, src);
7189
7190   /* We can't compare slen with len as constants below if len is not a
7191      constant.  */
7192   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7193     return 0;
7194
7195   if (!slen)
7196     slen = c_strlen (src, 1);
7197
7198   /* Now, we must be passed a constant src ptr parameter.  */
7199   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7200     return 0;
7201
7202   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7203
7204   /* We do not support simplification of this case, though we do
7205      support it when expanding trees into RTL.  */
7206   /* FIXME: generate a call to __builtin_memset.  */
7207   if (tree_int_cst_lt (slen, len))
7208     return 0;
7209
7210   /* OK transform into builtin memcpy.  */
7211   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7212   if (!fn)
7213     return 0;
7214   return fold_convert (TREE_TYPE (exp),
7215                        build_function_call_expr (fn, arglist));
7216 }
7217
7218 /* Fold function call to builtin strchr and strrchr.
7219    Return NULL_TREE if no simplification can be made.  */
7220
7221 static tree
7222 fold_builtin_strchr (tree exp, bool actually_strrchr)
7223 {
7224   tree arglist = TREE_OPERAND (exp, 1);
7225   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7226     return 0;
7227   else
7228     {
7229       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
7230       const char *p1;
7231
7232       if (TREE_CODE (s2) != INTEGER_CST)
7233         return 0;
7234
7235       p1 = c_getstr (s1);
7236       if (p1 != NULL)
7237         {
7238           char c;
7239           const char *r;
7240
7241           if (target_char_cast (s2, &c))
7242             return 0;
7243
7244           r = actually_strrchr ? strrchr (p1, c) : strchr (p1, c);
7245
7246           if (r == NULL)
7247             return fold_convert (TREE_TYPE (s1), integer_zero_node);
7248
7249           /* Return an offset into the constant string argument.  */
7250           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
7251                                s1, fold_convert (TREE_TYPE (s1),
7252                                                  ssize_int (r - p1))));
7253         }
7254
7255       if (actually_strrchr)
7256         {
7257           tree fn;
7258
7259           if (!integer_zerop (s2))
7260             return 0;
7261
7262           fn = implicit_built_in_decls[BUILT_IN_STRCHR];
7263           if (!fn)
7264             return 0;
7265
7266           /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
7267           return build_function_call_expr (fn, arglist);
7268         }
7269
7270       return 0;
7271     }
7272 }
7273
7274 /* Fold function call to builtin memcmp.  Return
7275    NULL_TREE if no simplification can be made.  */
7276
7277 static tree
7278 fold_builtin_memcmp (tree arglist)
7279 {
7280   tree arg1, arg2, len;
7281   const char *p1, *p2;
7282
7283   if (!validate_arglist (arglist,
7284                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7285     return 0;
7286
7287   arg1 = TREE_VALUE (arglist);
7288   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7289   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7290
7291   /* If the LEN parameter is zero, return zero.  */
7292   if (integer_zerop (len))
7293     return omit_two_operands (integer_type_node, integer_zero_node,
7294                               arg1, arg2);
7295
7296   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7297   if (operand_equal_p (arg1, arg2, 0))
7298     return omit_one_operand (integer_type_node, integer_zero_node, len);
7299
7300   p1 = c_getstr (arg1);
7301   p2 = c_getstr (arg2);
7302
7303   /* If all arguments are constant, and the value of len is not greater
7304      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7305   if (host_integerp (len, 1) && p1 && p2
7306       && compare_tree_int (len, strlen (p1) + 1) <= 0
7307       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7308     {
7309       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7310
7311       if (r > 0)
7312         return integer_one_node;
7313       else if (r < 0)
7314         return integer_minus_one_node;
7315       else
7316         return integer_zero_node;
7317     }
7318
7319   /* If len parameter is one, return an expression corresponding to
7320      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7321   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7322     {
7323       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7324       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7325       tree ind1 = fold_convert (integer_type_node,
7326                                 build1 (INDIRECT_REF, cst_uchar_node,
7327                                         fold_convert (cst_uchar_ptr_node,
7328                                                       arg1)));
7329       tree ind2 = fold_convert (integer_type_node,
7330                                 build1 (INDIRECT_REF, cst_uchar_node,
7331                                         fold_convert (cst_uchar_ptr_node,
7332                                                       arg2)));
7333       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7334     }
7335
7336   return 0;
7337 }
7338
7339 /* Fold function call to builtin strcmp.  Return
7340    NULL_TREE if no simplification can be made.  */
7341
7342 static tree
7343 fold_builtin_strcmp (tree arglist)
7344 {
7345   tree arg1, arg2;
7346   const char *p1, *p2;
7347
7348   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7349     return 0;
7350
7351   arg1 = TREE_VALUE (arglist);
7352   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7353
7354   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7355   if (operand_equal_p (arg1, arg2, 0))
7356     return integer_zero_node;
7357
7358   p1 = c_getstr (arg1);
7359   p2 = c_getstr (arg2);
7360
7361   if (p1 && p2)
7362     {
7363       const int i = strcmp (p1, p2);
7364       if (i < 0)
7365         return integer_minus_one_node;
7366       else if (i > 0)
7367         return integer_one_node;
7368       else
7369         return integer_zero_node;
7370     }
7371
7372   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7373   if (p2 && *p2 == '\0')
7374     {
7375       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7376       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7377       return fold_convert (integer_type_node,
7378                            build1 (INDIRECT_REF, cst_uchar_node,
7379                                    fold_convert (cst_uchar_ptr_node,
7380                                                  arg1)));
7381     }
7382
7383   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7384   if (p1 && *p1 == '\0')
7385     {
7386       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7387       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7388       tree temp = fold_convert (integer_type_node,
7389                                 build1 (INDIRECT_REF, cst_uchar_node,
7390                                         fold_convert (cst_uchar_ptr_node,
7391                                                       arg2)));
7392       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7393     }
7394
7395   return 0;
7396 }
7397
7398 /* Fold function call to builtin strncmp.  Return
7399    NULL_TREE if no simplification can be made.  */
7400
7401 static tree
7402 fold_builtin_strncmp (tree arglist)
7403 {
7404   tree arg1, arg2, len;
7405   const char *p1, *p2;
7406
7407   if (!validate_arglist (arglist,
7408                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7409     return 0;
7410
7411   arg1 = TREE_VALUE (arglist);
7412   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7413   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7414
7415   /* If the LEN parameter is zero, return zero.  */
7416   if (integer_zerop (len))
7417     return omit_two_operands (integer_type_node, integer_zero_node,
7418                               arg1, arg2);
7419
7420   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7421   if (operand_equal_p (arg1, arg2, 0))
7422     return omit_one_operand (integer_type_node, integer_zero_node, len);
7423
7424   p1 = c_getstr (arg1);
7425   p2 = c_getstr (arg2);
7426
7427   if (host_integerp (len, 1) && p1 && p2)
7428     {
7429       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7430       if (i > 0)
7431         return integer_one_node;
7432       else if (i < 0)
7433         return integer_minus_one_node;
7434       else
7435         return integer_zero_node;
7436     }
7437
7438   /* If the second arg is "", and the length is greater than zero,
7439      return *(const unsigned char*)arg1.  */
7440   if (p2 && *p2 == '\0'
7441       && TREE_CODE (len) == INTEGER_CST
7442       && tree_int_cst_sgn (len) == 1)
7443     {
7444       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7445       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7446       return fold_convert (integer_type_node,
7447                            build1 (INDIRECT_REF, cst_uchar_node,
7448                                    fold_convert (cst_uchar_ptr_node,
7449                                                  arg1)));
7450     }
7451
7452   /* If the first arg is "", and the length is greater than zero,
7453      return -*(const unsigned char*)arg2.  */
7454   if (p1 && *p1 == '\0'
7455       && TREE_CODE (len) == INTEGER_CST
7456       && tree_int_cst_sgn (len) == 1)
7457     {
7458       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7459       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7460       tree temp = fold_convert (integer_type_node,
7461                                 build1 (INDIRECT_REF, cst_uchar_node,
7462                                         fold_convert (cst_uchar_ptr_node,
7463                                                       arg2)));
7464       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7465     }
7466
7467   /* If len parameter is one, return an expression corresponding to
7468      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7469   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7470     {
7471       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7472       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7473       tree ind1 = fold_convert (integer_type_node,
7474                                 build1 (INDIRECT_REF, cst_uchar_node,
7475                                         fold_convert (cst_uchar_ptr_node,
7476                                                       arg1)));
7477       tree ind2 = fold_convert (integer_type_node,
7478                                 build1 (INDIRECT_REF, cst_uchar_node,
7479                                         fold_convert (cst_uchar_ptr_node,
7480                                                       arg2)));
7481       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7482     }
7483
7484   return 0;
7485 }
7486
7487 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7488    NULL_TREE if no simplification can be made.  */
7489
7490 static tree
7491 fold_builtin_signbit (tree exp)
7492 {
7493   tree arglist = TREE_OPERAND (exp, 1);
7494   tree arg, temp;
7495
7496   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7497     return NULL_TREE;
7498
7499   arg = TREE_VALUE (arglist);
7500
7501   /* If ARG is a compile-time constant, determine the result.  */
7502   if (TREE_CODE (arg) == REAL_CST
7503       && !TREE_CONSTANT_OVERFLOW (arg))
7504     {
7505       REAL_VALUE_TYPE c;
7506
7507       c = TREE_REAL_CST (arg);
7508       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7509       return fold_convert (TREE_TYPE (exp), temp);
7510     }
7511
7512   /* If ARG is non-negative, the result is always zero.  */
7513   if (tree_expr_nonnegative_p (arg))
7514     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7515
7516   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7517   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7518     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7519                          build_real (TREE_TYPE (arg), dconst0)));
7520
7521   return NULL_TREE;
7522 }
7523
7524 /* Fold function call to builtin copysign, copysignf or copysignl.
7525    Return NULL_TREE if no simplification can be made.  */
7526
7527 static tree
7528 fold_builtin_copysign (tree arglist, tree type)
7529 {
7530   tree arg1, arg2;
7531
7532   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7533     return NULL_TREE;
7534
7535   arg1 = TREE_VALUE (arglist);
7536   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7537
7538   /* copysign(X,X) is X.  */
7539   if (operand_equal_p (arg1, arg2, 0))
7540     return fold_convert (type, arg1);
7541
7542   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7543   if (TREE_CODE (arg1) == REAL_CST
7544       && TREE_CODE (arg2) == REAL_CST
7545       && !TREE_CONSTANT_OVERFLOW (arg1)
7546       && !TREE_CONSTANT_OVERFLOW (arg2))
7547     {
7548       REAL_VALUE_TYPE c1, c2;
7549
7550       c1 = TREE_REAL_CST (arg1);
7551       c2 = TREE_REAL_CST (arg2);
7552       real_copysign (&c1, &c2);
7553       return build_real (type, c1);
7554       c1.sign = c2.sign;
7555     }
7556
7557   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7558      Remember to evaluate Y for side-effects.  */
7559   if (tree_expr_nonnegative_p (arg2))
7560     return omit_one_operand (type,
7561                              fold (build1 (ABS_EXPR, type, arg1)),
7562                              arg2);
7563
7564   return NULL_TREE;
7565 }
7566
7567 /* Fold a call to builtin isascii.  */
7568
7569 static tree
7570 fold_builtin_isascii (tree arglist)
7571 {
7572   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7573     return 0;
7574   else
7575     {
7576       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7577       tree arg = TREE_VALUE (arglist);
7578
7579       arg = fold (build2 (EQ_EXPR, integer_type_node,
7580                           build2 (BIT_AND_EXPR, integer_type_node, arg,
7581                                   build_int_2 (~ (unsigned HOST_WIDE_INT) 0x7f,
7582                                                ~ (HOST_WIDE_INT) 0)),
7583                           integer_zero_node));
7584
7585       if (in_gimple_form && !TREE_CONSTANT (arg))
7586         return NULL_TREE;
7587       else
7588         return arg;
7589     }
7590 }
7591
7592 /* Fold a call to builtin toascii.  */
7593
7594 static tree
7595 fold_builtin_toascii (tree arglist)
7596 {
7597   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7598     return 0;
7599   else
7600     {
7601       /* Transform toascii(c) -> (c & 0x7f).  */
7602       tree arg = TREE_VALUE (arglist);
7603
7604       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7605                            build_int_2 (0x7f, 0)));
7606     }
7607 }
7608
7609 /* Fold a call to builtin isdigit.  */
7610
7611 static tree
7612 fold_builtin_isdigit (tree arglist)
7613 {
7614   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7615     return 0;
7616   else
7617     {
7618       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7619       /* According to the C standard, isdigit is unaffected by locale.  */
7620       tree arg = TREE_VALUE (arglist);
7621       arg = fold_convert (unsigned_type_node, arg);
7622       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7623                     fold_convert (unsigned_type_node,
7624                                   build_int_2 (TARGET_DIGIT0, 0)));
7625       arg = build2 (LE_EXPR, integer_type_node, arg,
7626                     fold_convert (unsigned_type_node, build_int_2 (9, 0)));
7627       arg = fold (arg);
7628       if (in_gimple_form && !TREE_CONSTANT (arg))
7629         return NULL_TREE;
7630       else
7631         return arg;
7632     }
7633 }
7634
7635 /* Fold a call to fabs, fabsf or fabsl.  */
7636
7637 static tree
7638 fold_builtin_fabs (tree arglist, tree type)
7639 {
7640   tree arg;
7641
7642   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7643     return 0;
7644
7645   arg = TREE_VALUE (arglist);
7646   if (TREE_CODE (arg) == REAL_CST)
7647     return fold_abs_const (arg, type);
7648   return fold (build1 (ABS_EXPR, type, arg));
7649 }
7650
7651 /* Fold a call to abs, labs, llabs or imaxabs.  */
7652
7653 static tree
7654 fold_builtin_abs (tree arglist, tree type)
7655 {
7656   tree arg;
7657
7658   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7659     return 0;
7660
7661   arg = TREE_VALUE (arglist);
7662   if (TREE_CODE (arg) == INTEGER_CST)
7663     return fold_abs_const (arg, type);
7664   return fold (build1 (ABS_EXPR, type, arg));
7665 }
7666
7667 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7668    EXP is the CALL_EXPR for the call.  */
7669
7670 static tree
7671 fold_builtin_classify (tree exp, int builtin_index)
7672 {
7673   tree fndecl = get_callee_fndecl (exp);
7674   tree arglist = TREE_OPERAND (exp, 1);
7675   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7676   tree arg;
7677   REAL_VALUE_TYPE r;
7678
7679   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7680     {
7681       /* Check that we have exactly one argument.  */
7682       if (arglist == 0)
7683         {
7684           error ("too few arguments to function `%s'",
7685                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7686           return error_mark_node;
7687         }
7688       else if (TREE_CHAIN (arglist) != 0)
7689         {
7690           error ("too many arguments to function `%s'",
7691                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7692           return error_mark_node;
7693         }
7694       else
7695         {
7696           error ("non-floating-point argument to function `%s'",
7697                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7698           return error_mark_node;
7699         }
7700     }
7701
7702   arg = TREE_VALUE (arglist);
7703   switch (builtin_index)
7704     {
7705     case BUILT_IN_ISINF:
7706       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7707         return omit_one_operand (type, integer_zero_node, arg);
7708
7709       if (TREE_CODE (arg) == REAL_CST)
7710         {
7711           r = TREE_REAL_CST (arg);
7712           if (real_isinf (&r))
7713             return real_compare (GT_EXPR, &r, &dconst0)
7714                    ? integer_one_node : integer_minus_one_node;
7715           else
7716             return integer_zero_node;
7717         }
7718
7719       return NULL_TREE;
7720
7721     case BUILT_IN_FINITE:
7722       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7723           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7724         return omit_one_operand (type, integer_zero_node, arg);
7725
7726       if (TREE_CODE (arg) == REAL_CST)
7727         {
7728           r = TREE_REAL_CST (arg);
7729           return real_isinf (&r) || real_isnan (&r)
7730                  ? integer_zero_node : integer_one_node;
7731         }
7732
7733       return NULL_TREE;
7734
7735     case BUILT_IN_ISNAN:
7736       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7737         return omit_one_operand (type, integer_zero_node, arg);
7738
7739       if (TREE_CODE (arg) == REAL_CST)
7740         {
7741           r = TREE_REAL_CST (arg);
7742           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7743         }
7744
7745       arg = builtin_save_expr (arg);
7746       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7747
7748     default:
7749       abort ();
7750     }
7751 }
7752
7753 /* Fold a call to an unordered comparison function such as
7754    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7755    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7756    the opposite of the desired result.  UNORDERED_CODE is used
7757    for modes that can hold NaNs and ORDERED_CODE is used for
7758    the rest.  */
7759
7760 static tree
7761 fold_builtin_unordered_cmp (tree exp,
7762                             enum tree_code unordered_code,
7763                             enum tree_code ordered_code)
7764 {
7765   tree fndecl = get_callee_fndecl (exp);
7766   tree arglist = TREE_OPERAND (exp, 1);
7767   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7768   enum tree_code code;
7769   tree arg0, arg1;
7770
7771   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7772     {
7773       enum tree_code code0, code1;
7774       tree type0, type1;
7775       tree cmp_type = 0;
7776
7777       /* Check that we have exactly two arguments.  */
7778       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7779         {
7780           error ("too few arguments to function `%s'",
7781                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7782           return error_mark_node;
7783         }
7784       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7785         {
7786           error ("too many arguments to function `%s'",
7787                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7788           return error_mark_node;
7789         }
7790
7791       arg0 = TREE_VALUE (arglist);
7792       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7793
7794       type0 = TREE_TYPE (arg0);
7795       type1 = TREE_TYPE (arg1);
7796
7797       code0 = TREE_CODE (type0);
7798       code1 = TREE_CODE (type1);
7799
7800       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7801         /* Choose the wider of two real types.  */
7802         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7803                    ? type0 : type1;
7804       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7805         cmp_type = type0;
7806       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7807         cmp_type = type1;
7808       else
7809         {
7810           error ("non-floating-point argument to function `%s'",
7811                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7812           return error_mark_node;
7813         }
7814
7815       arg0 = fold_convert (cmp_type, arg0);
7816       arg1 = fold_convert (cmp_type, arg1);
7817     }
7818   else
7819     {
7820       arg0 = TREE_VALUE (arglist);
7821       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7822     }
7823
7824   if (unordered_code == UNORDERED_EXPR)
7825     {
7826       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7827         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7828       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7829     }
7830
7831   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7832                                                       : ordered_code;
7833   return fold (build1 (TRUTH_NOT_EXPR, type,
7834                        fold (build2 (code, type, arg0, arg1))));
7835 }
7836
7837 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7838    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7839    result of the function call is ignored.  This function returns NULL_TREE
7840    if no simplification was possible.  */
7841
7842 static tree
7843 fold_builtin_1 (tree exp, bool ignore)
7844 {
7845   tree fndecl = get_callee_fndecl (exp);
7846   tree arglist = TREE_OPERAND (exp, 1);
7847   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7848
7849   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7850     return 0;
7851
7852   switch (DECL_FUNCTION_CODE (fndecl))
7853     {
7854     case BUILT_IN_CONSTANT_P:
7855       return fold_builtin_constant_p (arglist);
7856
7857     case BUILT_IN_EXPECT:
7858       return fold_builtin_expect (arglist);
7859
7860     case BUILT_IN_CLASSIFY_TYPE:
7861       return fold_builtin_classify_type (arglist);
7862
7863     case BUILT_IN_STRLEN:
7864       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7865         {
7866           tree len = c_strlen (TREE_VALUE (arglist), 0);
7867           if (len)
7868             {
7869               /* Convert from the internal "sizetype" type to "size_t".  */
7870               if (size_type_node)
7871                 len = fold_convert (size_type_node, len);
7872               return len;
7873             }
7874         }
7875       break;
7876
7877     case BUILT_IN_FABS:
7878     case BUILT_IN_FABSF:
7879     case BUILT_IN_FABSL:
7880       return fold_builtin_fabs (arglist, type);
7881
7882     case BUILT_IN_ABS:
7883     case BUILT_IN_LABS:
7884     case BUILT_IN_LLABS:
7885     case BUILT_IN_IMAXABS:
7886       return fold_builtin_abs (arglist, type);
7887
7888     case BUILT_IN_CONJ:
7889     case BUILT_IN_CONJF:
7890     case BUILT_IN_CONJL:
7891       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7892         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7893       break;
7894
7895     case BUILT_IN_CREAL:
7896     case BUILT_IN_CREALF:
7897     case BUILT_IN_CREALL:
7898       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7899         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7900                                          TREE_VALUE (arglist))));
7901       break;
7902
7903     case BUILT_IN_CIMAG:
7904     case BUILT_IN_CIMAGF:
7905     case BUILT_IN_CIMAGL:
7906       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7907         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7908                                          TREE_VALUE (arglist))));
7909       break;
7910
7911     case BUILT_IN_CABS:
7912     case BUILT_IN_CABSF:
7913     case BUILT_IN_CABSL:
7914       return fold_builtin_cabs (arglist, type);
7915
7916     case BUILT_IN_SQRT:
7917     case BUILT_IN_SQRTF:
7918     case BUILT_IN_SQRTL:
7919       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7920         {
7921           enum built_in_function fcode;
7922           tree arg = TREE_VALUE (arglist);
7923
7924           /* Optimize sqrt of constant value.  */
7925           if (TREE_CODE (arg) == REAL_CST
7926               && ! TREE_CONSTANT_OVERFLOW (arg))
7927             {
7928               REAL_VALUE_TYPE r, x;
7929
7930               x = TREE_REAL_CST (arg);
7931               if (real_sqrt (&r, TYPE_MODE (type), &x)
7932                   || (!flag_trapping_math && !flag_errno_math))
7933                 return build_real (type, r);
7934             }
7935
7936           /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7937           fcode = builtin_mathfn_code (arg);
7938           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7939             {
7940               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7941               arg = fold (build2 (MULT_EXPR, type,
7942                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
7943                                   build_real (type, dconsthalf)));
7944               arglist = build_tree_list (NULL_TREE, arg);
7945               return build_function_call_expr (expfn, arglist);
7946             }
7947
7948           /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7949           if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7950             {
7951               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7952
7953               if (powfn)
7954                 {
7955                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7956                   tree tree_root;
7957                   /* The inner root was either sqrt or cbrt.  */
7958                   REAL_VALUE_TYPE dconstroot =
7959                     BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7960
7961                   /* Adjust for the outer root.  */
7962                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7963                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7964                   tree_root = build_real (type, dconstroot);
7965                   arglist = tree_cons (NULL_TREE, arg0,
7966                                        build_tree_list (NULL_TREE, tree_root));
7967                   return build_function_call_expr (powfn, arglist);
7968                 }
7969             }
7970
7971           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
7972           if (flag_unsafe_math_optimizations
7973               && (fcode == BUILT_IN_POW
7974                   || fcode == BUILT_IN_POWF
7975                   || fcode == BUILT_IN_POWL))
7976             {
7977               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7978               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7979               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7980               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7981                                          build_real (type, dconsthalf)));
7982               arglist = tree_cons (NULL_TREE, arg0,
7983                                    build_tree_list (NULL_TREE, narg1));
7984               return build_function_call_expr (powfn, arglist);
7985             }
7986         }
7987       break;
7988
7989     case BUILT_IN_CBRT:
7990     case BUILT_IN_CBRTF:
7991     case BUILT_IN_CBRTL:
7992       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7993         {
7994           tree arg = TREE_VALUE (arglist);
7995           const enum built_in_function fcode = builtin_mathfn_code (arg);
7996
7997           /* Optimize cbrt of constant value.  */
7998           if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7999             return arg;
8000
8001           /* Optimize cbrt(expN(x)) -> expN(x/3).  */
8002           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8003             {
8004               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
8005               const REAL_VALUE_TYPE third_trunc =
8006                 real_value_truncate (TYPE_MODE (type), dconstthird);
8007               arg = fold (build2 (MULT_EXPR, type,
8008                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
8009                                   build_real (type, third_trunc)));
8010               arglist = build_tree_list (NULL_TREE, arg);
8011               return build_function_call_expr (expfn, arglist);
8012             }
8013
8014           /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
8015           /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
8016              x is negative pow will error but cbrt won't.  */
8017           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8018             {
8019               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
8020
8021               if (powfn)
8022                 {
8023                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
8024                   tree tree_root;
8025                   REAL_VALUE_TYPE dconstroot = dconstthird;
8026
8027                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
8028                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
8029                   tree_root = build_real (type, dconstroot);
8030                   arglist = tree_cons (NULL_TREE, arg0,
8031                                        build_tree_list (NULL_TREE, tree_root));
8032                   return build_function_call_expr (powfn, arglist);
8033                 }
8034
8035             }
8036         }
8037       break;
8038
8039     case BUILT_IN_SIN:
8040     case BUILT_IN_SINF:
8041     case BUILT_IN_SINL:
8042       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8043         {
8044           tree arg = TREE_VALUE (arglist);
8045
8046           /* Optimize sin(0.0) = 0.0.  */
8047           if (real_zerop (arg))
8048             return arg;
8049         }
8050       break;
8051
8052     case BUILT_IN_COS:
8053     case BUILT_IN_COSF:
8054     case BUILT_IN_COSL:
8055       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8056         {
8057           tree arg = TREE_VALUE (arglist);
8058
8059           /* Optimize cos(0.0) = 1.0.  */
8060           if (real_zerop (arg))
8061             return build_real (type, dconst1);
8062
8063           /* Optimize cos(-x) into cos(x).  */
8064           if (TREE_CODE (arg) == NEGATE_EXPR)
8065             {
8066               tree arglist = build_tree_list (NULL_TREE,
8067                                               TREE_OPERAND (arg, 0));
8068               return build_function_call_expr (fndecl, arglist);
8069             }
8070         }
8071       break;
8072
8073     case BUILT_IN_EXP:
8074     case BUILT_IN_EXPF:
8075     case BUILT_IN_EXPL:
8076       return fold_builtin_exponent (exp, &dconste);
8077
8078     case BUILT_IN_EXP2:
8079     case BUILT_IN_EXP2F:
8080     case BUILT_IN_EXP2L:
8081       return fold_builtin_exponent (exp, &dconst2);
8082
8083     case BUILT_IN_EXP10:
8084     case BUILT_IN_EXP10F:
8085     case BUILT_IN_EXP10L:
8086     case BUILT_IN_POW10:
8087     case BUILT_IN_POW10F:
8088     case BUILT_IN_POW10L:
8089       return fold_builtin_exponent (exp, &dconst10);
8090
8091     case BUILT_IN_LOG:
8092     case BUILT_IN_LOGF:
8093     case BUILT_IN_LOGL:
8094       return fold_builtin_logarithm (exp, &dconste);
8095
8096     case BUILT_IN_LOG2:
8097     case BUILT_IN_LOG2F:
8098     case BUILT_IN_LOG2L:
8099       return fold_builtin_logarithm (exp, &dconst2);
8100
8101     case BUILT_IN_LOG10:
8102     case BUILT_IN_LOG10F:
8103     case BUILT_IN_LOG10L:
8104       return fold_builtin_logarithm (exp, &dconst10);
8105
8106     case BUILT_IN_TAN:
8107     case BUILT_IN_TANF:
8108     case BUILT_IN_TANL:
8109       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8110         {
8111           enum built_in_function fcode;
8112           tree arg = TREE_VALUE (arglist);
8113
8114           /* Optimize tan(0.0) = 0.0.  */
8115           if (real_zerop (arg))
8116             return arg;
8117
8118           /* Optimize tan(atan(x)) = x.  */
8119           fcode = builtin_mathfn_code (arg);
8120           if (flag_unsafe_math_optimizations
8121               && (fcode == BUILT_IN_ATAN
8122                   || fcode == BUILT_IN_ATANF
8123                   || fcode == BUILT_IN_ATANL))
8124             return TREE_VALUE (TREE_OPERAND (arg, 1));
8125         }
8126       break;
8127
8128     case BUILT_IN_ATAN:
8129     case BUILT_IN_ATANF:
8130     case BUILT_IN_ATANL:
8131       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
8132         {
8133           tree arg = TREE_VALUE (arglist);
8134
8135           /* Optimize atan(0.0) = 0.0.  */
8136           if (real_zerop (arg))
8137             return arg;
8138
8139           /* Optimize atan(1.0) = pi/4.  */
8140           if (real_onep (arg))
8141             {
8142               REAL_VALUE_TYPE cst;
8143
8144               real_convert (&cst, TYPE_MODE (type), &dconstpi);
8145               SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8146               return build_real (type, cst);
8147             }
8148         }
8149       break;
8150
8151     case BUILT_IN_POW:
8152     case BUILT_IN_POWF:
8153     case BUILT_IN_POWL:
8154       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8155         {
8156           enum built_in_function fcode;
8157           tree arg0 = TREE_VALUE (arglist);
8158           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8159
8160           /* Optimize pow(1.0,y) = 1.0.  */
8161           if (real_onep (arg0))
8162             return omit_one_operand (type, build_real (type, dconst1), arg1);
8163
8164           if (TREE_CODE (arg1) == REAL_CST
8165               && ! TREE_CONSTANT_OVERFLOW (arg1))
8166             {
8167               REAL_VALUE_TYPE c;
8168               c = TREE_REAL_CST (arg1);
8169
8170               /* Optimize pow(x,0.0) = 1.0.  */
8171               if (REAL_VALUES_EQUAL (c, dconst0))
8172                 return omit_one_operand (type, build_real (type, dconst1),
8173                                          arg0);
8174
8175               /* Optimize pow(x,1.0) = x.  */
8176               if (REAL_VALUES_EQUAL (c, dconst1))
8177                 return arg0;
8178
8179               /* Optimize pow(x,-1.0) = 1.0/x.  */
8180               if (REAL_VALUES_EQUAL (c, dconstm1))
8181                 return fold (build2 (RDIV_EXPR, type,
8182                                      build_real (type, dconst1), arg0));
8183
8184               /* Optimize pow(x,0.5) = sqrt(x).  */
8185               if (flag_unsafe_math_optimizations
8186                   && REAL_VALUES_EQUAL (c, dconsthalf))
8187                 {
8188                   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8189
8190                   if (sqrtfn != NULL_TREE)
8191                     {
8192                       tree arglist = build_tree_list (NULL_TREE, arg0);
8193                       return build_function_call_expr (sqrtfn, arglist);
8194                     }
8195                 }
8196
8197               /* Attempt to evaluate pow at compile-time.  */
8198               if (TREE_CODE (arg0) == REAL_CST
8199                   && ! TREE_CONSTANT_OVERFLOW (arg0))
8200                 {
8201                   REAL_VALUE_TYPE cint;
8202                   HOST_WIDE_INT n;
8203
8204                   n = real_to_integer (&c);
8205                   real_from_integer (&cint, VOIDmode, n,
8206                                      n < 0 ? -1 : 0, 0);
8207                   if (real_identical (&c, &cint))
8208                     {
8209                       REAL_VALUE_TYPE x;
8210                       bool inexact;
8211
8212                       x = TREE_REAL_CST (arg0);
8213                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8214                       if (flag_unsafe_math_optimizations || !inexact)
8215                         return build_real (type, x);
8216                     }
8217                 }
8218             }
8219
8220           /* Optimize pow(expN(x),y) = expN(x*y).  */
8221           fcode = builtin_mathfn_code (arg0);
8222           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8223             {
8224               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8225               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8226               arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8227               arglist = build_tree_list (NULL_TREE, arg);
8228               return build_function_call_expr (expfn, arglist);
8229             }
8230
8231           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8232           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8233             {
8234               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8235               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8236                                          build_real (type, dconsthalf)));
8237
8238               arglist = tree_cons (NULL_TREE, narg0,
8239                                    build_tree_list (NULL_TREE, narg1));
8240               return build_function_call_expr (fndecl, arglist);
8241             }
8242
8243           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8244           if (flag_unsafe_math_optimizations
8245               && (fcode == BUILT_IN_POW
8246                   || fcode == BUILT_IN_POWF
8247                   || fcode == BUILT_IN_POWL))
8248             {
8249               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8250               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8251               tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8252               arglist = tree_cons (NULL_TREE, arg00,
8253                                    build_tree_list (NULL_TREE, narg1));
8254               return build_function_call_expr (fndecl, arglist);
8255             }
8256         }
8257       break;
8258
8259     case BUILT_IN_INF:
8260     case BUILT_IN_INFF:
8261     case BUILT_IN_INFL:
8262       return fold_builtin_inf (type, true);
8263
8264     case BUILT_IN_HUGE_VAL:
8265     case BUILT_IN_HUGE_VALF:
8266     case BUILT_IN_HUGE_VALL:
8267       return fold_builtin_inf (type, false);
8268
8269     case BUILT_IN_NAN:
8270     case BUILT_IN_NANF:
8271     case BUILT_IN_NANL:
8272       return fold_builtin_nan (arglist, type, true);
8273
8274     case BUILT_IN_NANS:
8275     case BUILT_IN_NANSF:
8276     case BUILT_IN_NANSL:
8277       return fold_builtin_nan (arglist, type, false);
8278
8279     case BUILT_IN_FLOOR:
8280     case BUILT_IN_FLOORF:
8281     case BUILT_IN_FLOORL:
8282       return fold_builtin_floor (exp);
8283
8284     case BUILT_IN_CEIL:
8285     case BUILT_IN_CEILF:
8286     case BUILT_IN_CEILL:
8287       return fold_builtin_ceil (exp);
8288
8289     case BUILT_IN_TRUNC:
8290     case BUILT_IN_TRUNCF:
8291     case BUILT_IN_TRUNCL:
8292       return fold_builtin_trunc (exp);
8293
8294     case BUILT_IN_ROUND:
8295     case BUILT_IN_ROUNDF:
8296     case BUILT_IN_ROUNDL:
8297       return fold_builtin_round (exp);
8298
8299     case BUILT_IN_NEARBYINT:
8300     case BUILT_IN_NEARBYINTF:
8301     case BUILT_IN_NEARBYINTL:
8302     case BUILT_IN_RINT:
8303     case BUILT_IN_RINTF:
8304     case BUILT_IN_RINTL:
8305       return fold_trunc_transparent_mathfn (exp);
8306
8307     case BUILT_IN_LROUND:
8308     case BUILT_IN_LROUNDF:
8309     case BUILT_IN_LROUNDL:
8310     case BUILT_IN_LLROUND:
8311     case BUILT_IN_LLROUNDF:
8312     case BUILT_IN_LLROUNDL:
8313       return fold_builtin_lround (exp);
8314
8315     case BUILT_IN_LRINT:
8316     case BUILT_IN_LRINTF:
8317     case BUILT_IN_LRINTL:
8318     case BUILT_IN_LLRINT:
8319     case BUILT_IN_LLRINTF:
8320     case BUILT_IN_LLRINTL:
8321       return fold_fixed_mathfn (exp);
8322
8323     case BUILT_IN_FFS:
8324     case BUILT_IN_FFSL:
8325     case BUILT_IN_FFSLL:
8326     case BUILT_IN_CLZ:
8327     case BUILT_IN_CLZL:
8328     case BUILT_IN_CLZLL:
8329     case BUILT_IN_CTZ:
8330     case BUILT_IN_CTZL:
8331     case BUILT_IN_CTZLL:
8332     case BUILT_IN_POPCOUNT:
8333     case BUILT_IN_POPCOUNTL:
8334     case BUILT_IN_POPCOUNTLL:
8335     case BUILT_IN_PARITY:
8336     case BUILT_IN_PARITYL:
8337     case BUILT_IN_PARITYLL:
8338       return fold_builtin_bitop (exp);
8339
8340     case BUILT_IN_MEMCPY:
8341       return fold_builtin_memcpy (exp);
8342
8343     case BUILT_IN_MEMPCPY:
8344       return fold_builtin_mempcpy (exp);
8345
8346     case BUILT_IN_MEMMOVE:
8347       return fold_builtin_memmove (exp);
8348
8349     case BUILT_IN_STRCPY:
8350       return fold_builtin_strcpy (exp, NULL_TREE);
8351
8352     case BUILT_IN_STRNCPY:
8353       return fold_builtin_strncpy (exp, NULL_TREE);
8354
8355     case BUILT_IN_INDEX:
8356     case BUILT_IN_STRCHR:
8357       return fold_builtin_strchr (exp, false);
8358
8359     case BUILT_IN_RINDEX:
8360     case BUILT_IN_STRRCHR:
8361       return fold_builtin_strchr (exp, true);
8362
8363     case BUILT_IN_MEMCMP:
8364       return fold_builtin_memcmp (arglist);
8365
8366     case BUILT_IN_STRCMP:
8367       return fold_builtin_strcmp (arglist);
8368
8369     case BUILT_IN_STRNCMP:
8370       return fold_builtin_strncmp (arglist);
8371
8372     case BUILT_IN_SIGNBIT:
8373     case BUILT_IN_SIGNBITF:
8374     case BUILT_IN_SIGNBITL:
8375       return fold_builtin_signbit (exp);
8376
8377     case BUILT_IN_ISASCII:
8378       return fold_builtin_isascii (arglist);
8379
8380     case BUILT_IN_TOASCII:
8381       return fold_builtin_toascii (arglist);
8382
8383     case BUILT_IN_ISDIGIT:
8384       return fold_builtin_isdigit (arglist);
8385
8386     case BUILT_IN_COPYSIGN:
8387     case BUILT_IN_COPYSIGNF:
8388     case BUILT_IN_COPYSIGNL:
8389       return fold_builtin_copysign (arglist, type);
8390
8391     case BUILT_IN_FINITE:
8392     case BUILT_IN_FINITEF:
8393     case BUILT_IN_FINITEL:
8394       return fold_builtin_classify (exp, BUILT_IN_FINITE);
8395
8396     case BUILT_IN_ISINF:
8397     case BUILT_IN_ISINFF:
8398     case BUILT_IN_ISINFL:
8399       return fold_builtin_classify (exp, BUILT_IN_ISINF);
8400
8401     case BUILT_IN_ISNAN:
8402     case BUILT_IN_ISNANF:
8403     case BUILT_IN_ISNANL:
8404       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
8405
8406     case BUILT_IN_ISGREATER:
8407       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8408     case BUILT_IN_ISGREATEREQUAL:
8409       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8410     case BUILT_IN_ISLESS:
8411       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8412     case BUILT_IN_ISLESSEQUAL:
8413       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8414     case BUILT_IN_ISLESSGREATER:
8415       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8416     case BUILT_IN_ISUNORDERED:
8417       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8418
8419     case BUILT_IN_FPUTS:
8420       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8421
8422     case BUILT_IN_FPUTS_UNLOCKED:
8423       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8424
8425     default:
8426       break;
8427     }
8428
8429   return 0;
8430 }
8431
8432 /* A wrapper function for builtin folding that prevents warnings for
8433    "statement without effect" and the like, caused by removing the
8434    call node earlier than the warning is generated.  */
8435
8436 tree
8437 fold_builtin (tree exp, bool ignore)
8438 {
8439   exp = fold_builtin_1 (exp, ignore);
8440   if (exp)
8441     {
8442       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8443       if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8444         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8445       TREE_NO_WARNING (exp) = 1;
8446     }
8447   return exp;
8448 }
8449
8450 /* Conveniently construct a function call expression.  */
8451
8452 tree
8453 build_function_call_expr (tree fn, tree arglist)
8454 {
8455   tree call_expr;
8456
8457   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8458   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8459                       call_expr, arglist, NULL_TREE);
8460   return fold (call_expr);
8461 }
8462
8463 /* This function validates the types of a function call argument list
8464    represented as a tree chain of parameters against a specified list
8465    of tree_codes.  If the last specifier is a 0, that represents an
8466    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8467
8468 static int
8469 validate_arglist (tree arglist, ...)
8470 {
8471   enum tree_code code;
8472   int res = 0;
8473   va_list ap;
8474
8475   va_start (ap, arglist);
8476
8477   do
8478     {
8479       code = va_arg (ap, enum tree_code);
8480       switch (code)
8481         {
8482         case 0:
8483           /* This signifies an ellipses, any further arguments are all ok.  */
8484           res = 1;
8485           goto end;
8486         case VOID_TYPE:
8487           /* This signifies an endlink, if no arguments remain, return
8488              true, otherwise return false.  */
8489           res = arglist == 0;
8490           goto end;
8491         default:
8492           /* If no parameters remain or the parameter's code does not
8493              match the specified code, return false.  Otherwise continue
8494              checking any remaining arguments.  */
8495           if (arglist == 0
8496               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8497             goto end;
8498           break;
8499         }
8500       arglist = TREE_CHAIN (arglist);
8501     }
8502   while (1);
8503
8504   /* We need gotos here since we can only have one VA_CLOSE in a
8505      function.  */
8506  end: ;
8507   va_end (ap);
8508
8509   return res;
8510 }
8511
8512 /* Default target-specific builtin expander that does nothing.  */
8513
8514 rtx
8515 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8516                         rtx target ATTRIBUTE_UNUSED,
8517                         rtx subtarget ATTRIBUTE_UNUSED,
8518                         enum machine_mode mode ATTRIBUTE_UNUSED,
8519                         int ignore ATTRIBUTE_UNUSED)
8520 {
8521   return NULL_RTX;
8522 }
8523
8524 /* Returns true is EXP represents data that would potentially reside
8525    in a readonly section.  */
8526
8527 static bool
8528 readonly_data_expr (tree exp)
8529 {
8530   STRIP_NOPS (exp);
8531
8532   if (TREE_CODE (exp) != ADDR_EXPR)
8533     return false;
8534
8535   exp = get_base_address (TREE_OPERAND (exp, 0));
8536   if (!exp)
8537     return false;
8538
8539   /* Make sure we call decl_readonly_section only for trees it
8540      can handle (since it returns true for everything it doesn't
8541      understand).  */
8542   if (TREE_CODE (exp) == STRING_CST
8543       || TREE_CODE (exp) == CONSTRUCTOR
8544       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8545     return decl_readonly_section (exp, 0);
8546   else
8547     return false;
8548 }
8549
8550 /* Front-end to the simplify_builtin_XXX routines.
8551
8552    EXP is a call to a builtin function.  If possible try to simplify
8553    that into a constant, expression or call to a more efficient
8554    builtin function.
8555
8556    If IGNORE is nonzero, then the result of this builtin function
8557    call is ignored.
8558
8559    If simplification is possible, return the simplified tree, otherwise
8560    return NULL_TREE.  */
8561
8562 tree
8563 simplify_builtin (tree exp, int ignore)
8564 {
8565   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8566   tree arglist = TREE_OPERAND (exp, 1);
8567   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8568   tree val;
8569
8570   switch (fcode)
8571     {
8572     case BUILT_IN_FPUTS:
8573       val = fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
8574       break;
8575     case BUILT_IN_FPUTS_UNLOCKED:
8576       val = fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
8577       break;
8578     case BUILT_IN_STRSTR:
8579       val = simplify_builtin_strstr (arglist);
8580       break;
8581     case BUILT_IN_STRCAT:
8582       val = simplify_builtin_strcat (arglist);
8583       break;
8584     case BUILT_IN_STRNCAT:
8585       val = simplify_builtin_strncat (arglist);
8586       break;
8587     case BUILT_IN_STRSPN:
8588       val = simplify_builtin_strspn (arglist);
8589       break;
8590     case BUILT_IN_STRCSPN:
8591       val = simplify_builtin_strcspn (arglist);
8592       break;
8593     case BUILT_IN_STRCHR:
8594     case BUILT_IN_INDEX:
8595       val = simplify_builtin_strchr (arglist);
8596       break;
8597     case BUILT_IN_STRRCHR:
8598     case BUILT_IN_RINDEX:
8599       val = simplify_builtin_strrchr (arglist);
8600       break;
8601     case BUILT_IN_STRCPY:
8602       val = fold_builtin_strcpy (exp, NULL_TREE);
8603       break;
8604     case BUILT_IN_STRNCPY:
8605       val = fold_builtin_strncpy (exp, NULL_TREE);
8606       break;
8607     case BUILT_IN_STRCMP:
8608       val = fold_builtin_strcmp (arglist);
8609       break;
8610     case BUILT_IN_STRNCMP:
8611       val = fold_builtin_strncmp (arglist);
8612       break;
8613     case BUILT_IN_STRPBRK:
8614       val = simplify_builtin_strpbrk (arglist);
8615       break;
8616     case BUILT_IN_BCMP:
8617     case BUILT_IN_MEMCMP:
8618       val = fold_builtin_memcmp (arglist);
8619       break;
8620     case BUILT_IN_VA_START:
8621       simplify_builtin_va_start (arglist);
8622       val = NULL_TREE;
8623       break;
8624     case BUILT_IN_SPRINTF:
8625       val = simplify_builtin_sprintf (arglist, ignore);
8626       break;
8627     case BUILT_IN_CONSTANT_P:
8628       val = fold_builtin_constant_p (arglist);
8629       /* Gimplification will pull the CALL_EXPR for the builtin out of
8630          an if condition.  When not optimizing, we'll not CSE it back.
8631          To avoid link error types of regressions, return false now.  */
8632       if (!val && !optimize)
8633         val = integer_zero_node;
8634       break;
8635     default:
8636       val = NULL_TREE;
8637       break;
8638     }
8639
8640   if (val)
8641     val = fold_convert (TREE_TYPE (exp), val);
8642   return val;
8643 }
8644
8645 /* Simplify a call to the strstr builtin.
8646
8647    Return 0 if no simplification was possible, otherwise return the
8648    simplified form of the call as a tree.
8649
8650    The simplified form may be a constant or other expression which
8651    computes the same value, but in a more efficient manner (including
8652    calls to other builtin functions).
8653
8654    The call may contain arguments which need to be evaluated, but
8655    which are not useful to determine the result of the call.  In
8656    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8657    COMPOUND_EXPR will be an argument which must be evaluated.
8658    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8659    COMPOUND_EXPR in the chain will contain the tree for the simplified
8660    form of the builtin function call.  */
8661
8662 static tree
8663 simplify_builtin_strstr (tree arglist)
8664 {
8665   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8666     return 0;
8667   else
8668     {
8669       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8670       tree fn;
8671       const char *p1, *p2;
8672
8673       p2 = c_getstr (s2);
8674       if (p2 == NULL)
8675         return 0;
8676
8677       p1 = c_getstr (s1);
8678       if (p1 != NULL)
8679         {
8680           const char *r = strstr (p1, p2);
8681
8682           if (r == NULL)
8683             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8684
8685           /* Return an offset into the constant string argument.  */
8686           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8687                                s1, fold_convert (TREE_TYPE (s1),
8688                                                  ssize_int (r - p1))));
8689         }
8690
8691       if (p2[0] == '\0')
8692         return s1;
8693
8694       if (p2[1] != '\0')
8695         return 0;
8696
8697       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8698       if (!fn)
8699         return 0;
8700
8701       /* New argument list transforming strstr(s1, s2) to
8702          strchr(s1, s2[0]).  */
8703       arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8704       arglist = tree_cons (NULL_TREE, s1, arglist);
8705       return build_function_call_expr (fn, arglist);
8706     }
8707 }
8708
8709 /* Simplify a call to the strstr builtin.
8710
8711    Return 0 if no simplification was possible, otherwise return the
8712    simplified form of the call as a tree.
8713
8714    The simplified form may be a constant or other expression which
8715    computes the same value, but in a more efficient manner (including
8716    calls to other builtin functions).
8717
8718    The call may contain arguments which need to be evaluated, but
8719    which are not useful to determine the result of the call.  In
8720    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8721    COMPOUND_EXPR will be an argument which must be evaluated.
8722    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8723    COMPOUND_EXPR in the chain will contain the tree for the simplified
8724    form of the builtin function call.  */
8725
8726 static tree
8727 simplify_builtin_strchr (tree arglist)
8728 {
8729   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8730     return 0;
8731   else
8732     {
8733       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8734       const char *p1;
8735
8736       if (TREE_CODE (s2) != INTEGER_CST)
8737         return 0;
8738
8739       p1 = c_getstr (s1);
8740       if (p1 != NULL)
8741         {
8742           char c;
8743           const char *r;
8744
8745           if (target_char_cast (s2, &c))
8746             return 0;
8747
8748           r = strchr (p1, c);
8749
8750           if (r == NULL)
8751             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8752
8753           /* Return an offset into the constant string argument.  */
8754           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8755                                s1, fold_convert (TREE_TYPE (s1),
8756                                                  ssize_int (r - p1))));
8757         }
8758
8759       /* FIXME: Should use here strchrM optab so that ports can optimize
8760          this.  */
8761       return 0;
8762     }
8763 }
8764
8765 /* Simplify a call to the strrchr builtin.
8766
8767    Return 0 if no simplification was possible, otherwise return the
8768    simplified form of the call as a tree.
8769
8770    The simplified form may be a constant or other expression which
8771    computes the same value, but in a more efficient manner (including
8772    calls to other builtin functions).
8773
8774    The call may contain arguments which need to be evaluated, but
8775    which are not useful to determine the result of the call.  In
8776    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8777    COMPOUND_EXPR will be an argument which must be evaluated.
8778    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8779    COMPOUND_EXPR in the chain will contain the tree for the simplified
8780    form of the builtin function call.  */
8781
8782 static tree
8783 simplify_builtin_strrchr (tree arglist)
8784 {
8785   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8786     return 0;
8787   else
8788     {
8789       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8790       tree fn;
8791       const char *p1;
8792
8793       if (TREE_CODE (s2) != INTEGER_CST)
8794         return 0;
8795
8796       p1 = c_getstr (s1);
8797       if (p1 != NULL)
8798         {
8799           char c;
8800           const char *r;
8801
8802           if (target_char_cast (s2, &c))
8803             return 0;
8804
8805           r = strrchr (p1, c);
8806
8807           if (r == NULL)
8808             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8809
8810           /* Return an offset into the constant string argument.  */
8811           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8812                                s1, fold_convert (TREE_TYPE (s1),
8813                                                  ssize_int (r - p1))));
8814         }
8815
8816       if (! integer_zerop (s2))
8817         return 0;
8818
8819       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8820       if (!fn)
8821         return 0;
8822
8823       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8824       return build_function_call_expr (fn, arglist);
8825     }
8826 }
8827
8828 /* Simplify a call to the strpbrk builtin.
8829
8830    Return 0 if no simplification was possible, otherwise return the
8831    simplified form of the call as a tree.
8832
8833    The simplified form may be a constant or other expression which
8834    computes the same value, but in a more efficient manner (including
8835    calls to other builtin functions).
8836
8837    The call may contain arguments which need to be evaluated, but
8838    which are not useful to determine the result of the call.  In
8839    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8840    COMPOUND_EXPR will be an argument which must be evaluated.
8841    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8842    COMPOUND_EXPR in the chain will contain the tree for the simplified
8843    form of the builtin function call.  */
8844
8845 static tree
8846 simplify_builtin_strpbrk (tree arglist)
8847 {
8848   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8849     return 0;
8850   else
8851     {
8852       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8853       tree fn;
8854       const char *p1, *p2;
8855
8856       p2 = c_getstr (s2);
8857       if (p2 == NULL)
8858         return 0;
8859
8860       p1 = c_getstr (s1);
8861       if (p1 != NULL)
8862         {
8863           const char *r = strpbrk (p1, p2);
8864
8865           if (r == NULL)
8866             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8867
8868           /* Return an offset into the constant string argument.  */
8869           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8870                                s1, fold_convert (TREE_TYPE (s1),
8871                                                  ssize_int (r - p1))));
8872         }
8873
8874       if (p2[0] == '\0')
8875         /* strpbrk(x, "") == NULL.
8876            Evaluate and ignore s1 in case it had side-effects.  */
8877         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8878
8879       if (p2[1] != '\0')
8880         return 0;  /* Really call strpbrk.  */
8881
8882       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8883       if (!fn)
8884         return 0;
8885
8886       /* New argument list transforming strpbrk(s1, s2) to
8887          strchr(s1, s2[0]).  */
8888       arglist =
8889         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8890       arglist = tree_cons (NULL_TREE, s1, arglist);
8891       return build_function_call_expr (fn, arglist);
8892     }
8893 }
8894
8895 /* Simplify a call to the strcat builtin.
8896
8897    Return 0 if no simplification was possible, otherwise return the
8898    simplified form of the call as a tree.
8899
8900    The simplified form may be a constant or other expression which
8901    computes the same value, but in a more efficient manner (including
8902    calls to other builtin functions).
8903
8904    The call may contain arguments which need to be evaluated, but
8905    which are not useful to determine the result of the call.  In
8906    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8907    COMPOUND_EXPR will be an argument which must be evaluated.
8908    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8909    COMPOUND_EXPR in the chain will contain the tree for the simplified
8910    form of the builtin function call.  */
8911
8912 static tree
8913 simplify_builtin_strcat (tree arglist)
8914 {
8915   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8916     return 0;
8917   else
8918     {
8919       tree dst = TREE_VALUE (arglist),
8920         src = TREE_VALUE (TREE_CHAIN (arglist));
8921       const char *p = c_getstr (src);
8922
8923       /* If the string length is zero, return the dst parameter.  */
8924       if (p && *p == '\0')
8925         return dst;
8926
8927       return 0;
8928     }
8929 }
8930
8931 /* Simplify a call to the strncat builtin.
8932
8933    Return 0 if no simplification was possible, otherwise return the
8934    simplified form of the call as a tree.
8935
8936    The simplified form may be a constant or other expression which
8937    computes the same value, but in a more efficient manner (including
8938    calls to other builtin functions).
8939
8940    The call may contain arguments which need to be evaluated, but
8941    which are not useful to determine the result of the call.  In
8942    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8943    COMPOUND_EXPR will be an argument which must be evaluated.
8944    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8945    COMPOUND_EXPR in the chain will contain the tree for the simplified
8946    form of the builtin function call.  */
8947
8948 static tree
8949 simplify_builtin_strncat (tree arglist)
8950 {
8951   if (!validate_arglist (arglist,
8952                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8953     return 0;
8954   else
8955     {
8956       tree dst = TREE_VALUE (arglist);
8957       tree src = TREE_VALUE (TREE_CHAIN (arglist));
8958       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8959       const char *p = c_getstr (src);
8960
8961       /* If the requested length is zero, or the src parameter string
8962           length is zero, return the dst parameter.  */
8963       if (integer_zerop (len) || (p && *p == '\0'))
8964         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8965
8966       /* If the requested len is greater than or equal to the string
8967          length, call strcat.  */
8968       if (TREE_CODE (len) == INTEGER_CST && p
8969           && compare_tree_int (len, strlen (p)) >= 0)
8970         {
8971           tree newarglist
8972             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8973           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8974
8975           /* If the replacement _DECL isn't initialized, don't do the
8976              transformation.  */
8977           if (!fn)
8978             return 0;
8979
8980           return build_function_call_expr (fn, newarglist);
8981         }
8982       return 0;
8983     }
8984 }
8985
8986 /* Simplify a call to the strspn builtin.
8987
8988    Return 0 if no simplification was possible, otherwise return the
8989    simplified form of the call as a tree.
8990
8991    The simplified form may be a constant or other expression which
8992    computes the same value, but in a more efficient manner (including
8993    calls to other builtin functions).
8994
8995    The call may contain arguments which need to be evaluated, but
8996    which are not useful to determine the result of the call.  In
8997    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8998    COMPOUND_EXPR will be an argument which must be evaluated.
8999    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9000    COMPOUND_EXPR in the chain will contain the tree for the simplified
9001    form of the builtin function call.  */
9002
9003 static tree
9004 simplify_builtin_strspn (tree arglist)
9005 {
9006   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9007     return 0;
9008   else
9009     {
9010       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9011       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9012
9013       /* If both arguments are constants, evaluate at compile-time.  */
9014       if (p1 && p2)
9015         {
9016           const size_t r = strspn (p1, p2);
9017           return size_int (r);
9018         }
9019
9020       /* If either argument is "", return 0.  */
9021       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9022         /* Evaluate and ignore both arguments in case either one has
9023            side-effects.  */
9024         return omit_two_operands (integer_type_node, integer_zero_node,
9025                                   s1, s2);
9026       return 0;
9027     }
9028 }
9029
9030 /* Simplify a call to the strcspn builtin.
9031
9032    Return 0 if no simplification was possible, otherwise return the
9033    simplified form of the call as a tree.
9034
9035    The simplified form may be a constant or other expression which
9036    computes the same value, but in a more efficient manner (including
9037    calls to other builtin functions).
9038
9039    The call may contain arguments which need to be evaluated, but
9040    which are not useful to determine the result of the call.  In
9041    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9042    COMPOUND_EXPR will be an argument which must be evaluated.
9043    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9044    COMPOUND_EXPR in the chain will contain the tree for the simplified
9045    form of the builtin function call.  */
9046
9047 static tree
9048 simplify_builtin_strcspn (tree arglist)
9049 {
9050   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9051     return 0;
9052   else
9053     {
9054       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9055       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9056
9057       /* If both arguments are constants, evaluate at compile-time.  */
9058       if (p1 && p2)
9059         {
9060           const size_t r = strcspn (p1, p2);
9061           return size_int (r);
9062         }
9063
9064       /* If the first argument is "", return 0.  */
9065       if (p1 && *p1 == '\0')
9066         {
9067           /* Evaluate and ignore argument s2 in case it has
9068              side-effects.  */
9069           return omit_one_operand (integer_type_node,
9070                                    integer_zero_node, s2);
9071         }
9072
9073       /* If the second argument is "", return __builtin_strlen(s1).  */
9074       if (p2 && *p2 == '\0')
9075         {
9076           tree newarglist = build_tree_list (NULL_TREE, s1),
9077             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9078
9079           /* If the replacement _DECL isn't initialized, don't do the
9080              transformation.  */
9081           if (!fn)
9082             return 0;
9083
9084           return build_function_call_expr (fn, newarglist);
9085         }
9086       return 0;
9087     }
9088 }
9089
9090 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
9091    by the builtin will be ignored.  UNLOCKED is true is true if this
9092    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
9093    the known length of the string.  Return NULL_TREE if no simplification
9094    was possible.  */
9095
9096 tree
9097 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
9098 {
9099   tree fn;
9100   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9101     : implicit_built_in_decls[BUILT_IN_FPUTC];
9102   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9103     : implicit_built_in_decls[BUILT_IN_FWRITE];
9104
9105   /* If the return value is used, or the replacement _DECL isn't
9106      initialized, don't do the transformation.  */
9107   if (!ignore || !fn_fputc || !fn_fwrite)
9108     return 0;
9109
9110   /* Verify the arguments in the original call.  */
9111   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9112     return 0;
9113
9114   if (! len)
9115     len = c_strlen (TREE_VALUE (arglist), 0);
9116
9117   /* Get the length of the string passed to fputs.  If the length
9118      can't be determined, punt.  */
9119   if (!len
9120       || TREE_CODE (len) != INTEGER_CST)
9121     return 0;
9122
9123   switch (compare_tree_int (len, 1))
9124     {
9125     case -1: /* length is 0, delete the call entirely .  */
9126       return omit_one_operand (integer_type_node, integer_zero_node,
9127                                TREE_VALUE (TREE_CHAIN (arglist)));
9128
9129     case 0: /* length is 1, call fputc.  */
9130       {
9131         const char *p = c_getstr (TREE_VALUE (arglist));
9132
9133         if (p != NULL)
9134           {
9135             /* New argument list transforming fputs(string, stream) to
9136                fputc(string[0], stream).  */
9137             arglist =
9138               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9139             arglist = tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9140             fn = fn_fputc;
9141             break;
9142           }
9143       }
9144       /* FALLTHROUGH */
9145     case 1: /* length is greater than 1, call fwrite.  */
9146       {
9147         tree string_arg;
9148
9149         /* If optimizing for size keep fputs.  */
9150         if (optimize_size)
9151           return 0;
9152         string_arg = TREE_VALUE (arglist);
9153         /* New argument list transforming fputs(string, stream) to
9154            fwrite(string, 1, len, stream).  */
9155         arglist = build_tree_list (NULL_TREE,
9156                                    TREE_VALUE (TREE_CHAIN (arglist)));
9157         arglist = tree_cons (NULL_TREE, len, arglist);
9158         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9159         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9160         fn = fn_fwrite;
9161         break;
9162       }
9163     default:
9164       abort ();
9165     }
9166
9167   /* These optimizations are only performed when the result is ignored,
9168      hence there's no need to cast the result to integer_type_node.  */
9169   return build_function_call_expr (fn, arglist);
9170 }
9171
9172 static void
9173 simplify_builtin_va_start (tree arglist)
9174 {
9175   tree chain = TREE_CHAIN (arglist);
9176
9177   if (TREE_CHAIN (chain))
9178     error ("too many arguments to function `va_start'");
9179
9180   simplify_builtin_next_arg (chain);
9181 }
9182
9183 static void
9184 simplify_builtin_next_arg (tree arglist)
9185 {
9186   tree fntype = TREE_TYPE (current_function_decl);
9187
9188   if (TYPE_ARG_TYPES (fntype) == 0
9189       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9190           == void_type_node))
9191     error ("`va_start' used in function with fixed args");
9192   else if (arglist)
9193     {
9194       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9195       tree arg = TREE_VALUE (arglist);
9196
9197       /* Strip off all nops for the sake of the comparison.  This
9198          is not quite the same as STRIP_NOPS.  It does more.
9199          We must also strip off INDIRECT_EXPR for C++ reference
9200          parameters.  */
9201       while (TREE_CODE (arg) == NOP_EXPR
9202              || TREE_CODE (arg) == CONVERT_EXPR
9203              || TREE_CODE (arg) == NON_LVALUE_EXPR
9204              || TREE_CODE (arg) == INDIRECT_REF)
9205         arg = TREE_OPERAND (arg, 0);
9206       if (arg != last_parm)
9207         warning ("second parameter of `va_start' not last named argument");
9208       TREE_VALUE (arglist) = arg;
9209     }
9210   else
9211     /* Evidently an out of date version of <stdarg.h>; can't validate
9212        va_start's second argument, but can still work as intended.  */
9213     warning ("`__builtin_next_arg' called without an argument");
9214 }
9215
9216
9217 /* Simplify a call to the sprintf builtin.
9218
9219    Return 0 if no simplification was possible, otherwise return the
9220    simplified form of the call as a tree.  If IGNORED is true, it means that
9221    the caller does not use the returned value of the function.  */
9222
9223 static tree
9224 simplify_builtin_sprintf (tree arglist, int ignored)
9225 {
9226   tree call, retval, dest, fmt;
9227   const char *fmt_str = NULL;
9228
9229   /* Verify the required arguments in the original call.  We deal with two
9230      types of sprintf() calls: 'sprintf (str, fmt)' and
9231      'sprintf (dest, "%s", orig)'.  */
9232   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9233       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9234                             VOID_TYPE))
9235     return NULL_TREE;
9236
9237   /* Get the destination string and the format specifier.  */
9238   dest = TREE_VALUE (arglist);
9239   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9240
9241   /* Check whether the format is a literal string constant.  */
9242   fmt_str = c_getstr (fmt);
9243   if (fmt_str == NULL)
9244     return NULL_TREE;
9245
9246   call = NULL_TREE;
9247   retval = NULL_TREE;
9248
9249   /* If the format doesn't contain % args or %%, use strcpy.  */
9250   if (strchr (fmt_str, '%') == NULL)
9251     {
9252       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9253
9254       if (!fn)
9255         return NULL_TREE;
9256
9257       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9258          'format' is known to contain no % formats.  */
9259       arglist = build_tree_list (NULL_TREE, fmt);
9260       arglist = tree_cons (NULL_TREE, dest, arglist);
9261       call = build_function_call_expr (fn, arglist);
9262       if (!ignored)
9263         retval = build_int_2 (strlen (fmt_str), 0);
9264     }
9265
9266   /* If the format is "%s", use strcpy if the result isn't used.  */
9267   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9268     {
9269       tree fn, orig;
9270       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9271
9272       if (!fn)
9273         return NULL_TREE;
9274
9275       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9276       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9277       arglist = build_tree_list (NULL_TREE, orig);
9278       arglist = tree_cons (NULL_TREE, dest, arglist);
9279       if (!ignored)
9280         {
9281           retval = c_strlen (orig, 1);
9282           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9283             return NULL_TREE;
9284         }
9285       call = build_function_call_expr (fn, arglist);
9286     }
9287
9288   if (call && retval)
9289     {
9290       retval = convert
9291         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9292          retval);
9293       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9294     }
9295   else
9296     return call;
9297 }