OSDN Git Service

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