OSDN Git Service

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