OSDN Git Service

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