OSDN Git Service

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