OSDN Git Service

2004-07-20 Frank Ch. Eigler <fche@redhat.com>
[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.  The code below is from expand_end_bindings
575      in stmt.c; see detailed documentation there.  */
576 #ifdef HAVE_nonlocal_goto
577   if (! HAVE_nonlocal_goto)
578 #endif
579     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
580
581 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
582   if (fixed_regs[ARG_POINTER_REGNUM])
583     {
584 #ifdef ELIMINABLE_REGS
585       size_t i;
586       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
587
588       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
589         if (elim_regs[i].from == ARG_POINTER_REGNUM
590             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
591           break;
592
593       if (i == ARRAY_SIZE (elim_regs))
594 #endif
595         {
596           /* Now restore our arg pointer from the address at which it
597              was saved in our stack frame.  */
598           emit_move_insn (virtual_incoming_args_rtx,
599                           copy_to_reg (get_arg_pointer_save_area (cfun)));
600         }
601     }
602 #endif
603
604 #ifdef HAVE_builtin_setjmp_receiver
605   if (HAVE_builtin_setjmp_receiver)
606     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
607   else
608 #endif
609 #ifdef HAVE_nonlocal_goto_receiver
610     if (HAVE_nonlocal_goto_receiver)
611       emit_insn (gen_nonlocal_goto_receiver ());
612     else
613 #endif
614       { /* Nothing */ }
615
616   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
617      insn, but we must not allow the code we just generated to be reordered
618      by scheduling.  Specifically, the update of the frame pointer must
619      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
620      insn.  */
621   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
622 }
623
624 /* __builtin_setjmp is passed a pointer to an array of five words (not
625    all will be used on all machines).  It operates similarly to the C
626    library function of the same name, but is more efficient.  Much of
627    the code below (and for longjmp) is copied from the handling of
628    non-local gotos.
629
630    NOTE: This is intended for use by GNAT and the exception handling
631    scheme in the compiler and will only work in the method used by
632    them.  */
633
634 static rtx
635 expand_builtin_setjmp (tree arglist, rtx target)
636 {
637   rtx buf_addr, next_lab, cont_lab;
638
639   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
640     return NULL_RTX;
641
642   if (target == 0 || !REG_P (target)
643       || REGNO (target) < FIRST_PSEUDO_REGISTER)
644     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
645
646   buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
647
648   next_lab = gen_label_rtx ();
649   cont_lab = gen_label_rtx ();
650
651   expand_builtin_setjmp_setup (buf_addr, next_lab);
652
653   /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
654      ensure that pending stack adjustments are flushed.  */
655   emit_move_insn (target, const0_rtx);
656   emit_jump (cont_lab);
657
658   emit_label (next_lab);
659
660   expand_builtin_setjmp_receiver (next_lab);
661
662   /* Set TARGET to one.  */
663   emit_move_insn (target, const1_rtx);
664   emit_label (cont_lab);
665
666   /* Tell flow about the strange goings on.  Putting `next_lab' on
667      `nonlocal_goto_handler_labels' to indicates that function
668      calls may traverse the arc back to this label.  */
669
670   current_function_has_nonlocal_label = 1;
671   nonlocal_goto_handler_labels
672     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
673
674   return target;
675 }
676
677 /* __builtin_longjmp is passed a pointer to an array of five words (not
678    all will be used on all machines).  It operates similarly to the C
679    library function of the same name, but is more efficient.  Much of
680    the code below is copied from the handling of non-local gotos.
681
682    NOTE: This is intended for use by GNAT and the exception handling
683    scheme in the compiler and will only work in the method used by
684    them.  */
685
686 void
687 expand_builtin_longjmp (rtx buf_addr, rtx value)
688 {
689   rtx fp, lab, stack, insn, last;
690   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
691
692   if (setjmp_alias_set == -1)
693     setjmp_alias_set = new_alias_set ();
694
695   buf_addr = convert_memory_address (Pmode, buf_addr);
696
697   buf_addr = force_reg (Pmode, buf_addr);
698
699   /* We used to store value in static_chain_rtx, but that fails if pointers
700      are smaller than integers.  We instead require that the user must pass
701      a second argument of 1, because that is what builtin_setjmp will
702      return.  This also makes EH slightly more efficient, since we are no
703      longer copying around a value that we don't care about.  */
704   if (value != const1_rtx)
705     abort ();
706
707   current_function_calls_longjmp = 1;
708
709   last = get_last_insn ();
710 #ifdef HAVE_builtin_longjmp
711   if (HAVE_builtin_longjmp)
712     emit_insn (gen_builtin_longjmp (buf_addr));
713   else
714 #endif
715     {
716       fp = gen_rtx_MEM (Pmode, buf_addr);
717       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
718                                                GET_MODE_SIZE (Pmode)));
719
720       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
721                                                    2 * GET_MODE_SIZE (Pmode)));
722       set_mem_alias_set (fp, setjmp_alias_set);
723       set_mem_alias_set (lab, setjmp_alias_set);
724       set_mem_alias_set (stack, setjmp_alias_set);
725
726       /* Pick up FP, label, and SP from the block and jump.  This code is
727          from expand_goto in stmt.c; see there for detailed comments.  */
728 #if HAVE_nonlocal_goto
729       if (HAVE_nonlocal_goto)
730         /* We have to pass a value to the nonlocal_goto pattern that will
731            get copied into the static_chain pointer, but it does not matter
732            what that value is, because builtin_setjmp does not use it.  */
733         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
734       else
735 #endif
736         {
737           lab = copy_to_reg (lab);
738
739           emit_insn (gen_rtx_CLOBBER (VOIDmode,
740                                       gen_rtx_MEM (BLKmode,
741                                                    gen_rtx_SCRATCH (VOIDmode))));
742           emit_insn (gen_rtx_CLOBBER (VOIDmode,
743                                       gen_rtx_MEM (BLKmode,
744                                                    hard_frame_pointer_rtx)));
745
746           emit_move_insn (hard_frame_pointer_rtx, fp);
747           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
748
749           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
750           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
751           emit_indirect_jump (lab);
752         }
753     }
754
755   /* Search backwards and mark the jump insn as a non-local goto.
756      Note that this precludes the use of __builtin_longjmp to a
757      __builtin_setjmp target in the same function.  However, we've
758      already cautioned the user that these functions are for
759      internal exception handling use only.  */
760   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
761     {
762       if (insn == last)
763         abort ();
764       if (JUMP_P (insn))
765         {
766           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
767                                               REG_NOTES (insn));
768           break;
769         }
770       else if (CALL_P (insn))
771         break;
772     }
773 }
774
775 /* Expand a call to __builtin_nonlocal_goto.  We're passed the target label
776    and the address of the save area.  */
777
778 static rtx
779 expand_builtin_nonlocal_goto (tree arglist)
780 {
781   tree t_label, t_save_area;
782   rtx r_label, r_save_area, r_fp, r_sp, insn;
783
784   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
785     return NULL_RTX;
786
787   t_label = TREE_VALUE (arglist);
788   arglist = TREE_CHAIN (arglist);
789   t_save_area = TREE_VALUE (arglist);
790
791   r_label = expand_expr (t_label, NULL_RTX, VOIDmode, 0);
792   r_label = convert_memory_address (Pmode, r_label);
793   r_save_area = expand_expr (t_save_area, NULL_RTX, VOIDmode, 0);
794   r_save_area = convert_memory_address (Pmode, r_save_area);
795   r_fp = gen_rtx_MEM (Pmode, r_save_area);
796   r_sp = gen_rtx_MEM (STACK_SAVEAREA_MODE (SAVE_NONLOCAL),
797                       plus_constant (r_save_area, GET_MODE_SIZE (Pmode)));
798
799   current_function_has_nonlocal_goto = 1;
800
801 #if HAVE_nonlocal_goto
802   /* ??? We no longer need to pass the static chain value, afaik.  */
803   if (HAVE_nonlocal_goto)
804     emit_insn (gen_nonlocal_goto (const0_rtx, r_label, r_sp, r_fp));
805   else
806 #endif
807     {
808       r_label = copy_to_reg (r_label);
809
810       emit_insn (gen_rtx_CLOBBER (VOIDmode,
811                                   gen_rtx_MEM (BLKmode,
812                                                gen_rtx_SCRATCH (VOIDmode))));
813
814       emit_insn (gen_rtx_CLOBBER (VOIDmode,
815                                   gen_rtx_MEM (BLKmode,
816                                                hard_frame_pointer_rtx)));
817  
818       /* Restore frame pointer for containing function.
819          This sets the actual hard register used for the frame pointer
820          to the location of the function's incoming static chain info.
821          The non-local goto handler will then adjust it to contain the
822          proper value and reload the argument pointer, if needed.  */
823       emit_move_insn (hard_frame_pointer_rtx, r_fp);
824       emit_stack_restore (SAVE_NONLOCAL, r_sp, NULL_RTX);
825  
826       /* USE of hard_frame_pointer_rtx added for consistency;
827          not clear if really needed.  */
828       emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
829       emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
830       emit_indirect_jump (r_label);
831     }
832  
833   /* Search backwards to the jump insn and mark it as a
834      non-local goto.  */
835   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
836     {
837       if (JUMP_P (insn))
838         {
839           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO,
840                                               const0_rtx, REG_NOTES (insn));
841           break;
842         }
843       else if (CALL_P (insn))
844         break;
845     }
846
847   return const0_rtx;
848 }
849
850 /* __builtin_update_setjmp_buf is passed a pointer to an array of five words
851    (not all will be used on all machines) that was passed to __builtin_setjmp.
852    It updates the stack pointer in that block to correspond to the current
853    stack pointer.  */
854
855 static void
856 expand_builtin_update_setjmp_buf (rtx buf_addr)
857 {
858   enum machine_mode sa_mode = Pmode;
859   rtx stack_save;
860
861
862 #ifdef HAVE_save_stack_nonlocal
863   if (HAVE_save_stack_nonlocal)
864     sa_mode = insn_data[(int) CODE_FOR_save_stack_nonlocal].operand[0].mode;
865 #endif
866 #ifdef STACK_SAVEAREA_MODE
867   sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
868 #endif
869
870   stack_save
871     = gen_rtx_MEM (sa_mode,
872                    memory_address
873                    (sa_mode,
874                     plus_constant (buf_addr, 2 * GET_MODE_SIZE (Pmode))));
875
876 #ifdef HAVE_setjmp
877   if (HAVE_setjmp)
878     emit_insn (gen_setjmp ());
879 #endif
880
881   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
882 }
883
884 /* Expand a call to __builtin_prefetch.  For a target that does not support
885    data prefetch, evaluate the memory address argument in case it has side
886    effects.  */
887
888 static void
889 expand_builtin_prefetch (tree arglist)
890 {
891   tree arg0, arg1, arg2;
892   rtx op0, op1, op2;
893
894   if (!validate_arglist (arglist, POINTER_TYPE, 0))
895     return;
896
897   arg0 = TREE_VALUE (arglist);
898   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
899      zero (read) and argument 2 (locality) defaults to 3 (high degree of
900      locality).  */
901   if (TREE_CHAIN (arglist))
902     {
903       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
904       if (TREE_CHAIN (TREE_CHAIN (arglist)))
905         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
906       else
907         arg2 = build_int_2 (3, 0);
908     }
909   else
910     {
911       arg1 = integer_zero_node;
912       arg2 = build_int_2 (3, 0);
913     }
914
915   /* Argument 0 is an address.  */
916   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
917
918   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
919   if (TREE_CODE (arg1) != INTEGER_CST)
920     {
921       error ("second arg to `__builtin_prefetch' must be a constant");
922       arg1 = integer_zero_node;
923     }
924   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
925   /* Argument 1 must be either zero or one.  */
926   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
927     {
928       warning ("invalid second arg to __builtin_prefetch; using zero");
929       op1 = const0_rtx;
930     }
931
932   /* Argument 2 (locality) must be a compile-time constant int.  */
933   if (TREE_CODE (arg2) != INTEGER_CST)
934     {
935       error ("third arg to `__builtin_prefetch' must be a constant");
936       arg2 = integer_zero_node;
937     }
938   op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
939   /* Argument 2 must be 0, 1, 2, or 3.  */
940   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
941     {
942       warning ("invalid third arg to __builtin_prefetch; using zero");
943       op2 = const0_rtx;
944     }
945
946 #ifdef HAVE_prefetch
947   if (HAVE_prefetch)
948     {
949       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
950              (op0,
951               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
952           || (GET_MODE (op0) != Pmode))
953         {
954           op0 = convert_memory_address (Pmode, op0);
955           op0 = force_reg (Pmode, op0);
956         }
957       emit_insn (gen_prefetch (op0, op1, op2));
958     }
959 #endif
960
961   /* Don't do anything with direct references to volatile memory, but
962      generate code to handle other side effects.  */
963   if (!MEM_P (op0) && side_effects_p (op0))
964     emit_insn (op0);
965 }
966
967 /* Get a MEM rtx for expression EXP which is the address of an operand
968    to be used to be used in a string instruction (cmpstrsi, movmemsi, ..).  */
969
970 static rtx
971 get_memory_rtx (tree exp)
972 {
973   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
974   rtx mem;
975
976   addr = convert_memory_address (Pmode, addr);
977
978   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
979
980   /* Get an expression we can use to find the attributes to assign to MEM.
981      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
982      we can.  First remove any nops.  */
983   while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
984           || TREE_CODE (exp) == NON_LVALUE_EXPR)
985          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
986     exp = TREE_OPERAND (exp, 0);
987
988   if (TREE_CODE (exp) == ADDR_EXPR)
989     {
990       exp = TREE_OPERAND (exp, 0);
991       set_mem_attributes (mem, exp, 0);
992     }
993   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
994     {
995       exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
996       /* memcpy, memset and other builtin stringops can alias with anything.  */
997       set_mem_alias_set (mem, 0);
998     }
999
1000   return mem;
1001 }
1002 \f
1003 /* Built-in functions to perform an untyped call and return.  */
1004
1005 /* For each register that may be used for calling a function, this
1006    gives a mode used to copy the register's value.  VOIDmode indicates
1007    the register is not used for calling a function.  If the machine
1008    has register windows, this gives only the outbound registers.
1009    INCOMING_REGNO gives the corresponding inbound register.  */
1010 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
1011
1012 /* For each register that may be used for returning values, this gives
1013    a mode used to copy the register's value.  VOIDmode indicates the
1014    register is not used for returning values.  If the machine has
1015    register windows, this gives only the outbound registers.
1016    INCOMING_REGNO gives the corresponding inbound register.  */
1017 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
1018
1019 /* For each register that may be used for calling a function, this
1020    gives the offset of that register into the block returned by
1021    __builtin_apply_args.  0 indicates that the register is not
1022    used for calling a function.  */
1023 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
1024
1025 /* Return the size required for the block returned by __builtin_apply_args,
1026    and initialize apply_args_mode.  */
1027
1028 static int
1029 apply_args_size (void)
1030 {
1031   static int size = -1;
1032   int align;
1033   unsigned int regno;
1034   enum machine_mode mode;
1035
1036   /* The values computed by this function never change.  */
1037   if (size < 0)
1038     {
1039       /* The first value is the incoming arg-pointer.  */
1040       size = GET_MODE_SIZE (Pmode);
1041
1042       /* The second value is the structure value address unless this is
1043          passed as an "invisible" first argument.  */
1044       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1045         size += GET_MODE_SIZE (Pmode);
1046
1047       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1048         if (FUNCTION_ARG_REGNO_P (regno))
1049           {
1050             mode = reg_raw_mode[regno];
1051
1052             if (mode == VOIDmode)
1053               abort ();
1054
1055             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1056             if (size % align != 0)
1057               size = CEIL (size, align) * align;
1058             apply_args_reg_offset[regno] = size;
1059             size += GET_MODE_SIZE (mode);
1060             apply_args_mode[regno] = mode;
1061           }
1062         else
1063           {
1064             apply_args_mode[regno] = VOIDmode;
1065             apply_args_reg_offset[regno] = 0;
1066           }
1067     }
1068   return size;
1069 }
1070
1071 /* Return the size required for the block returned by __builtin_apply,
1072    and initialize apply_result_mode.  */
1073
1074 static int
1075 apply_result_size (void)
1076 {
1077   static int size = -1;
1078   int align, regno;
1079   enum machine_mode mode;
1080
1081   /* The values computed by this function never change.  */
1082   if (size < 0)
1083     {
1084       size = 0;
1085
1086       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1087         if (FUNCTION_VALUE_REGNO_P (regno))
1088           {
1089             mode = reg_raw_mode[regno];
1090
1091             if (mode == VOIDmode)
1092               abort ();
1093
1094             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1095             if (size % align != 0)
1096               size = CEIL (size, align) * align;
1097             size += GET_MODE_SIZE (mode);
1098             apply_result_mode[regno] = mode;
1099           }
1100         else
1101           apply_result_mode[regno] = VOIDmode;
1102
1103       /* Allow targets that use untyped_call and untyped_return to override
1104          the size so that machine-specific information can be stored here.  */
1105 #ifdef APPLY_RESULT_SIZE
1106       size = APPLY_RESULT_SIZE;
1107 #endif
1108     }
1109   return size;
1110 }
1111
1112 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1113 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1114    the result block is used to save the values; otherwise it is used to
1115    restore the values.  */
1116
1117 static rtx
1118 result_vector (int savep, rtx result)
1119 {
1120   int regno, size, align, nelts;
1121   enum machine_mode mode;
1122   rtx reg, mem;
1123   rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1124
1125   size = nelts = 0;
1126   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1127     if ((mode = apply_result_mode[regno]) != VOIDmode)
1128       {
1129         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1130         if (size % align != 0)
1131           size = CEIL (size, align) * align;
1132         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1133         mem = adjust_address (result, mode, size);
1134         savevec[nelts++] = (savep
1135                             ? gen_rtx_SET (VOIDmode, mem, reg)
1136                             : gen_rtx_SET (VOIDmode, reg, mem));
1137         size += GET_MODE_SIZE (mode);
1138       }
1139   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1140 }
1141 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1142
1143 /* Save the state required to perform an untyped call with the same
1144    arguments as were passed to the current function.  */
1145
1146 static rtx
1147 expand_builtin_apply_args_1 (void)
1148 {
1149   rtx registers, tem;
1150   int size, align, regno;
1151   enum machine_mode mode;
1152   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1153
1154   /* Create a block where the arg-pointer, structure value address,
1155      and argument registers can be saved.  */
1156   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1157
1158   /* Walk past the arg-pointer and structure value address.  */
1159   size = GET_MODE_SIZE (Pmode);
1160   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1161     size += GET_MODE_SIZE (Pmode);
1162
1163   /* Save each register used in calling a function to the block.  */
1164   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1165     if ((mode = apply_args_mode[regno]) != VOIDmode)
1166       {
1167         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1168         if (size % align != 0)
1169           size = CEIL (size, align) * align;
1170
1171         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1172
1173         emit_move_insn (adjust_address (registers, mode, size), tem);
1174         size += GET_MODE_SIZE (mode);
1175       }
1176
1177   /* Save the arg pointer to the block.  */
1178   tem = copy_to_reg (virtual_incoming_args_rtx);
1179 #ifdef STACK_GROWS_DOWNWARD
1180   /* We need the pointer as the caller actually passed them to us, not
1181      as we might have pretended they were passed.  Make sure it's a valid
1182      operand, as emit_move_insn isn't expected to handle a PLUS.  */
1183   tem
1184     = force_operand (plus_constant (tem, current_function_pretend_args_size),
1185                      NULL_RTX);
1186 #endif
1187   emit_move_insn (adjust_address (registers, Pmode, 0), tem);
1188
1189   size = GET_MODE_SIZE (Pmode);
1190
1191   /* Save the structure value address unless this is passed as an
1192      "invisible" first argument.  */
1193   if (struct_incoming_value)
1194     {
1195       emit_move_insn (adjust_address (registers, Pmode, size),
1196                       copy_to_reg (struct_incoming_value));
1197       size += GET_MODE_SIZE (Pmode);
1198     }
1199
1200   /* Return the address of the block.  */
1201   return copy_addr_to_reg (XEXP (registers, 0));
1202 }
1203
1204 /* __builtin_apply_args returns block of memory allocated on
1205    the stack into which is stored the arg pointer, structure
1206    value address, static chain, and all the registers that might
1207    possibly be used in performing a function call.  The code is
1208    moved to the start of the function so the incoming values are
1209    saved.  */
1210
1211 static rtx
1212 expand_builtin_apply_args (void)
1213 {
1214   /* Don't do __builtin_apply_args more than once in a function.
1215      Save the result of the first call and reuse it.  */
1216   if (apply_args_value != 0)
1217     return apply_args_value;
1218   {
1219     /* When this function is called, it means that registers must be
1220        saved on entry to this function.  So we migrate the
1221        call to the first insn of this function.  */
1222     rtx temp;
1223     rtx seq;
1224
1225     start_sequence ();
1226     temp = expand_builtin_apply_args_1 ();
1227     seq = get_insns ();
1228     end_sequence ();
1229
1230     apply_args_value = temp;
1231
1232     /* Put the insns after the NOTE that starts the function.
1233        If this is inside a start_sequence, make the outer-level insn
1234        chain current, so the code is placed at the start of the
1235        function.  */
1236     push_topmost_sequence ();
1237     emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
1238     pop_topmost_sequence ();
1239     return temp;
1240   }
1241 }
1242
1243 /* Perform an untyped call and save the state required to perform an
1244    untyped return of whatever value was returned by the given function.  */
1245
1246 static rtx
1247 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1248 {
1249   int size, align, regno;
1250   enum machine_mode mode;
1251   rtx incoming_args, result, reg, dest, src, call_insn;
1252   rtx old_stack_level = 0;
1253   rtx call_fusage = 0;
1254   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1255
1256   arguments = convert_memory_address (Pmode, arguments);
1257
1258   /* Create a block where the return registers can be saved.  */
1259   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1260
1261   /* Fetch the arg pointer from the ARGUMENTS block.  */
1262   incoming_args = gen_reg_rtx (Pmode);
1263   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1264 #ifndef STACK_GROWS_DOWNWARD
1265   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1266                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1267 #endif
1268
1269   /* Push a new argument block and copy the arguments.  Do not allow
1270      the (potential) memcpy call below to interfere with our stack
1271      manipulations.  */
1272   do_pending_stack_adjust ();
1273   NO_DEFER_POP;
1274
1275   /* Save the stack with nonlocal if available.  */
1276 #ifdef HAVE_save_stack_nonlocal
1277   if (HAVE_save_stack_nonlocal)
1278     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1279   else
1280 #endif
1281     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1282
1283   /* Allocate a block of memory onto the stack and copy the memory
1284      arguments to the outgoing arguments address.  */
1285   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1286   dest = virtual_outgoing_args_rtx;
1287 #ifndef STACK_GROWS_DOWNWARD
1288   if (GET_CODE (argsize) == CONST_INT)
1289     dest = plus_constant (dest, -INTVAL (argsize));
1290   else
1291     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1292 #endif
1293   dest = gen_rtx_MEM (BLKmode, dest);
1294   set_mem_align (dest, PARM_BOUNDARY);
1295   src = gen_rtx_MEM (BLKmode, incoming_args);
1296   set_mem_align (src, PARM_BOUNDARY);
1297   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1298
1299   /* Refer to the argument block.  */
1300   apply_args_size ();
1301   arguments = gen_rtx_MEM (BLKmode, arguments);
1302   set_mem_align (arguments, PARM_BOUNDARY);
1303
1304   /* Walk past the arg-pointer and structure value address.  */
1305   size = GET_MODE_SIZE (Pmode);
1306   if (struct_value)
1307     size += GET_MODE_SIZE (Pmode);
1308
1309   /* Restore each of the registers previously saved.  Make USE insns
1310      for each of these registers for use in making the call.  */
1311   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1312     if ((mode = apply_args_mode[regno]) != VOIDmode)
1313       {
1314         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1315         if (size % align != 0)
1316           size = CEIL (size, align) * align;
1317         reg = gen_rtx_REG (mode, regno);
1318         emit_move_insn (reg, adjust_address (arguments, mode, size));
1319         use_reg (&call_fusage, reg);
1320         size += GET_MODE_SIZE (mode);
1321       }
1322
1323   /* Restore the structure value address unless this is passed as an
1324      "invisible" first argument.  */
1325   size = GET_MODE_SIZE (Pmode);
1326   if (struct_value)
1327     {
1328       rtx value = gen_reg_rtx (Pmode);
1329       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1330       emit_move_insn (struct_value, value);
1331       if (REG_P (struct_value))
1332         use_reg (&call_fusage, struct_value);
1333       size += GET_MODE_SIZE (Pmode);
1334     }
1335
1336   /* All arguments and registers used for the call are set up by now!  */
1337   function = prepare_call_address (function, NULL, &call_fusage, 0, 0);
1338
1339   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1340      and we don't want to load it into a register as an optimization,
1341      because prepare_call_address already did it if it should be done.  */
1342   if (GET_CODE (function) != SYMBOL_REF)
1343     function = memory_address (FUNCTION_MODE, function);
1344
1345   /* Generate the actual call instruction and save the return value.  */
1346 #ifdef HAVE_untyped_call
1347   if (HAVE_untyped_call)
1348     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1349                                       result, result_vector (1, result)));
1350   else
1351 #endif
1352 #ifdef HAVE_call_value
1353   if (HAVE_call_value)
1354     {
1355       rtx valreg = 0;
1356
1357       /* Locate the unique return register.  It is not possible to
1358          express a call that sets more than one return register using
1359          call_value; use untyped_call for that.  In fact, untyped_call
1360          only needs to save the return registers in the given block.  */
1361       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1362         if ((mode = apply_result_mode[regno]) != VOIDmode)
1363           {
1364             if (valreg)
1365               abort (); /* HAVE_untyped_call required.  */
1366             valreg = gen_rtx_REG (mode, regno);
1367           }
1368
1369       emit_call_insn (GEN_CALL_VALUE (valreg,
1370                                       gen_rtx_MEM (FUNCTION_MODE, function),
1371                                       const0_rtx, NULL_RTX, const0_rtx));
1372
1373       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1374     }
1375   else
1376 #endif
1377     abort ();
1378
1379   /* Find the CALL insn we just emitted, and attach the register usage
1380      information.  */
1381   call_insn = last_call_insn ();
1382   add_function_usage_to (call_insn, call_fusage);
1383
1384   /* Restore the stack.  */
1385 #ifdef HAVE_save_stack_nonlocal
1386   if (HAVE_save_stack_nonlocal)
1387     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1388   else
1389 #endif
1390     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1391
1392   OK_DEFER_POP;
1393
1394   /* Return the address of the result block.  */
1395   result = copy_addr_to_reg (XEXP (result, 0));
1396   return convert_memory_address (ptr_mode, result);
1397 }
1398
1399 /* Perform an untyped return.  */
1400
1401 static void
1402 expand_builtin_return (rtx result)
1403 {
1404   int size, align, regno;
1405   enum machine_mode mode;
1406   rtx reg;
1407   rtx call_fusage = 0;
1408
1409   result = convert_memory_address (Pmode, result);
1410
1411   apply_result_size ();
1412   result = gen_rtx_MEM (BLKmode, result);
1413
1414 #ifdef HAVE_untyped_return
1415   if (HAVE_untyped_return)
1416     {
1417       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1418       emit_barrier ();
1419       return;
1420     }
1421 #endif
1422
1423   /* Restore the return value and note that each value is used.  */
1424   size = 0;
1425   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1426     if ((mode = apply_result_mode[regno]) != VOIDmode)
1427       {
1428         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1429         if (size % align != 0)
1430           size = CEIL (size, align) * align;
1431         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1432         emit_move_insn (reg, adjust_address (result, mode, size));
1433
1434         push_to_sequence (call_fusage);
1435         emit_insn (gen_rtx_USE (VOIDmode, reg));
1436         call_fusage = get_insns ();
1437         end_sequence ();
1438         size += GET_MODE_SIZE (mode);
1439       }
1440
1441   /* Put the USE insns before the return.  */
1442   emit_insn (call_fusage);
1443
1444   /* Return whatever values was restored by jumping directly to the end
1445      of the function.  */
1446   expand_naked_return ();
1447 }
1448
1449 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1450
1451 static enum type_class
1452 type_to_class (tree type)
1453 {
1454   switch (TREE_CODE (type))
1455     {
1456     case VOID_TYPE:        return void_type_class;
1457     case INTEGER_TYPE:     return integer_type_class;
1458     case CHAR_TYPE:        return char_type_class;
1459     case ENUMERAL_TYPE:    return enumeral_type_class;
1460     case BOOLEAN_TYPE:     return boolean_type_class;
1461     case POINTER_TYPE:     return pointer_type_class;
1462     case REFERENCE_TYPE:   return reference_type_class;
1463     case OFFSET_TYPE:      return offset_type_class;
1464     case REAL_TYPE:        return real_type_class;
1465     case COMPLEX_TYPE:     return complex_type_class;
1466     case FUNCTION_TYPE:    return function_type_class;
1467     case METHOD_TYPE:      return method_type_class;
1468     case RECORD_TYPE:      return record_type_class;
1469     case UNION_TYPE:
1470     case QUAL_UNION_TYPE:  return union_type_class;
1471     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1472                                    ? string_type_class : array_type_class);
1473     case SET_TYPE:         return set_type_class;
1474     case FILE_TYPE:        return file_type_class;
1475     case LANG_TYPE:        return lang_type_class;
1476     default:               return no_type_class;
1477     }
1478 }
1479
1480 /* Expand a call to __builtin_classify_type with arguments found in
1481    ARGLIST.  */
1482
1483 static rtx
1484 expand_builtin_classify_type (tree arglist)
1485 {
1486   if (arglist != 0)
1487     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1488   return GEN_INT (no_type_class);
1489 }
1490
1491 /* This helper macro, meant to be used in mathfn_built_in below,
1492    determines which among a set of three builtin math functions is
1493    appropriate for a given type mode.  The `F' and `L' cases are
1494    automatically generated from the `double' case.  */
1495 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1496   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1497   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1498   fcodel = BUILT_IN_MATHFN##L ; break;
1499
1500 /* Return mathematic function equivalent to FN but operating directly
1501    on TYPE, if available.  If we can't do the conversion, return zero.  */
1502 tree
1503 mathfn_built_in (tree type, enum built_in_function fn)
1504 {
1505   enum built_in_function fcode, fcodef, fcodel;
1506
1507   switch (fn)
1508     {
1509       CASE_MATHFN (BUILT_IN_ACOS)
1510       CASE_MATHFN (BUILT_IN_ACOSH)
1511       CASE_MATHFN (BUILT_IN_ASIN)
1512       CASE_MATHFN (BUILT_IN_ASINH)
1513       CASE_MATHFN (BUILT_IN_ATAN)
1514       CASE_MATHFN (BUILT_IN_ATAN2)
1515       CASE_MATHFN (BUILT_IN_ATANH)
1516       CASE_MATHFN (BUILT_IN_CBRT)
1517       CASE_MATHFN (BUILT_IN_CEIL)
1518       CASE_MATHFN (BUILT_IN_COPYSIGN)
1519       CASE_MATHFN (BUILT_IN_COS)
1520       CASE_MATHFN (BUILT_IN_COSH)
1521       CASE_MATHFN (BUILT_IN_DREM)
1522       CASE_MATHFN (BUILT_IN_ERF)
1523       CASE_MATHFN (BUILT_IN_ERFC)
1524       CASE_MATHFN (BUILT_IN_EXP)
1525       CASE_MATHFN (BUILT_IN_EXP10)
1526       CASE_MATHFN (BUILT_IN_EXP2)
1527       CASE_MATHFN (BUILT_IN_EXPM1)
1528       CASE_MATHFN (BUILT_IN_FABS)
1529       CASE_MATHFN (BUILT_IN_FDIM)
1530       CASE_MATHFN (BUILT_IN_FLOOR)
1531       CASE_MATHFN (BUILT_IN_FMA)
1532       CASE_MATHFN (BUILT_IN_FMAX)
1533       CASE_MATHFN (BUILT_IN_FMIN)
1534       CASE_MATHFN (BUILT_IN_FMOD)
1535       CASE_MATHFN (BUILT_IN_FREXP)
1536       CASE_MATHFN (BUILT_IN_GAMMA)
1537       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1538       CASE_MATHFN (BUILT_IN_HYPOT)
1539       CASE_MATHFN (BUILT_IN_ILOGB)
1540       CASE_MATHFN (BUILT_IN_INF)
1541       CASE_MATHFN (BUILT_IN_J0)
1542       CASE_MATHFN (BUILT_IN_J1)
1543       CASE_MATHFN (BUILT_IN_JN)
1544       CASE_MATHFN (BUILT_IN_LDEXP)
1545       CASE_MATHFN (BUILT_IN_LGAMMA)
1546       CASE_MATHFN (BUILT_IN_LLRINT)
1547       CASE_MATHFN (BUILT_IN_LLROUND)
1548       CASE_MATHFN (BUILT_IN_LOG)
1549       CASE_MATHFN (BUILT_IN_LOG10)
1550       CASE_MATHFN (BUILT_IN_LOG1P)
1551       CASE_MATHFN (BUILT_IN_LOG2)
1552       CASE_MATHFN (BUILT_IN_LOGB)
1553       CASE_MATHFN (BUILT_IN_LRINT)
1554       CASE_MATHFN (BUILT_IN_LROUND)
1555       CASE_MATHFN (BUILT_IN_MODF)
1556       CASE_MATHFN (BUILT_IN_NAN)
1557       CASE_MATHFN (BUILT_IN_NANS)
1558       CASE_MATHFN (BUILT_IN_NEARBYINT)
1559       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1560       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1561       CASE_MATHFN (BUILT_IN_POW)
1562       CASE_MATHFN (BUILT_IN_POW10)
1563       CASE_MATHFN (BUILT_IN_REMAINDER)
1564       CASE_MATHFN (BUILT_IN_REMQUO)
1565       CASE_MATHFN (BUILT_IN_RINT)
1566       CASE_MATHFN (BUILT_IN_ROUND)
1567       CASE_MATHFN (BUILT_IN_SCALB)
1568       CASE_MATHFN (BUILT_IN_SCALBLN)
1569       CASE_MATHFN (BUILT_IN_SCALBN)
1570       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1571       CASE_MATHFN (BUILT_IN_SIN)
1572       CASE_MATHFN (BUILT_IN_SINCOS)
1573       CASE_MATHFN (BUILT_IN_SINH)
1574       CASE_MATHFN (BUILT_IN_SQRT)
1575       CASE_MATHFN (BUILT_IN_TAN)
1576       CASE_MATHFN (BUILT_IN_TANH)
1577       CASE_MATHFN (BUILT_IN_TGAMMA)
1578       CASE_MATHFN (BUILT_IN_TRUNC)
1579       CASE_MATHFN (BUILT_IN_Y0)
1580       CASE_MATHFN (BUILT_IN_Y1)
1581       CASE_MATHFN (BUILT_IN_YN)
1582
1583       default:
1584         return 0;
1585       }
1586
1587   if (TYPE_MAIN_VARIANT (type) == double_type_node)
1588     return implicit_built_in_decls[fcode];
1589   else if (TYPE_MAIN_VARIANT (type) == float_type_node)
1590     return implicit_built_in_decls[fcodef];
1591   else if (TYPE_MAIN_VARIANT (type) == long_double_type_node)
1592     return implicit_built_in_decls[fcodel];
1593   else
1594     return 0;
1595 }
1596
1597 /* If errno must be maintained, expand the RTL to check if the result,
1598    TARGET, of a built-in function call, EXP, is NaN, and if so set
1599    errno to EDOM.  */
1600
1601 static void
1602 expand_errno_check (tree exp, rtx target)
1603 {
1604   rtx lab = gen_label_rtx ();
1605
1606   /* Test the result; if it is NaN, set errno=EDOM because
1607      the argument was not in the domain.  */
1608   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1609                            0, lab);
1610
1611 #ifdef TARGET_EDOM
1612   /* If this built-in doesn't throw an exception, set errno directly.  */
1613   if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1614     {
1615 #ifdef GEN_ERRNO_RTX
1616       rtx errno_rtx = GEN_ERRNO_RTX;
1617 #else
1618       rtx errno_rtx
1619           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1620 #endif
1621       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1622       emit_label (lab);
1623       return;
1624     }
1625 #endif
1626
1627   /* We can't set errno=EDOM directly; let the library call do it.
1628      Pop the arguments right away in case the call gets deleted.  */
1629   NO_DEFER_POP;
1630   expand_call (exp, target, 0);
1631   OK_DEFER_POP;
1632   emit_label (lab);
1633 }
1634
1635
1636 /* Expand a call to one of the builtin math functions (sqrt, exp, or log).
1637    Return 0 if a normal call should be emitted rather than expanding the
1638    function in-line.  EXP is the expression that is a call to the builtin
1639    function; if convenient, the result should be placed in TARGET.
1640    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1641
1642 static rtx
1643 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1644 {
1645   optab builtin_optab;
1646   rtx op0, insns, before_call;
1647   tree fndecl = get_callee_fndecl (exp);
1648   tree arglist = TREE_OPERAND (exp, 1);
1649   enum machine_mode mode;
1650   bool errno_set = false;
1651   tree arg, narg;
1652
1653   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1654     return 0;
1655
1656   arg = TREE_VALUE (arglist);
1657
1658   switch (DECL_FUNCTION_CODE (fndecl))
1659     {
1660     case BUILT_IN_SQRT:
1661     case BUILT_IN_SQRTF:
1662     case BUILT_IN_SQRTL:
1663       errno_set = ! tree_expr_nonnegative_p (arg);
1664       builtin_optab = sqrt_optab;
1665       break;
1666     case BUILT_IN_EXP:
1667     case BUILT_IN_EXPF:
1668     case BUILT_IN_EXPL:
1669       errno_set = true; builtin_optab = exp_optab; break;
1670     case BUILT_IN_EXP10:
1671     case BUILT_IN_EXP10F:
1672     case BUILT_IN_EXP10L:
1673     case BUILT_IN_POW10:
1674     case BUILT_IN_POW10F:
1675     case BUILT_IN_POW10L:
1676       errno_set = true; builtin_optab = exp10_optab; break;
1677     case BUILT_IN_EXP2:
1678     case BUILT_IN_EXP2F:
1679     case BUILT_IN_EXP2L:
1680       errno_set = true; builtin_optab = exp2_optab; break;
1681     case BUILT_IN_EXPM1:
1682     case BUILT_IN_EXPM1F:
1683     case BUILT_IN_EXPM1L:
1684       errno_set = true; builtin_optab = expm1_optab; break;
1685     case BUILT_IN_LOGB:
1686     case BUILT_IN_LOGBF:
1687     case BUILT_IN_LOGBL:
1688       errno_set = true; builtin_optab = logb_optab; break;
1689     case BUILT_IN_ILOGB:
1690     case BUILT_IN_ILOGBF:
1691     case BUILT_IN_ILOGBL:
1692       errno_set = true; builtin_optab = ilogb_optab; break;
1693     case BUILT_IN_LOG:
1694     case BUILT_IN_LOGF:
1695     case BUILT_IN_LOGL:
1696       errno_set = true; builtin_optab = log_optab; break;
1697     case BUILT_IN_LOG10:
1698     case BUILT_IN_LOG10F:
1699     case BUILT_IN_LOG10L:
1700       errno_set = true; builtin_optab = log10_optab; break;
1701     case BUILT_IN_LOG2:
1702     case BUILT_IN_LOG2F:
1703     case BUILT_IN_LOG2L:
1704       errno_set = true; builtin_optab = log2_optab; break;
1705     case BUILT_IN_LOG1P:
1706     case BUILT_IN_LOG1PF:
1707     case BUILT_IN_LOG1PL:
1708       errno_set = true; builtin_optab = log1p_optab; break;
1709     case BUILT_IN_ASIN:
1710     case BUILT_IN_ASINF:
1711     case BUILT_IN_ASINL:
1712       builtin_optab = asin_optab; break;
1713     case BUILT_IN_ACOS:
1714     case BUILT_IN_ACOSF:
1715     case BUILT_IN_ACOSL:
1716       builtin_optab = acos_optab; break;
1717     case BUILT_IN_TAN:
1718     case BUILT_IN_TANF:
1719     case BUILT_IN_TANL:
1720       builtin_optab = tan_optab; break;
1721     case BUILT_IN_ATAN:
1722     case BUILT_IN_ATANF:
1723     case BUILT_IN_ATANL:
1724       builtin_optab = atan_optab; break;
1725     case BUILT_IN_FLOOR:
1726     case BUILT_IN_FLOORF:
1727     case BUILT_IN_FLOORL:
1728       builtin_optab = floor_optab; break;
1729     case BUILT_IN_CEIL:
1730     case BUILT_IN_CEILF:
1731     case BUILT_IN_CEILL:
1732       builtin_optab = ceil_optab; break;
1733     case BUILT_IN_TRUNC:
1734     case BUILT_IN_TRUNCF:
1735     case BUILT_IN_TRUNCL:
1736       builtin_optab = btrunc_optab; break;
1737     case BUILT_IN_ROUND:
1738     case BUILT_IN_ROUNDF:
1739     case BUILT_IN_ROUNDL:
1740       builtin_optab = round_optab; break;
1741     case BUILT_IN_NEARBYINT:
1742     case BUILT_IN_NEARBYINTF:
1743     case BUILT_IN_NEARBYINTL:
1744       builtin_optab = nearbyint_optab; break;
1745     default:
1746       abort ();
1747     }
1748
1749   /* Make a suitable register to place result in.  */
1750   mode = TYPE_MODE (TREE_TYPE (exp));
1751
1752   if (! flag_errno_math || ! HONOR_NANS (mode))
1753     errno_set = false;
1754
1755   /* Before working hard, check whether the instruction is available.  */
1756   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1757     {
1758       target = gen_reg_rtx (mode);
1759
1760       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1761          need to expand the argument again.  This way, we will not perform
1762          side-effects more the once.  */
1763       narg = builtin_save_expr (arg);
1764       if (narg != arg)
1765         {
1766           arglist = build_tree_list (NULL_TREE, arg);
1767           exp = build_function_call_expr (fndecl, arglist);
1768         }
1769
1770       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1771
1772       start_sequence ();
1773
1774       /* Compute into TARGET.
1775          Set TARGET to wherever the result comes back.  */
1776       target = expand_unop (mode, builtin_optab, op0, target, 0);
1777
1778       if (target != 0)
1779         {
1780           if (errno_set)
1781             expand_errno_check (exp, target);
1782
1783           /* Output the entire sequence.  */
1784           insns = get_insns ();
1785           end_sequence ();
1786           emit_insn (insns);
1787           return target;
1788         }
1789
1790       /* If we were unable to expand via the builtin, stop the sequence
1791          (without outputting the insns) and call to the library function
1792          with the stabilized argument list.  */
1793       end_sequence ();
1794     }
1795
1796   before_call = get_last_insn ();
1797
1798   target = expand_call (exp, target, target == const0_rtx);
1799
1800   /* If this is a sqrt operation and we don't care about errno, try to
1801      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1802      This allows the semantics of the libcall to be visible to the RTL
1803      optimizers.  */
1804   if (builtin_optab == sqrt_optab && !errno_set)
1805     {
1806       /* Search backwards through the insns emitted by expand_call looking
1807          for the instruction with the REG_RETVAL note.  */
1808       rtx last = get_last_insn ();
1809       while (last != before_call)
1810         {
1811           if (find_reg_note (last, REG_RETVAL, NULL))
1812             {
1813               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1814               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1815                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1816               if (note
1817                   && GET_CODE (note) == EXPR_LIST
1818                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1819                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1820                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1821                 {
1822                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1823                   /* Check operand is a register with expected mode.  */
1824                   if (operand
1825                       && REG_P (operand)
1826                       && GET_MODE (operand) == mode)
1827                     {
1828                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1829                       rtx equiv = gen_rtx_SQRT (mode, operand);
1830                       set_unique_reg_note (last, REG_EQUAL, equiv);
1831                     }
1832                 }
1833               break;
1834             }
1835           last = PREV_INSN (last);
1836         }
1837     }
1838
1839   return target;
1840 }
1841
1842 /* Expand a call to the builtin binary math functions (pow and atan2).
1843    Return 0 if a normal call should be emitted rather than expanding the
1844    function in-line.  EXP is the expression that is a call to the builtin
1845    function; if convenient, the result should be placed in TARGET.
1846    SUBTARGET may be used as the target for computing one of EXP's
1847    operands.  */
1848
1849 static rtx
1850 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1851 {
1852   optab builtin_optab;
1853   rtx op0, op1, insns;
1854   tree fndecl = get_callee_fndecl (exp);
1855   tree arglist = TREE_OPERAND (exp, 1);
1856   tree arg0, arg1, temp, narg;
1857   enum machine_mode mode;
1858   bool errno_set = true;
1859   bool stable = true;
1860
1861   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1862     return 0;
1863
1864   arg0 = TREE_VALUE (arglist);
1865   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1866
1867   switch (DECL_FUNCTION_CODE (fndecl))
1868     {
1869     case BUILT_IN_POW:
1870     case BUILT_IN_POWF:
1871     case BUILT_IN_POWL:
1872       builtin_optab = pow_optab; break;
1873     case BUILT_IN_ATAN2:
1874     case BUILT_IN_ATAN2F:
1875     case BUILT_IN_ATAN2L:
1876       builtin_optab = atan2_optab; break;
1877     case BUILT_IN_FMOD:
1878     case BUILT_IN_FMODF:
1879     case BUILT_IN_FMODL:
1880       builtin_optab = fmod_optab; break;
1881     case BUILT_IN_DREM:
1882     case BUILT_IN_DREMF:
1883     case BUILT_IN_DREML:
1884       builtin_optab = drem_optab; break;
1885     default:
1886       abort ();
1887     }
1888
1889   /* Make a suitable register to place result in.  */
1890   mode = TYPE_MODE (TREE_TYPE (exp));
1891
1892   /* Before working hard, check whether the instruction is available.  */
1893   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1894     return 0;
1895
1896   target = gen_reg_rtx (mode);
1897
1898   if (! flag_errno_math || ! HONOR_NANS (mode))
1899     errno_set = false;
1900
1901   /* Always stabilize the argument list.  */
1902   narg = builtin_save_expr (arg1);
1903   if (narg != arg1)
1904     {
1905       temp = build_tree_list (NULL_TREE, narg);
1906       stable = false;
1907     }
1908   else
1909     temp = TREE_CHAIN (arglist);
1910
1911   narg = builtin_save_expr (arg0);
1912   if (narg != arg0)
1913     {
1914       arglist = tree_cons (NULL_TREE, narg, temp);
1915       stable = false;
1916     }
1917   else if (! stable)
1918     arglist = tree_cons (NULL_TREE, arg0, temp);
1919
1920   if (! stable)
1921     exp = build_function_call_expr (fndecl, arglist);
1922
1923   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1924   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1925
1926   start_sequence ();
1927
1928   /* Compute into TARGET.
1929      Set TARGET to wherever the result comes back.  */
1930   target = expand_binop (mode, builtin_optab, op0, op1,
1931                          target, 0, OPTAB_DIRECT);
1932
1933   /* If we were unable to expand via the builtin, stop the sequence
1934      (without outputting the insns) and call to the library function
1935      with the stabilized argument list.  */
1936   if (target == 0)
1937     {
1938       end_sequence ();
1939       return expand_call (exp, target, target == const0_rtx);
1940     }
1941
1942   if (errno_set)
1943     expand_errno_check (exp, target);
1944
1945   /* Output the entire sequence.  */
1946   insns = get_insns ();
1947   end_sequence ();
1948   emit_insn (insns);
1949
1950   return target;
1951 }
1952
1953 /* Expand a call to the builtin sin and cos math functions.
1954    Return 0 if a normal call should be emitted rather than expanding the
1955    function in-line.  EXP is the expression that is a call to the builtin
1956    function; if convenient, the result should be placed in TARGET.
1957    SUBTARGET may be used as the target for computing one of EXP's
1958    operands.  */
1959
1960 static rtx
1961 expand_builtin_mathfn_3 (tree exp, rtx target, rtx subtarget)
1962 {
1963   optab builtin_optab;
1964   rtx op0, insns, before_call;
1965   tree fndecl = get_callee_fndecl (exp);
1966   tree arglist = TREE_OPERAND (exp, 1);
1967   enum machine_mode mode;
1968   bool errno_set = false;
1969   tree arg, narg;
1970
1971   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1972     return 0;
1973
1974   arg = TREE_VALUE (arglist);
1975
1976   switch (DECL_FUNCTION_CODE (fndecl))
1977     {
1978     case BUILT_IN_SIN:
1979     case BUILT_IN_SINF:
1980     case BUILT_IN_SINL:
1981     case BUILT_IN_COS:
1982     case BUILT_IN_COSF:
1983     case BUILT_IN_COSL:
1984       builtin_optab = sincos_optab; break;
1985     default:
1986       abort ();
1987     }
1988
1989   /* Make a suitable register to place result in.  */
1990   mode = TYPE_MODE (TREE_TYPE (exp));
1991
1992   if (! flag_errno_math || ! HONOR_NANS (mode))
1993     errno_set = false;
1994
1995   /* Check if sincos insn is available, otherwise fallback
1996      to sin or cos insn.  */
1997   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing) {
1998     switch (DECL_FUNCTION_CODE (fndecl))
1999       {
2000       case BUILT_IN_SIN:
2001       case BUILT_IN_SINF:
2002       case BUILT_IN_SINL:
2003         builtin_optab = sin_optab; break;
2004       case BUILT_IN_COS:
2005       case BUILT_IN_COSF:
2006       case BUILT_IN_COSL:
2007         builtin_optab = cos_optab; break;
2008       default:
2009         abort();
2010       }
2011   }
2012
2013   /* Before working hard, check whether the instruction is available.  */
2014   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2015     {
2016       target = gen_reg_rtx (mode);
2017
2018       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
2019          need to expand the argument again.  This way, we will not perform
2020          side-effects more the once.  */
2021       narg = save_expr (arg);
2022       if (narg != arg)
2023         {
2024           arglist = build_tree_list (NULL_TREE, arg);
2025           exp = build_function_call_expr (fndecl, arglist);
2026         }
2027
2028       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
2029
2030       start_sequence ();
2031
2032       /* Compute into TARGET.
2033          Set TARGET to wherever the result comes back.  */
2034       if (builtin_optab == sincos_optab)
2035         {
2036           switch (DECL_FUNCTION_CODE (fndecl))
2037             {
2038             case BUILT_IN_SIN:
2039             case BUILT_IN_SINF:
2040             case BUILT_IN_SINL:
2041               if (!expand_twoval_unop (builtin_optab, op0, 0, target, 0))    
2042                 abort();
2043               break;
2044             case BUILT_IN_COS:
2045             case BUILT_IN_COSF:
2046             case BUILT_IN_COSL:
2047               if (!expand_twoval_unop (builtin_optab, op0, target, 0, 0))
2048                 abort();
2049               break;
2050             default:
2051               abort();
2052             }
2053         }
2054       else
2055         {
2056           target = expand_unop (mode, builtin_optab, op0, target, 0);
2057         }
2058
2059       if (target != 0)
2060         {
2061           if (errno_set)
2062             expand_errno_check (exp, target);
2063
2064           /* Output the entire sequence.  */
2065           insns = get_insns ();
2066           end_sequence ();
2067           emit_insn (insns);
2068           return target;
2069         }
2070
2071       /* If we were unable to expand via the builtin, stop the sequence
2072          (without outputting the insns) and call to the library function
2073          with the stabilized argument list.  */
2074       end_sequence ();
2075     }
2076
2077   before_call = get_last_insn ();
2078
2079   target = expand_call (exp, target, target == const0_rtx);
2080
2081   return target;
2082 }
2083
2084 /* To evaluate powi(x,n), the floating point value x raised to the
2085    constant integer exponent n, we use a hybrid algorithm that
2086    combines the "window method" with look-up tables.  For an
2087    introduction to exponentiation algorithms and "addition chains",
2088    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
2089    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
2090    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
2091    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
2092
2093 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
2094    multiplications to inline before calling the system library's pow
2095    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
2096    so this default never requires calling pow, powf or powl.  */
2097
2098 #ifndef POWI_MAX_MULTS
2099 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
2100 #endif
2101
2102 /* The size of the "optimal power tree" lookup table.  All
2103    exponents less than this value are simply looked up in the
2104    powi_table below.  This threshold is also used to size the
2105    cache of pseudo registers that hold intermediate results.  */
2106 #define POWI_TABLE_SIZE 256
2107
2108 /* The size, in bits of the window, used in the "window method"
2109    exponentiation algorithm.  This is equivalent to a radix of
2110    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
2111 #define POWI_WINDOW_SIZE 3
2112
2113 /* The following table is an efficient representation of an
2114    "optimal power tree".  For each value, i, the corresponding
2115    value, j, in the table states than an optimal evaluation
2116    sequence for calculating pow(x,i) can be found by evaluating
2117    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
2118    100 integers is given in Knuth's "Seminumerical algorithms".  */
2119
2120 static const unsigned char powi_table[POWI_TABLE_SIZE] =
2121   {
2122       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
2123       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
2124       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
2125      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
2126      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
2127      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
2128      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
2129      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
2130      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
2131      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
2132      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
2133      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
2134      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
2135      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
2136      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
2137      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
2138      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
2139      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
2140      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
2141      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
2142      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
2143      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
2144      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
2145      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
2146      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
2147     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
2148     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
2149     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
2150     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
2151     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
2152     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
2153     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
2154   };
2155
2156
2157 /* Return the number of multiplications required to calculate
2158    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
2159    subroutine of powi_cost.  CACHE is an array indicating
2160    which exponents have already been calculated.  */
2161
2162 static int
2163 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
2164 {
2165   /* If we've already calculated this exponent, then this evaluation
2166      doesn't require any additional multiplications.  */
2167   if (cache[n])
2168     return 0;
2169
2170   cache[n] = true;
2171   return powi_lookup_cost (n - powi_table[n], cache)
2172          + powi_lookup_cost (powi_table[n], cache) + 1;
2173 }
2174
2175 /* Return the number of multiplications required to calculate
2176    powi(x,n) for an arbitrary x, given the exponent N.  This
2177    function needs to be kept in sync with expand_powi below.  */
2178
2179 static int
2180 powi_cost (HOST_WIDE_INT n)
2181 {
2182   bool cache[POWI_TABLE_SIZE];
2183   unsigned HOST_WIDE_INT digit;
2184   unsigned HOST_WIDE_INT val;
2185   int result;
2186
2187   if (n == 0)
2188     return 0;
2189
2190   /* Ignore the reciprocal when calculating the cost.  */
2191   val = (n < 0) ? -n : n;
2192
2193   /* Initialize the exponent cache.  */
2194   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
2195   cache[1] = true;
2196
2197   result = 0;
2198
2199   while (val >= POWI_TABLE_SIZE)
2200     {
2201       if (val & 1)
2202         {
2203           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2204           result += powi_lookup_cost (digit, cache)
2205                     + POWI_WINDOW_SIZE + 1;
2206           val >>= POWI_WINDOW_SIZE;
2207         }
2208       else
2209         {
2210           val >>= 1;
2211           result++;
2212         }
2213     }
2214
2215   return result + powi_lookup_cost (val, cache);
2216 }
2217
2218 /* Recursive subroutine of expand_powi.  This function takes the array,
2219    CACHE, of already calculated exponents and an exponent N and returns
2220    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2221
2222 static rtx
2223 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2224 {
2225   unsigned HOST_WIDE_INT digit;
2226   rtx target, result;
2227   rtx op0, op1;
2228
2229   if (n < POWI_TABLE_SIZE)
2230     {
2231       if (cache[n])
2232         return cache[n];
2233
2234       target = gen_reg_rtx (mode);
2235       cache[n] = target;
2236
2237       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2238       op1 = expand_powi_1 (mode, powi_table[n], cache);
2239     }
2240   else if (n & 1)
2241     {
2242       target = gen_reg_rtx (mode);
2243       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2244       op0 = expand_powi_1 (mode, n - digit, cache);
2245       op1 = expand_powi_1 (mode, digit, cache);
2246     }
2247   else
2248     {
2249       target = gen_reg_rtx (mode);
2250       op0 = expand_powi_1 (mode, n >> 1, cache);
2251       op1 = op0;
2252     }
2253
2254   result = expand_mult (mode, op0, op1, target, 0);
2255   if (result != target)
2256     emit_move_insn (target, result);
2257   return target;
2258 }
2259
2260 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2261    floating point operand in mode MODE, and N is the exponent.  This
2262    function needs to be kept in sync with powi_cost above.  */
2263
2264 static rtx
2265 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2266 {
2267   unsigned HOST_WIDE_INT val;
2268   rtx cache[POWI_TABLE_SIZE];
2269   rtx result;
2270
2271   if (n == 0)
2272     return CONST1_RTX (mode);
2273
2274   val = (n < 0) ? -n : n;
2275
2276   memset (cache, 0, sizeof (cache));
2277   cache[1] = x;
2278
2279   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2280
2281   /* If the original exponent was negative, reciprocate the result.  */
2282   if (n < 0)
2283     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2284                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2285
2286   return result;
2287 }
2288
2289 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2290    a normal call should be emitted rather than expanding the function
2291    in-line.  EXP is the expression that is a call to the builtin
2292    function; if convenient, the result should be placed in TARGET.  */
2293
2294 static rtx
2295 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2296 {
2297   tree arglist = TREE_OPERAND (exp, 1);
2298   tree arg0, arg1;
2299
2300   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2301     return 0;
2302
2303   arg0 = TREE_VALUE (arglist);
2304   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2305
2306   if (TREE_CODE (arg1) == REAL_CST
2307       && ! TREE_CONSTANT_OVERFLOW (arg1))
2308     {
2309       REAL_VALUE_TYPE cint;
2310       REAL_VALUE_TYPE c;
2311       HOST_WIDE_INT n;
2312
2313       c = TREE_REAL_CST (arg1);
2314       n = real_to_integer (&c);
2315       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2316       if (real_identical (&c, &cint))
2317         {
2318           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2319              Otherwise, check the number of multiplications required.
2320              Note that pow never sets errno for an integer exponent.  */
2321           if ((n >= -1 && n <= 2)
2322               || (flag_unsafe_math_optimizations
2323                   && ! optimize_size
2324                   && powi_cost (n) <= POWI_MAX_MULTS))
2325             {
2326               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2327               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2328               op = force_reg (mode, op);
2329               return expand_powi (op, mode, n);
2330             }
2331         }
2332     }
2333
2334   if (! flag_unsafe_math_optimizations)
2335     return NULL_RTX;
2336   return expand_builtin_mathfn_2 (exp, target, subtarget);
2337 }
2338
2339 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2340    if we failed the caller should emit a normal call, otherwise
2341    try to get the result in TARGET, if convenient.  */
2342
2343 static rtx
2344 expand_builtin_strlen (tree arglist, rtx target,
2345                        enum machine_mode target_mode)
2346 {
2347   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2348     return 0;
2349   else
2350     {
2351       rtx pat;
2352       tree len, src = TREE_VALUE (arglist);
2353       rtx result, src_reg, char_rtx, before_strlen;
2354       enum machine_mode insn_mode = target_mode, char_mode;
2355       enum insn_code icode = CODE_FOR_nothing;
2356       int align;
2357
2358       /* If the length can be computed at compile-time, return it.  */
2359       len = c_strlen (src, 0);
2360       if (len)
2361         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2362
2363       /* If the length can be computed at compile-time and is constant
2364          integer, but there are side-effects in src, evaluate
2365          src for side-effects, then return len.
2366          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2367          can be optimized into: i++; x = 3;  */
2368       len = c_strlen (src, 1);
2369       if (len && TREE_CODE (len) == INTEGER_CST)
2370         {
2371           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2372           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2373         }
2374
2375       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2376
2377       /* If SRC is not a pointer type, don't do this operation inline.  */
2378       if (align == 0)
2379         return 0;
2380
2381       /* Bail out if we can't compute strlen in the right mode.  */
2382       while (insn_mode != VOIDmode)
2383         {
2384           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2385           if (icode != CODE_FOR_nothing)
2386             break;
2387
2388           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2389         }
2390       if (insn_mode == VOIDmode)
2391         return 0;
2392
2393       /* Make a place to write the result of the instruction.  */
2394       result = target;
2395       if (! (result != 0
2396              && REG_P (result)
2397              && GET_MODE (result) == insn_mode
2398              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2399         result = gen_reg_rtx (insn_mode);
2400
2401       /* Make a place to hold the source address.  We will not expand
2402          the actual source until we are sure that the expansion will
2403          not fail -- there are trees that cannot be expanded twice.  */
2404       src_reg = gen_reg_rtx (Pmode);
2405
2406       /* Mark the beginning of the strlen sequence so we can emit the
2407          source operand later.  */
2408       before_strlen = get_last_insn ();
2409
2410       char_rtx = const0_rtx;
2411       char_mode = insn_data[(int) icode].operand[2].mode;
2412       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2413                                                             char_mode))
2414         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2415
2416       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2417                              char_rtx, GEN_INT (align));
2418       if (! pat)
2419         return 0;
2420       emit_insn (pat);
2421
2422       /* Now that we are assured of success, expand the source.  */
2423       start_sequence ();
2424       pat = memory_address (BLKmode,
2425                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2426       if (pat != src_reg)
2427         emit_move_insn (src_reg, pat);
2428       pat = get_insns ();
2429       end_sequence ();
2430
2431       if (before_strlen)
2432         emit_insn_after (pat, before_strlen);
2433       else
2434         emit_insn_before (pat, get_insns ());
2435
2436       /* Return the value in the proper mode for this function.  */
2437       if (GET_MODE (result) == target_mode)
2438         target = result;
2439       else if (target != 0)
2440         convert_move (target, result, 0);
2441       else
2442         target = convert_to_mode (target_mode, result, 0);
2443
2444       return target;
2445     }
2446 }
2447
2448 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2449    caller should emit a normal call, otherwise try to get the result
2450    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2451
2452 static rtx
2453 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2454 {
2455   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2456     return 0;
2457   else
2458     {
2459       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2460       tree fn, tmp;
2461       const char *p1, *p2;
2462
2463       p2 = c_getstr (s2);
2464       if (p2 == NULL)
2465         return 0;
2466
2467       p1 = c_getstr (s1);
2468       if (p1 != NULL)
2469         {
2470           const char *r = strstr (p1, p2);
2471
2472           if (r == NULL)
2473             return const0_rtx;
2474
2475           /* Return an offset into the constant string argument.  */
2476           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2477                               fold_convert (TREE_TYPE (s1),
2478                                             ssize_int (r - p1))));
2479           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2480         }
2481
2482       if (p2[0] == '\0')
2483         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2484
2485       if (p2[1] != '\0')
2486         return 0;
2487
2488       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2489       if (!fn)
2490         return 0;
2491
2492       /* New argument list transforming strstr(s1, s2) to
2493          strchr(s1, s2[0]).  */
2494       arglist =
2495         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2496       arglist = tree_cons (NULL_TREE, s1, arglist);
2497       return expand_expr (build_function_call_expr (fn, arglist),
2498                           target, mode, EXPAND_NORMAL);
2499     }
2500 }
2501
2502 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2503    caller should emit a normal call, otherwise try to get the result
2504    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2505
2506 static rtx
2507 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2508 {
2509   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2510     return 0;
2511   else
2512     {
2513       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2514       const char *p1;
2515
2516       if (TREE_CODE (s2) != INTEGER_CST)
2517         return 0;
2518
2519       p1 = c_getstr (s1);
2520       if (p1 != NULL)
2521         {
2522           char c;
2523           const char *r;
2524           tree tmp;
2525
2526           if (target_char_cast (s2, &c))
2527             return 0;
2528
2529           r = strchr (p1, c);
2530
2531           if (r == NULL)
2532             return const0_rtx;
2533
2534           /* Return an offset into the constant string argument.  */
2535           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2536                               fold_convert (TREE_TYPE (s1),
2537                                             ssize_int (r - p1))));
2538           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2539         }
2540
2541       /* FIXME: Should use here strchrM optab so that ports can optimize
2542          this.  */
2543       return 0;
2544     }
2545 }
2546
2547 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2548    caller should emit a normal call, otherwise try to get the result
2549    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2550
2551 static rtx
2552 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2553 {
2554   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2555     return 0;
2556   else
2557     {
2558       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2559       tree fn, tmp;
2560       const char *p1;
2561
2562       if (TREE_CODE (s2) != INTEGER_CST)
2563         return 0;
2564
2565       p1 = c_getstr (s1);
2566       if (p1 != NULL)
2567         {
2568           char c;
2569           const char *r;
2570
2571           if (target_char_cast (s2, &c))
2572             return 0;
2573
2574           r = strrchr (p1, c);
2575
2576           if (r == NULL)
2577             return const0_rtx;
2578
2579           /* Return an offset into the constant string argument.  */
2580           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2581                               fold_convert (TREE_TYPE (s1),
2582                                             ssize_int (r - p1))));
2583           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2584         }
2585
2586       if (! integer_zerop (s2))
2587         return 0;
2588
2589       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2590       if (!fn)
2591         return 0;
2592
2593       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2594       return expand_expr (build_function_call_expr (fn, arglist),
2595                           target, mode, EXPAND_NORMAL);
2596     }
2597 }
2598
2599 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2600    caller should emit a normal call, otherwise try to get the result
2601    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2602
2603 static rtx
2604 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2605 {
2606   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2607     return 0;
2608   else
2609     {
2610       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2611       tree fn, tmp;
2612       const char *p1, *p2;
2613
2614       p2 = c_getstr (s2);
2615       if (p2 == NULL)
2616         return 0;
2617
2618       p1 = c_getstr (s1);
2619       if (p1 != NULL)
2620         {
2621           const char *r = strpbrk (p1, p2);
2622
2623           if (r == NULL)
2624             return const0_rtx;
2625
2626           /* Return an offset into the constant string argument.  */
2627           tmp = fold (build2 (PLUS_EXPR, TREE_TYPE (s1), s1,
2628                               fold_convert (TREE_TYPE (s1),
2629                                             ssize_int (r - p1))));
2630           return expand_expr (tmp, target, mode, EXPAND_NORMAL);
2631         }
2632
2633       if (p2[0] == '\0')
2634         {
2635           /* strpbrk(x, "") == NULL.
2636              Evaluate and ignore the arguments in case they had
2637              side-effects.  */
2638           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2639           return const0_rtx;
2640         }
2641
2642       if (p2[1] != '\0')
2643         return 0;  /* Really call strpbrk.  */
2644
2645       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2646       if (!fn)
2647         return 0;
2648
2649       /* New argument list transforming strpbrk(s1, s2) to
2650          strchr(s1, s2[0]).  */
2651       arglist =
2652         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2653       arglist = tree_cons (NULL_TREE, s1, arglist);
2654       return expand_expr (build_function_call_expr (fn, arglist),
2655                           target, mode, EXPAND_NORMAL);
2656     }
2657 }
2658
2659 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2660    bytes from constant string DATA + OFFSET and return it as target
2661    constant.  */
2662
2663 static rtx
2664 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2665                          enum machine_mode mode)
2666 {
2667   const char *str = (const char *) data;
2668
2669   if (offset < 0
2670       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2671           > strlen (str) + 1))
2672     abort ();  /* Attempt to read past the end of constant string.  */
2673
2674   return c_readstr (str + offset, mode);
2675 }
2676
2677 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2678    Return 0 if we failed, the caller should emit a normal call,
2679    otherwise try to get the result in TARGET, if convenient (and in
2680    mode MODE if that's convenient).  */
2681 static rtx
2682 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2683 {
2684   if (!validate_arglist (arglist,
2685                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2686     return 0;
2687   else
2688     {
2689       tree dest = TREE_VALUE (arglist);
2690       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2691       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2692       const char *src_str;
2693       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2694       unsigned int dest_align
2695         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2696       rtx dest_mem, src_mem, dest_addr, len_rtx;
2697
2698       /* If DEST is not a pointer type, call the normal function.  */
2699       if (dest_align == 0)
2700         return 0;
2701
2702       /* If the LEN parameter is zero, return DEST.  */
2703       if (integer_zerop (len))
2704         {
2705           /* Evaluate and ignore SRC in case it has side-effects.  */
2706           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2707           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2708         }
2709
2710       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2711       if (operand_equal_p (src, dest, 0))
2712         {
2713           /* Evaluate and ignore LEN in case it has side-effects.  */
2714           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2715           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2716         }
2717
2718       /* If either SRC is not a pointer type, don't do this
2719          operation in-line.  */
2720       if (src_align == 0)
2721         return 0;
2722
2723       dest_mem = get_memory_rtx (dest);
2724       set_mem_align (dest_mem, dest_align);
2725       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2726       src_str = c_getstr (src);
2727
2728       /* If SRC is a string constant and block move would be done
2729          by pieces, we can avoid loading the string from memory
2730          and only stored the computed constants.  */
2731       if (src_str
2732           && GET_CODE (len_rtx) == CONST_INT
2733           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2734           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2735                                   (void *) src_str, dest_align))
2736         {
2737           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2738                                       builtin_memcpy_read_str,
2739                                       (void *) src_str, dest_align, 0);
2740           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2741           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2742           return dest_mem;
2743         }
2744
2745       src_mem = get_memory_rtx (src);
2746       set_mem_align (src_mem, src_align);
2747
2748       /* Copy word part most expediently.  */
2749       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2750                                    BLOCK_OP_NORMAL);
2751
2752       if (dest_addr == 0)
2753         {
2754           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2755           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2756         }
2757       return dest_addr;
2758     }
2759 }
2760
2761 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2762    Return 0 if we failed the caller should emit a normal call,
2763    otherwise try to get the result in TARGET, if convenient (and in
2764    mode MODE if that's convenient).  If ENDP is 0 return the
2765    destination pointer, if ENDP is 1 return the end pointer ala
2766    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2767    stpcpy.  */
2768
2769 static rtx
2770 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2771                         int endp)
2772 {
2773   if (!validate_arglist (arglist,
2774                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2775     return 0;
2776   /* If return value is ignored, transform mempcpy into memcpy.  */
2777   else if (target == const0_rtx)
2778     {
2779       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2780
2781       if (!fn)
2782         return 0;
2783
2784       return expand_expr (build_function_call_expr (fn, arglist),
2785                           target, mode, EXPAND_NORMAL);
2786     }
2787   else
2788     {
2789       tree dest = TREE_VALUE (arglist);
2790       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2791       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2792       const char *src_str;
2793       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2794       unsigned int dest_align
2795         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2796       rtx dest_mem, src_mem, len_rtx;
2797
2798       /* If DEST is not a pointer type, call the normal function.  */
2799       if (dest_align == 0)
2800         return 0;
2801
2802       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2803       if (operand_equal_p (src, dest, 0))
2804         {
2805           tree expr;
2806
2807           if (endp == 0)
2808             {
2809               /* Evaluate and ignore LEN in case it has side-effects.  */
2810               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2811               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2812             }
2813
2814           if (endp == 2)
2815             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
2816                                 integer_one_node));
2817           len = fold_convert (TREE_TYPE (dest), len);
2818           expr = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2819           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2820         }
2821
2822       /* If LEN is not constant, call the normal function.  */
2823       if (! host_integerp (len, 1))
2824         return 0;
2825
2826       /* If the LEN parameter is zero, return DEST.  */
2827       if (tree_low_cst (len, 1) == 0)
2828         {
2829           /* Evaluate and ignore SRC in case it has side-effects.  */
2830           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2831           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2832         }
2833
2834       /* If either SRC is not a pointer type, don't do this
2835          operation in-line.  */
2836       if (src_align == 0)
2837         return 0;
2838
2839       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2840       src_str = c_getstr (src);
2841
2842       /* If SRC is a string constant and block move would be done
2843          by pieces, we can avoid loading the string from memory
2844          and only stored the computed constants.  */
2845       if (src_str
2846           && GET_CODE (len_rtx) == CONST_INT
2847           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2848           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2849                                   (void *) src_str, dest_align))
2850         {
2851           dest_mem = get_memory_rtx (dest);
2852           set_mem_align (dest_mem, dest_align);
2853           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2854                                       builtin_memcpy_read_str,
2855                                       (void *) src_str, dest_align, endp);
2856           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2857           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2858           return dest_mem;
2859         }
2860
2861       if (GET_CODE (len_rtx) == CONST_INT
2862           && can_move_by_pieces (INTVAL (len_rtx),
2863                                  MIN (dest_align, src_align)))
2864         {
2865           dest_mem = get_memory_rtx (dest);
2866           set_mem_align (dest_mem, dest_align);
2867           src_mem = get_memory_rtx (src);
2868           set_mem_align (src_mem, src_align);
2869           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2870                                      MIN (dest_align, src_align), endp);
2871           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2872           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2873           return dest_mem;
2874         }
2875
2876       return 0;
2877     }
2878 }
2879
2880 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2881    if we failed the caller should emit a normal call.  */
2882
2883 static rtx
2884 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2885 {
2886   if (!validate_arglist (arglist,
2887                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2888     return 0;
2889   else
2890     {
2891       tree dest = TREE_VALUE (arglist);
2892       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2893       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2894
2895       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2896       unsigned int dest_align
2897         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2898
2899       /* If DEST is not a pointer type, call the normal function.  */
2900       if (dest_align == 0)
2901         return 0;
2902
2903       /* If the LEN parameter is zero, return DEST.  */
2904       if (integer_zerop (len))
2905         {
2906           /* Evaluate and ignore SRC in case it has side-effects.  */
2907           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2908           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2909         }
2910
2911       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2912       if (operand_equal_p (src, dest, 0))
2913         {
2914           /* Evaluate and ignore LEN in case it has side-effects.  */
2915           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2916           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2917         }
2918
2919       /* If either SRC is not a pointer type, don't do this
2920          operation in-line.  */
2921       if (src_align == 0)
2922         return 0;
2923
2924       /* If src is categorized for a readonly section we can use
2925          normal memcpy.  */
2926       if (readonly_data_expr (src))
2927         {
2928           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2929           if (!fn)
2930             return 0;
2931           return expand_expr (build_function_call_expr (fn, arglist),
2932                               target, mode, EXPAND_NORMAL);
2933         }
2934
2935       /* Otherwise, call the normal function.  */
2936       return 0;
2937    }
2938 }
2939
2940 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2941    if we failed the caller should emit a normal call.  */
2942
2943 static rtx
2944 expand_builtin_bcopy (tree arglist)
2945 {
2946   tree src, dest, size, newarglist;
2947
2948   if (!validate_arglist (arglist,
2949                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2950     return NULL_RTX;
2951
2952   src = TREE_VALUE (arglist);
2953   dest = TREE_VALUE (TREE_CHAIN (arglist));
2954   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2955
2956   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2957      memmove(ptr y, ptr x, size_t z).   This is done this way
2958      so that if it isn't expanded inline, we fallback to
2959      calling bcopy instead of memmove.  */
2960
2961   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
2962   newarglist = tree_cons (NULL_TREE, src, newarglist);
2963   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2964
2965   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2966 }
2967
2968 #ifndef HAVE_movstr
2969 # define HAVE_movstr 0
2970 # define CODE_FOR_movstr CODE_FOR_nothing
2971 #endif
2972
2973 /* Expand into a movstr instruction, if one is available.  Return 0 if
2974    we failed, the caller should emit a normal call, otherwise try to
2975    get the result in TARGET, if convenient.  If ENDP is 0 return the
2976    destination pointer, if ENDP is 1 return the end pointer ala
2977    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2978    stpcpy.  */
2979
2980 static rtx
2981 expand_movstr (tree dest, tree src, rtx target, int endp)
2982 {
2983   rtx end;
2984   rtx dest_mem;
2985   rtx src_mem;
2986   rtx insn;
2987   const struct insn_data * data;
2988
2989   if (!HAVE_movstr)
2990     return 0;
2991
2992   dest_mem = get_memory_rtx (dest);
2993   src_mem = get_memory_rtx (src);
2994   if (!endp)
2995     {
2996       target = force_reg (Pmode, XEXP (dest_mem, 0));
2997       dest_mem = replace_equiv_address (dest_mem, target);
2998       end = gen_reg_rtx (Pmode);
2999     }
3000   else
3001     {
3002       if (target == 0 || target == const0_rtx)
3003         {
3004           end = gen_reg_rtx (Pmode);
3005           if (target == 0)
3006             target = end;
3007         }
3008       else
3009         end = target;
3010     }
3011
3012   data = insn_data + CODE_FOR_movstr;
3013
3014   if (data->operand[0].mode != VOIDmode)
3015     end = gen_lowpart (data->operand[0].mode, end);
3016
3017   insn = data->genfun (end, dest_mem, src_mem);
3018
3019   if (insn == 0)
3020     abort ();
3021
3022   emit_insn (insn);
3023
3024   /* movstr is supposed to set end to the address of the NUL
3025      terminator.  If the caller requested a mempcpy-like return value,
3026      adjust it.  */
3027   if (endp == 1 && target != const0_rtx)
3028     emit_move_insn (target, plus_constant (gen_lowpart (GET_MODE (target),
3029                                                         end), 1));
3030
3031   return target;
3032 }
3033
3034 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
3035    if we failed the caller should emit a normal call, otherwise try to get
3036    the result in TARGET, if convenient (and in mode MODE if that's
3037    convenient).  */
3038
3039 static rtx
3040 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
3041 {
3042   tree fn, len, src, dst;
3043
3044   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3045     return 0;
3046
3047   src = TREE_VALUE (TREE_CHAIN (arglist));
3048   dst = TREE_VALUE (arglist);
3049
3050   /* If SRC and DST are equal (and not volatile), return DST.  */
3051   if (operand_equal_p (src, dst, 0))
3052     return expand_expr (dst, target, mode, EXPAND_NORMAL);
3053
3054   len = c_strlen (src, 1);
3055   if (len == 0 || TREE_SIDE_EFFECTS (len))
3056     return expand_movstr (TREE_VALUE (arglist),
3057                           TREE_VALUE (TREE_CHAIN (arglist)),
3058                           target, /*endp=*/0);
3059
3060   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3061   if (!fn)
3062     return 0;
3063
3064   len = size_binop (PLUS_EXPR, len, ssize_int (1));
3065   arglist = build_tree_list (NULL_TREE, len);
3066   arglist = tree_cons (NULL_TREE, src, arglist);
3067   arglist = tree_cons (NULL_TREE, dst, arglist);
3068   return expand_expr (build_function_call_expr (fn, arglist),
3069                       target, mode, EXPAND_NORMAL);
3070 }
3071
3072 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
3073    Return 0 if we failed the caller should emit a normal call,
3074    otherwise try to get the result in TARGET, if convenient (and in
3075    mode MODE if that's convenient).  */
3076
3077 static rtx
3078 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
3079 {
3080   /* If return value is ignored, transform stpcpy into strcpy.  */
3081   if (target == const0_rtx)
3082     {
3083       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
3084       if (!fn)
3085         return 0;
3086
3087       return expand_expr (build_function_call_expr (fn, arglist),
3088                           target, mode, EXPAND_NORMAL);
3089     }
3090
3091   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3092     return 0;
3093   else
3094     {
3095       tree dst, src, len, lenp1;
3096       tree narglist;
3097       rtx ret;
3098
3099       /* Ensure we get an actual string whose length can be evaluated at
3100          compile-time, not an expression containing a string.  This is
3101          because the latter will potentially produce pessimized code
3102          when used to produce the return value.  */
3103       src = TREE_VALUE (TREE_CHAIN (arglist));
3104       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
3105         return expand_movstr (TREE_VALUE (arglist),
3106                               TREE_VALUE (TREE_CHAIN (arglist)),
3107                               target, /*endp=*/2);
3108
3109       dst = TREE_VALUE (arglist);
3110       lenp1 = size_binop (PLUS_EXPR, len, ssize_int (1));
3111       narglist = build_tree_list (NULL_TREE, lenp1);
3112       narglist = tree_cons (NULL_TREE, src, narglist);
3113       narglist = tree_cons (NULL_TREE, dst, narglist);
3114       ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2);
3115
3116       if (ret)
3117         return ret;
3118
3119       if (TREE_CODE (len) == INTEGER_CST)
3120         {
3121           rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3122
3123           if (GET_CODE (len_rtx) == CONST_INT)
3124             {
3125               ret = expand_builtin_strcpy (arglist, target, mode);
3126
3127               if (ret)
3128                 {
3129                   if (! target)
3130                     {
3131                       if (mode != VOIDmode)
3132                         target = gen_reg_rtx (mode);
3133                       else
3134                         target = gen_reg_rtx (GET_MODE (ret));
3135                     }
3136                   if (GET_MODE (target) != GET_MODE (ret))
3137                     ret = gen_lowpart (GET_MODE (target), ret);
3138
3139                   ret = emit_move_insn (target,
3140                                         plus_constant (ret,
3141                                                        INTVAL (len_rtx)));
3142                   if (! ret)
3143                     abort ();
3144
3145                   return target;
3146                 }
3147             }
3148         }
3149
3150       return expand_movstr (TREE_VALUE (arglist),
3151                             TREE_VALUE (TREE_CHAIN (arglist)),
3152                             target, /*endp=*/2);
3153     }
3154 }
3155
3156 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3157    bytes from constant string DATA + OFFSET and return it as target
3158    constant.  */
3159
3160 static rtx
3161 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
3162                           enum machine_mode mode)
3163 {
3164   const char *str = (const char *) data;
3165
3166   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
3167     return const0_rtx;
3168
3169   return c_readstr (str + offset, mode);
3170 }
3171
3172 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
3173    if we failed the caller should emit a normal call.  */
3174
3175 static rtx
3176 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
3177 {
3178   if (!validate_arglist (arglist,
3179                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3180     return 0;
3181   else
3182     {
3183       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
3184       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3185       tree fn;
3186
3187       /* We must be passed a constant len parameter.  */
3188       if (TREE_CODE (len) != INTEGER_CST)
3189         return 0;
3190
3191       /* If the len parameter is zero, return the dst parameter.  */
3192       if (integer_zerop (len))
3193         {
3194           /* Evaluate and ignore the src argument in case it has
3195              side-effects.  */
3196           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
3197                        VOIDmode, EXPAND_NORMAL);
3198           /* Return the dst parameter.  */
3199           return expand_expr (TREE_VALUE (arglist), target, mode,
3200                               EXPAND_NORMAL);
3201         }
3202
3203       /* Now, we must be passed a constant src ptr parameter.  */
3204       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
3205         return 0;
3206
3207       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
3208
3209       /* We're required to pad with trailing zeros if the requested
3210          len is greater than strlen(s2)+1.  In that case try to
3211          use store_by_pieces, if it fails, punt.  */
3212       if (tree_int_cst_lt (slen, len))
3213         {
3214           tree dest = TREE_VALUE (arglist);
3215           unsigned int dest_align
3216             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3217           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
3218           rtx dest_mem;
3219
3220           if (!p || dest_align == 0 || !host_integerp (len, 1)
3221               || !can_store_by_pieces (tree_low_cst (len, 1),
3222                                        builtin_strncpy_read_str,
3223                                        (void *) p, dest_align))
3224             return 0;
3225
3226           dest_mem = get_memory_rtx (dest);
3227           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3228                            builtin_strncpy_read_str,
3229                            (void *) p, dest_align, 0);
3230           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3231           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3232           return dest_mem;
3233         }
3234
3235       /* OK transform into builtin memcpy.  */
3236       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
3237       if (!fn)
3238         return 0;
3239       return expand_expr (build_function_call_expr (fn, arglist),
3240                           target, mode, EXPAND_NORMAL);
3241     }
3242 }
3243
3244 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
3245    bytes from constant string DATA + OFFSET and return it as target
3246    constant.  */
3247
3248 static rtx
3249 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3250                          enum machine_mode mode)
3251 {
3252   const char *c = (const char *) data;
3253   char *p = alloca (GET_MODE_SIZE (mode));
3254
3255   memset (p, *c, GET_MODE_SIZE (mode));
3256
3257   return c_readstr (p, mode);
3258 }
3259
3260 /* Callback routine for store_by_pieces.  Return the RTL of a register
3261    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
3262    char value given in the RTL register data.  For example, if mode is
3263    4 bytes wide, return the RTL for 0x01010101*data.  */
3264
3265 static rtx
3266 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
3267                         enum machine_mode mode)
3268 {
3269   rtx target, coeff;
3270   size_t size;
3271   char *p;
3272
3273   size = GET_MODE_SIZE (mode);
3274   if (size == 1)
3275     return (rtx) data;
3276
3277   p = alloca (size);
3278   memset (p, 1, size);
3279   coeff = c_readstr (p, mode);
3280
3281   target = convert_to_mode (mode, (rtx) data, 1);
3282   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
3283   return force_reg (mode, target);
3284 }
3285
3286 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
3287    if we failed the caller should emit a normal call, otherwise try to get
3288    the result in TARGET, if convenient (and in mode MODE if that's
3289    convenient).  */
3290
3291 static rtx
3292 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
3293 {
3294   if (!validate_arglist (arglist,
3295                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
3296     return 0;
3297   else
3298     {
3299       tree dest = TREE_VALUE (arglist);
3300       tree val = TREE_VALUE (TREE_CHAIN (arglist));
3301       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3302       char c;
3303
3304       unsigned int dest_align
3305         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
3306       rtx dest_mem, dest_addr, len_rtx;
3307
3308       /* If DEST is not a pointer type, don't do this
3309          operation in-line.  */
3310       if (dest_align == 0)
3311         return 0;
3312
3313       /* If the LEN parameter is zero, return DEST.  */
3314       if (integer_zerop (len))
3315         {
3316           /* Evaluate and ignore VAL in case it has side-effects.  */
3317           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3318           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3319         }
3320
3321       if (TREE_CODE (val) != INTEGER_CST)
3322         {
3323           rtx val_rtx;
3324
3325           if (!host_integerp (len, 1))
3326             return 0;
3327
3328           if (optimize_size && tree_low_cst (len, 1) > 1)
3329             return 0;
3330
3331           /* Assume that we can memset by pieces if we can store the
3332            * the coefficients by pieces (in the required modes).
3333            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3334           c = 1;
3335           if (!can_store_by_pieces (tree_low_cst (len, 1),
3336                                     builtin_memset_read_str,
3337                                     &c, dest_align))
3338             return 0;
3339
3340           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3341           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3342           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3343                                val_rtx);
3344           dest_mem = get_memory_rtx (dest);
3345           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3346                            builtin_memset_gen_str,
3347                            val_rtx, dest_align, 0);
3348           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3349           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3350           return dest_mem;
3351         }
3352
3353       if (target_char_cast (val, &c))
3354         return 0;
3355
3356       if (c)
3357         {
3358           if (!host_integerp (len, 1))
3359             return 0;
3360           if (!can_store_by_pieces (tree_low_cst (len, 1),
3361                                     builtin_memset_read_str, &c,
3362                                     dest_align))
3363             return 0;
3364
3365           dest_mem = get_memory_rtx (dest);
3366           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3367                            builtin_memset_read_str,
3368                            &c, dest_align, 0);
3369           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3370           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3371           return dest_mem;
3372         }
3373
3374       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3375
3376       dest_mem = get_memory_rtx (dest);
3377       set_mem_align (dest_mem, dest_align);
3378       dest_addr = clear_storage (dest_mem, len_rtx);
3379
3380       if (dest_addr == 0)
3381         {
3382           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3383           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3384         }
3385
3386       return dest_addr;
3387     }
3388 }
3389
3390 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3391    if we failed the caller should emit a normal call.  */
3392
3393 static rtx
3394 expand_builtin_bzero (tree arglist)
3395 {
3396   tree dest, size, newarglist;
3397
3398   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3399     return NULL_RTX;
3400
3401   dest = TREE_VALUE (arglist);
3402   size = TREE_VALUE (TREE_CHAIN (arglist));
3403
3404   /* New argument list transforming bzero(ptr x, int y) to
3405      memset(ptr x, int 0, size_t y).   This is done this way
3406      so that if it isn't expanded inline, we fallback to
3407      calling bzero instead of memset.  */
3408
3409   newarglist = build_tree_list (NULL_TREE, fold_convert (sizetype, size));
3410   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3411   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3412
3413   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3414 }
3415
3416 /* Expand expression EXP, which is a call to the memcmp built-in function.
3417    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3418    caller should emit a normal call, otherwise try to get the result in
3419    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3420
3421 static rtx
3422 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3423                        enum machine_mode mode)
3424 {
3425   tree arg1, arg2, len;
3426   const char *p1, *p2;
3427
3428   if (!validate_arglist (arglist,
3429                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3430     return 0;
3431
3432   arg1 = TREE_VALUE (arglist);
3433   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3434   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3435
3436   /* If the len parameter is zero, return zero.  */
3437   if (integer_zerop (len))
3438     {
3439       /* Evaluate and ignore arg1 and arg2 in case they have
3440          side-effects.  */
3441       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3442       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3443       return const0_rtx;
3444     }
3445
3446   /* If both arguments are equal (and not volatile), return zero.  */
3447   if (operand_equal_p (arg1, arg2, 0))
3448     {
3449       /* Evaluate and ignore len in case it has side-effects.  */
3450       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3451       return const0_rtx;
3452     }
3453
3454   p1 = c_getstr (arg1);
3455   p2 = c_getstr (arg2);
3456
3457   /* If all arguments are constant, and the value of len is not greater
3458      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3459   if (host_integerp (len, 1) && p1 && p2
3460       && compare_tree_int (len, strlen (p1) + 1) <= 0
3461       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3462     {
3463       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3464
3465       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3466     }
3467
3468   /* If len parameter is one, return an expression corresponding to
3469      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3470   if (integer_onep (len))
3471     {
3472       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3473       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3474       tree ind1 =
3475       fold (build1 (CONVERT_EXPR, integer_type_node,
3476                     build1 (INDIRECT_REF, cst_uchar_node,
3477                             fold_convert (cst_uchar_ptr_node, arg1))));
3478       tree ind2 =
3479       fold (build1 (CONVERT_EXPR, integer_type_node,
3480                     build1 (INDIRECT_REF, cst_uchar_node,
3481                             fold_convert (cst_uchar_ptr_node, arg2))));
3482       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3483       return expand_expr (result, target, mode, EXPAND_NORMAL);
3484     }
3485
3486 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3487   {
3488     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3489     rtx result;
3490     rtx insn;
3491
3492     int arg1_align
3493       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3494     int arg2_align
3495       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3496     enum machine_mode insn_mode;
3497
3498 #ifdef HAVE_cmpmemsi
3499     if (HAVE_cmpmemsi)
3500       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3501     else
3502 #endif
3503 #ifdef HAVE_cmpstrsi
3504     if (HAVE_cmpstrsi)
3505       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3506     else
3507 #endif
3508       return 0;
3509
3510     /* If we don't have POINTER_TYPE, call the function.  */
3511     if (arg1_align == 0 || arg2_align == 0)
3512       return 0;
3513
3514     /* Make a place to write the result of the instruction.  */
3515     result = target;
3516     if (! (result != 0
3517            && REG_P (result) && GET_MODE (result) == insn_mode
3518            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3519       result = gen_reg_rtx (insn_mode);
3520
3521     arg1_rtx = get_memory_rtx (arg1);
3522     arg2_rtx = get_memory_rtx (arg2);
3523     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3524 #ifdef HAVE_cmpmemsi
3525     if (HAVE_cmpmemsi)
3526       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3527                            GEN_INT (MIN (arg1_align, arg2_align)));
3528     else
3529 #endif
3530 #ifdef HAVE_cmpstrsi
3531     if (HAVE_cmpstrsi)
3532       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3533                            GEN_INT (MIN (arg1_align, arg2_align)));
3534     else
3535 #endif
3536       abort ();
3537
3538     if (insn)
3539       emit_insn (insn);
3540     else
3541       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3542                                TYPE_MODE (integer_type_node), 3,
3543                                XEXP (arg1_rtx, 0), Pmode,
3544                                XEXP (arg2_rtx, 0), Pmode,
3545                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3546                                                 TYPE_UNSIGNED (sizetype)),
3547                                TYPE_MODE (sizetype));
3548
3549     /* Return the value in the proper mode for this function.  */
3550     mode = TYPE_MODE (TREE_TYPE (exp));
3551     if (GET_MODE (result) == mode)
3552       return result;
3553     else if (target != 0)
3554       {
3555         convert_move (target, result, 0);
3556         return target;
3557       }
3558     else
3559       return convert_to_mode (mode, result, 0);
3560   }
3561 #endif
3562
3563   return 0;
3564 }
3565
3566 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3567    if we failed the caller should emit a normal call, otherwise try to get
3568    the result in TARGET, if convenient.  */
3569
3570 static rtx
3571 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3572 {
3573   tree arglist = TREE_OPERAND (exp, 1);
3574   tree arg1, arg2;
3575   const char *p1, *p2;
3576
3577   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3578     return 0;
3579
3580   arg1 = TREE_VALUE (arglist);
3581   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3582
3583   /* If both arguments are equal (and not volatile), return zero.  */
3584   if (operand_equal_p (arg1, arg2, 0))
3585     return const0_rtx;
3586
3587   p1 = c_getstr (arg1);
3588   p2 = c_getstr (arg2);
3589
3590   if (p1 && p2)
3591     {
3592       const int i = strcmp (p1, p2);
3593       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3594     }
3595
3596   /* If either arg is "", return an expression corresponding to
3597      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3598   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3599     {
3600       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3601       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3602       tree ind1 =
3603         fold (build1 (CONVERT_EXPR, integer_type_node,
3604                       build1 (INDIRECT_REF, cst_uchar_node,
3605                               fold_convert (cst_uchar_ptr_node, arg1))));
3606       tree ind2 =
3607         fold (build1 (CONVERT_EXPR, integer_type_node,
3608                       build1 (INDIRECT_REF, cst_uchar_node,
3609                               fold_convert (cst_uchar_ptr_node, arg2))));
3610       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3611       return expand_expr (result, target, mode, EXPAND_NORMAL);
3612     }
3613
3614 #ifdef HAVE_cmpstrsi
3615   if (HAVE_cmpstrsi)
3616   {
3617     tree len, len1, len2;
3618     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3619     rtx result, insn;
3620     tree fndecl;
3621
3622     int arg1_align
3623       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3624     int arg2_align
3625       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3626     enum machine_mode insn_mode
3627       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3628
3629     len1 = c_strlen (arg1, 1);
3630     len2 = c_strlen (arg2, 1);
3631
3632     if (len1)
3633       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3634     if (len2)
3635       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3636
3637     /* If we don't have a constant length for the first, use the length
3638        of the second, if we know it.  We don't require a constant for
3639        this case; some cost analysis could be done if both are available
3640        but neither is constant.  For now, assume they're equally cheap,
3641        unless one has side effects.  If both strings have constant lengths,
3642        use the smaller.  */
3643
3644     if (!len1)
3645       len = len2;
3646     else if (!len2)
3647       len = len1;
3648     else if (TREE_SIDE_EFFECTS (len1))
3649       len = len2;
3650     else if (TREE_SIDE_EFFECTS (len2))
3651       len = len1;
3652     else if (TREE_CODE (len1) != INTEGER_CST)
3653       len = len2;
3654     else if (TREE_CODE (len2) != INTEGER_CST)
3655       len = len1;
3656     else if (tree_int_cst_lt (len1, len2))
3657       len = len1;
3658     else
3659       len = len2;
3660
3661     /* If both arguments have side effects, we cannot optimize.  */
3662     if (!len || TREE_SIDE_EFFECTS (len))
3663       return 0;
3664
3665     /* If we don't have POINTER_TYPE, call the function.  */
3666     if (arg1_align == 0 || arg2_align == 0)
3667       return 0;
3668
3669     /* Make a place to write the result of the instruction.  */
3670     result = target;
3671     if (! (result != 0
3672            && REG_P (result) && GET_MODE (result) == insn_mode
3673            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3674       result = gen_reg_rtx (insn_mode);
3675
3676     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3677     arg1 = builtin_save_expr (arg1);
3678     arg2 = builtin_save_expr (arg2);
3679
3680     arg1_rtx = get_memory_rtx (arg1);
3681     arg2_rtx = get_memory_rtx (arg2);
3682     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3683     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3684                          GEN_INT (MIN (arg1_align, arg2_align)));
3685     if (insn)
3686       {
3687         emit_insn (insn);
3688
3689         /* Return the value in the proper mode for this function.  */
3690         mode = TYPE_MODE (TREE_TYPE (exp));
3691         if (GET_MODE (result) == mode)
3692           return result;
3693         if (target == 0)
3694           return convert_to_mode (mode, result, 0);
3695         convert_move (target, result, 0);
3696         return target;
3697       }
3698
3699     /* Expand the library call ourselves using a stabilized argument
3700        list to avoid re-evaluating the function's arguments twice.  */
3701     arglist = build_tree_list (NULL_TREE, arg2);
3702     arglist = tree_cons (NULL_TREE, arg1, arglist);
3703     fndecl = get_callee_fndecl (exp);
3704     exp = build_function_call_expr (fndecl, arglist);
3705     return expand_call (exp, target, target == const0_rtx);
3706   }
3707 #endif
3708   return 0;
3709 }
3710
3711 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3712    if we failed the caller should emit a normal call, otherwise try to get
3713    the result in TARGET, if convenient.  */
3714
3715 static rtx
3716 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3717 {
3718   tree arglist = TREE_OPERAND (exp, 1);
3719   tree arg1, arg2, arg3;
3720   const char *p1, *p2;
3721
3722   if (!validate_arglist (arglist,
3723                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3724     return 0;
3725
3726   arg1 = TREE_VALUE (arglist);
3727   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3728   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3729
3730   /* If the len parameter is zero, return zero.  */
3731   if (integer_zerop (arg3))
3732     {
3733       /* Evaluate and ignore arg1 and arg2 in case they have
3734          side-effects.  */
3735       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3736       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3737       return const0_rtx;
3738     }
3739
3740   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3741   if (operand_equal_p (arg1, arg2, 0))
3742     {
3743       /* Evaluate and ignore arg3 in case it has side-effects.  */
3744       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3745       return const0_rtx;
3746     }
3747
3748   p1 = c_getstr (arg1);
3749   p2 = c_getstr (arg2);
3750
3751   /* If all arguments are constant, evaluate at compile-time.  */
3752   if (host_integerp (arg3, 1) && p1 && p2)
3753     {
3754       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3755       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3756     }
3757
3758   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3759       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3760   if (host_integerp (arg3, 1)
3761       && (tree_low_cst (arg3, 1) == 1
3762           || (tree_low_cst (arg3, 1) > 1
3763               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3764     {
3765       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3766       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3767       tree ind1 =
3768         fold (build1 (CONVERT_EXPR, integer_type_node,
3769                       build1 (INDIRECT_REF, cst_uchar_node,
3770                               fold_convert (cst_uchar_ptr_node, arg1))));
3771       tree ind2 =
3772         fold (build1 (CONVERT_EXPR, integer_type_node,
3773                       build1 (INDIRECT_REF, cst_uchar_node,
3774                               fold_convert (cst_uchar_ptr_node, arg2))));
3775       tree result = fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
3776       return expand_expr (result, target, mode, EXPAND_NORMAL);
3777     }
3778
3779   /* If c_strlen can determine an expression for one of the string
3780      lengths, and it doesn't have side effects, then emit cmpstrsi
3781      using length MIN(strlen(string)+1, arg3).  */
3782 #ifdef HAVE_cmpstrsi
3783   if (HAVE_cmpstrsi)
3784   {
3785     tree len, len1, len2;
3786     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3787     rtx result, insn;
3788     tree fndecl;
3789
3790     int arg1_align
3791       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3792     int arg2_align
3793       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3794     enum machine_mode insn_mode
3795       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3796
3797     len1 = c_strlen (arg1, 1);
3798     len2 = c_strlen (arg2, 1);
3799
3800     if (len1)
3801       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3802     if (len2)
3803       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3804
3805     /* If we don't have a constant length for the first, use the length
3806        of the second, if we know it.  We don't require a constant for
3807        this case; some cost analysis could be done if both are available
3808        but neither is constant.  For now, assume they're equally cheap,
3809        unless one has side effects.  If both strings have constant lengths,
3810        use the smaller.  */
3811
3812     if (!len1)
3813       len = len2;
3814     else if (!len2)
3815       len = len1;
3816     else if (TREE_SIDE_EFFECTS (len1))
3817       len = len2;
3818     else if (TREE_SIDE_EFFECTS (len2))
3819       len = len1;
3820     else if (TREE_CODE (len1) != INTEGER_CST)
3821       len = len2;
3822     else if (TREE_CODE (len2) != INTEGER_CST)
3823       len = len1;
3824     else if (tree_int_cst_lt (len1, len2))
3825       len = len1;
3826     else
3827       len = len2;
3828
3829     /* If both arguments have side effects, we cannot optimize.  */
3830     if (!len || TREE_SIDE_EFFECTS (len))
3831       return 0;
3832
3833     /* The actual new length parameter is MIN(len,arg3).  */
3834     len = fold (build2 (MIN_EXPR, TREE_TYPE (len), 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 }