OSDN Git Service

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