OSDN Git Service

* config/sparc/sparc-protos.h (output_cbranch): Constify return
[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 an unordered comparison function such as
7615    __builtin_isgreater().  ARGLIST is the funtion's argument list
7616    and TYPE is the functions return type.  UNORDERED_CODE and
7617    ORDERED_CODE are comparison codes that give the opposite of
7618    the desired result.  UNORDERED_CODE is used for modes that can
7619    hold NaNs and ORDERED_CODE is used for the rest.  */
7620
7621 static tree
7622 fold_builtin_unordered_cmp (tree exp,
7623                             enum tree_code unordered_code,
7624                             enum tree_code ordered_code)
7625 {
7626   tree fndecl = get_callee_fndecl (exp);
7627   tree arglist = TREE_OPERAND (exp, 1);
7628   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7629   enum tree_code code;
7630   tree arg0, arg1;
7631
7632   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7633     {
7634       enum tree_code code0, code1;
7635       tree type0, type1;
7636       tree cmp_type = 0;
7637
7638       /* Check that we have exactly two arguments.  */
7639       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7640         {
7641           error ("too few arguments to function `%s'",
7642                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7643           return error_mark_node;
7644         }
7645       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7646         {
7647           error ("too many arguments to function `%s'",
7648                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7649           return error_mark_node;
7650         }
7651
7652       arg0 = TREE_VALUE (arglist);
7653       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7654
7655       type0 = TREE_TYPE (arg0);
7656       type1 = TREE_TYPE (arg1);
7657
7658       code0 = TREE_CODE (type0);
7659       code1 = TREE_CODE (type1);
7660
7661       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7662         /* Choose the wider of two real types.  */
7663         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7664                    ? type0 : type1;
7665       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7666         cmp_type = type0;
7667       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7668         cmp_type = type1;
7669       else
7670         {
7671           error ("non-floating-point argument to function `%s'",
7672                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7673           return error_mark_node;
7674         }
7675
7676       arg0 = fold_convert (cmp_type, arg0);
7677       arg1 = fold_convert (cmp_type, arg1);
7678     }
7679   else
7680     {
7681       arg0 = TREE_VALUE (arglist);
7682       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7683     }
7684
7685   if (unordered_code == UNORDERED_EXPR)
7686     {
7687       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7688         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7689       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7690     }
7691
7692   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7693                                                       : ordered_code;
7694   return fold (build1 (TRUTH_NOT_EXPR, type,
7695                        fold (build2 (code, type, arg0, arg1))));
7696 }
7697
7698 /* Used by constant folding to eliminate some builtin calls early.  EXP is
7699    the CALL_EXPR of a call to a builtin function.  */
7700
7701 static tree
7702 fold_builtin_1 (tree exp)
7703 {
7704   tree fndecl = get_callee_fndecl (exp);
7705   tree arglist = TREE_OPERAND (exp, 1);
7706   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7707
7708   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7709     return 0;
7710
7711   switch (DECL_FUNCTION_CODE (fndecl))
7712     {
7713     case BUILT_IN_CONSTANT_P:
7714       return fold_builtin_constant_p (arglist);
7715
7716     case BUILT_IN_EXPECT:
7717       return fold_builtin_expect (arglist);
7718
7719     case BUILT_IN_CLASSIFY_TYPE:
7720       return fold_builtin_classify_type (arglist);
7721
7722     case BUILT_IN_STRLEN:
7723       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
7724         {
7725           tree len = c_strlen (TREE_VALUE (arglist), 0);
7726           if (len)
7727             {
7728               /* Convert from the internal "sizetype" type to "size_t".  */
7729               if (size_type_node)
7730                 len = fold_convert (size_type_node, len);
7731               return len;
7732             }
7733         }
7734       break;
7735
7736     case BUILT_IN_FABS:
7737     case BUILT_IN_FABSF:
7738     case BUILT_IN_FABSL:
7739       return fold_builtin_fabs (arglist, type);
7740
7741     case BUILT_IN_ABS:
7742     case BUILT_IN_LABS:
7743     case BUILT_IN_LLABS:
7744     case BUILT_IN_IMAXABS:
7745       return fold_builtin_abs (arglist, type);
7746
7747     case BUILT_IN_CONJ:
7748     case BUILT_IN_CONJF:
7749     case BUILT_IN_CONJL:
7750       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7751         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7752       break;
7753
7754     case BUILT_IN_CREAL:
7755     case BUILT_IN_CREALF:
7756     case BUILT_IN_CREALL:
7757       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7758         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7759                                          TREE_VALUE (arglist))));
7760       break;
7761
7762     case BUILT_IN_CIMAG:
7763     case BUILT_IN_CIMAGF:
7764     case BUILT_IN_CIMAGL:
7765       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7766         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7767                                          TREE_VALUE (arglist))));
7768       break;
7769
7770     case BUILT_IN_CABS:
7771     case BUILT_IN_CABSF:
7772     case BUILT_IN_CABSL:
7773       return fold_builtin_cabs (arglist, type);
7774
7775     case BUILT_IN_SQRT:
7776     case BUILT_IN_SQRTF:
7777     case BUILT_IN_SQRTL:
7778       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7779         {
7780           enum built_in_function fcode;
7781           tree arg = TREE_VALUE (arglist);
7782
7783           /* Optimize sqrt of constant value.  */
7784           if (TREE_CODE (arg) == REAL_CST
7785               && ! TREE_CONSTANT_OVERFLOW (arg))
7786             {
7787               REAL_VALUE_TYPE r, x;
7788
7789               x = TREE_REAL_CST (arg);
7790               if (real_sqrt (&r, TYPE_MODE (type), &x)
7791                   || (!flag_trapping_math && !flag_errno_math))
7792                 return build_real (type, r);
7793             }
7794
7795           /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
7796           fcode = builtin_mathfn_code (arg);
7797           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7798             {
7799               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7800               arg = fold (build2 (MULT_EXPR, type,
7801                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
7802                                   build_real (type, dconsthalf)));
7803               arglist = build_tree_list (NULL_TREE, arg);
7804               return build_function_call_expr (expfn, arglist);
7805             }
7806
7807           /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
7808           if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
7809             {
7810               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7811               
7812               if (powfn)
7813                 {
7814                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7815                   tree tree_root;
7816                   /* The inner root was either sqrt or cbrt.  */
7817                   REAL_VALUE_TYPE dconstroot =
7818                     BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
7819                   
7820                   /* Adjust for the outer root.  */
7821                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7822                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7823                   tree_root = build_real (type, dconstroot);
7824                   arglist = tree_cons (NULL_TREE, arg0,
7825                                        build_tree_list (NULL_TREE, tree_root));
7826                   return build_function_call_expr (powfn, arglist);
7827                 }
7828             }
7829
7830           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
7831           if (flag_unsafe_math_optimizations
7832               && (fcode == BUILT_IN_POW
7833                   || fcode == BUILT_IN_POWF
7834                   || fcode == BUILT_IN_POWL))
7835             {
7836               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7837               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7838               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
7839               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
7840                                          build_real (type, dconsthalf)));
7841               arglist = tree_cons (NULL_TREE, arg0,
7842                                    build_tree_list (NULL_TREE, narg1));
7843               return build_function_call_expr (powfn, arglist);
7844             }
7845         }
7846       break;
7847
7848     case BUILT_IN_CBRT:
7849     case BUILT_IN_CBRTF:
7850     case BUILT_IN_CBRTL:
7851       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7852         {
7853           tree arg = TREE_VALUE (arglist);
7854           const enum built_in_function fcode = builtin_mathfn_code (arg);
7855
7856           /* Optimize cbrt of constant value.  */
7857           if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
7858             return arg;
7859
7860           /* Optimize cbrt(expN(x)) -> expN(x/3).  */
7861           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
7862             {
7863               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
7864               const REAL_VALUE_TYPE third_trunc =
7865                 real_value_truncate (TYPE_MODE (type), dconstthird);
7866               arg = fold (build2 (MULT_EXPR, type,
7867                                   TREE_VALUE (TREE_OPERAND (arg, 1)),
7868                                   build_real (type, third_trunc)));
7869               arglist = build_tree_list (NULL_TREE, arg);
7870               return build_function_call_expr (expfn, arglist);
7871             }
7872
7873           /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
7874           /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
7875              x is negative pow will error but cbrt won't.  */
7876           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
7877             {
7878               tree powfn = mathfn_built_in (type, BUILT_IN_POW);
7879
7880               if (powfn)
7881                 {
7882                   tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
7883                   tree tree_root;
7884                   REAL_VALUE_TYPE dconstroot = dconstthird;
7885
7886                   SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
7887                   dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
7888                   tree_root = build_real (type, dconstroot);
7889                   arglist = tree_cons (NULL_TREE, arg0,
7890                                        build_tree_list (NULL_TREE, tree_root));
7891                   return build_function_call_expr (powfn, arglist);
7892                 }
7893               
7894             }
7895         }
7896       break;
7897
7898     case BUILT_IN_SIN:
7899     case BUILT_IN_SINF:
7900     case BUILT_IN_SINL:
7901       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7902         {
7903           tree arg = TREE_VALUE (arglist);
7904
7905           /* Optimize sin(0.0) = 0.0.  */
7906           if (real_zerop (arg))
7907             return arg;
7908         }
7909       break;
7910
7911     case BUILT_IN_COS:
7912     case BUILT_IN_COSF:
7913     case BUILT_IN_COSL:
7914       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7915         {
7916           tree arg = TREE_VALUE (arglist);
7917
7918           /* Optimize cos(0.0) = 1.0.  */
7919           if (real_zerop (arg))
7920             return build_real (type, dconst1);
7921
7922           /* Optimize cos(-x) into cos(x).  */
7923           if (TREE_CODE (arg) == NEGATE_EXPR)
7924             {
7925               tree arglist = build_tree_list (NULL_TREE,
7926                                               TREE_OPERAND (arg, 0));
7927               return build_function_call_expr (fndecl, arglist);
7928             }
7929         }
7930       break;
7931
7932     case BUILT_IN_EXP:
7933     case BUILT_IN_EXPF:
7934     case BUILT_IN_EXPL:
7935       return fold_builtin_exponent (exp, &dconste);
7936
7937     case BUILT_IN_EXP2:
7938     case BUILT_IN_EXP2F:
7939     case BUILT_IN_EXP2L:
7940       return fold_builtin_exponent (exp, &dconst2);
7941
7942     case BUILT_IN_EXP10:
7943     case BUILT_IN_EXP10F:
7944     case BUILT_IN_EXP10L:
7945     case BUILT_IN_POW10:
7946     case BUILT_IN_POW10F:
7947     case BUILT_IN_POW10L:
7948       return fold_builtin_exponent (exp, &dconst10);
7949
7950     case BUILT_IN_LOG:
7951     case BUILT_IN_LOGF:
7952     case BUILT_IN_LOGL:
7953       return fold_builtin_logarithm (exp, &dconste);
7954
7955     case BUILT_IN_LOG2:
7956     case BUILT_IN_LOG2F:
7957     case BUILT_IN_LOG2L:
7958       return fold_builtin_logarithm (exp, &dconst2);
7959
7960     case BUILT_IN_LOG10:
7961     case BUILT_IN_LOG10F:
7962     case BUILT_IN_LOG10L:
7963       return fold_builtin_logarithm (exp, &dconst10);
7964
7965     case BUILT_IN_TAN:
7966     case BUILT_IN_TANF:
7967     case BUILT_IN_TANL:
7968       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7969         {
7970           enum built_in_function fcode;
7971           tree arg = TREE_VALUE (arglist);
7972
7973           /* Optimize tan(0.0) = 0.0.  */
7974           if (real_zerop (arg))
7975             return arg;
7976
7977           /* Optimize tan(atan(x)) = x.  */
7978           fcode = builtin_mathfn_code (arg);
7979           if (flag_unsafe_math_optimizations
7980               && (fcode == BUILT_IN_ATAN
7981                   || fcode == BUILT_IN_ATANF
7982                   || fcode == BUILT_IN_ATANL))
7983             return TREE_VALUE (TREE_OPERAND (arg, 1));
7984         }
7985       break;
7986
7987     case BUILT_IN_ATAN:
7988     case BUILT_IN_ATANF:
7989     case BUILT_IN_ATANL:
7990       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7991         {
7992           tree arg = TREE_VALUE (arglist);
7993
7994           /* Optimize atan(0.0) = 0.0.  */
7995           if (real_zerop (arg))
7996             return arg;
7997
7998           /* Optimize atan(1.0) = pi/4.  */
7999           if (real_onep (arg))
8000             {
8001               REAL_VALUE_TYPE cst;
8002
8003               real_convert (&cst, TYPE_MODE (type), &dconstpi);
8004               SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
8005               return build_real (type, cst);
8006             }
8007         }
8008       break;
8009
8010     case BUILT_IN_POW:
8011     case BUILT_IN_POWF:
8012     case BUILT_IN_POWL:
8013       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
8014         {
8015           enum built_in_function fcode;
8016           tree arg0 = TREE_VALUE (arglist);
8017           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
8018
8019           /* Optimize pow(1.0,y) = 1.0.  */
8020           if (real_onep (arg0))
8021             return omit_one_operand (type, build_real (type, dconst1), arg1);
8022
8023           if (TREE_CODE (arg1) == REAL_CST
8024               && ! TREE_CONSTANT_OVERFLOW (arg1))
8025             {
8026               REAL_VALUE_TYPE c;
8027               c = TREE_REAL_CST (arg1);
8028
8029               /* Optimize pow(x,0.0) = 1.0.  */
8030               if (REAL_VALUES_EQUAL (c, dconst0))
8031                 return omit_one_operand (type, build_real (type, dconst1),
8032                                          arg0);
8033
8034               /* Optimize pow(x,1.0) = x.  */
8035               if (REAL_VALUES_EQUAL (c, dconst1))
8036                 return arg0;
8037
8038               /* Optimize pow(x,-1.0) = 1.0/x.  */
8039               if (REAL_VALUES_EQUAL (c, dconstm1))
8040                 return fold (build2 (RDIV_EXPR, type,
8041                                      build_real (type, dconst1), arg0));
8042
8043               /* Optimize pow(x,0.5) = sqrt(x).  */
8044               if (flag_unsafe_math_optimizations
8045                   && REAL_VALUES_EQUAL (c, dconsthalf))
8046                 {
8047                   tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
8048
8049                   if (sqrtfn != NULL_TREE)
8050                     {
8051                       tree arglist = build_tree_list (NULL_TREE, arg0);
8052                       return build_function_call_expr (sqrtfn, arglist);
8053                     }
8054                 }
8055
8056               /* Attempt to evaluate pow at compile-time.  */
8057               if (TREE_CODE (arg0) == REAL_CST
8058                   && ! TREE_CONSTANT_OVERFLOW (arg0))
8059                 {
8060                   REAL_VALUE_TYPE cint;
8061                   HOST_WIDE_INT n;
8062
8063                   n = real_to_integer (&c);
8064                   real_from_integer (&cint, VOIDmode, n,
8065                                      n < 0 ? -1 : 0, 0);
8066                   if (real_identical (&c, &cint))
8067                     {
8068                       REAL_VALUE_TYPE x;
8069                       bool inexact;
8070
8071                       x = TREE_REAL_CST (arg0);
8072                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
8073                       if (flag_unsafe_math_optimizations || !inexact)
8074                         return build_real (type, x);
8075                     }
8076                 }
8077             }
8078
8079           /* Optimize pow(expN(x),y) = expN(x*y).  */
8080           fcode = builtin_mathfn_code (arg0);
8081           if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
8082             {
8083               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
8084               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
8085               arg = fold (build2 (MULT_EXPR, type, arg, arg1));
8086               arglist = build_tree_list (NULL_TREE, arg);
8087               return build_function_call_expr (expfn, arglist);
8088             }
8089
8090           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
8091           if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
8092             {
8093               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8094               tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
8095                                          build_real (type, dconsthalf)));
8096
8097               arglist = tree_cons (NULL_TREE, narg0,
8098                                    build_tree_list (NULL_TREE, narg1));
8099               return build_function_call_expr (fndecl, arglist);
8100             }
8101
8102           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
8103           if (flag_unsafe_math_optimizations
8104               && (fcode == BUILT_IN_POW
8105                   || fcode == BUILT_IN_POWF
8106                   || fcode == BUILT_IN_POWL))
8107             {
8108               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
8109               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
8110               tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
8111               arglist = tree_cons (NULL_TREE, arg00,
8112                                    build_tree_list (NULL_TREE, narg1));
8113               return build_function_call_expr (fndecl, arglist);
8114             }
8115         }
8116       break;
8117
8118     case BUILT_IN_INF:
8119     case BUILT_IN_INFF:
8120     case BUILT_IN_INFL:
8121       return fold_builtin_inf (type, true);
8122
8123     case BUILT_IN_HUGE_VAL:
8124     case BUILT_IN_HUGE_VALF:
8125     case BUILT_IN_HUGE_VALL:
8126       return fold_builtin_inf (type, false);
8127
8128     case BUILT_IN_NAN:
8129     case BUILT_IN_NANF:
8130     case BUILT_IN_NANL:
8131       return fold_builtin_nan (arglist, type, true);
8132
8133     case BUILT_IN_NANS:
8134     case BUILT_IN_NANSF:
8135     case BUILT_IN_NANSL:
8136       return fold_builtin_nan (arglist, type, false);
8137
8138     case BUILT_IN_FLOOR:
8139     case BUILT_IN_FLOORF:
8140     case BUILT_IN_FLOORL:
8141       return fold_builtin_floor (exp);
8142
8143     case BUILT_IN_CEIL:
8144     case BUILT_IN_CEILF:
8145     case BUILT_IN_CEILL:
8146       return fold_builtin_ceil (exp);
8147
8148     case BUILT_IN_TRUNC:
8149     case BUILT_IN_TRUNCF:
8150     case BUILT_IN_TRUNCL:
8151       return fold_builtin_trunc (exp);
8152
8153     case BUILT_IN_ROUND:
8154     case BUILT_IN_ROUNDF:
8155     case BUILT_IN_ROUNDL:
8156       return fold_builtin_round (exp);
8157
8158     case BUILT_IN_NEARBYINT:
8159     case BUILT_IN_NEARBYINTF:
8160     case BUILT_IN_NEARBYINTL:
8161     case BUILT_IN_RINT:
8162     case BUILT_IN_RINTF:
8163     case BUILT_IN_RINTL:
8164       return fold_trunc_transparent_mathfn (exp);
8165
8166     case BUILT_IN_LROUND:
8167     case BUILT_IN_LROUNDF:
8168     case BUILT_IN_LROUNDL:
8169     case BUILT_IN_LLROUND:
8170     case BUILT_IN_LLROUNDF:
8171     case BUILT_IN_LLROUNDL:
8172       return fold_builtin_lround (exp);
8173
8174     case BUILT_IN_LRINT:
8175     case BUILT_IN_LRINTF:
8176     case BUILT_IN_LRINTL:
8177     case BUILT_IN_LLRINT:
8178     case BUILT_IN_LLRINTF:
8179     case BUILT_IN_LLRINTL:
8180       return fold_fixed_mathfn (exp);
8181
8182     case BUILT_IN_FFS:
8183     case BUILT_IN_FFSL:
8184     case BUILT_IN_FFSLL:
8185     case BUILT_IN_CLZ:
8186     case BUILT_IN_CLZL:
8187     case BUILT_IN_CLZLL:
8188     case BUILT_IN_CTZ:
8189     case BUILT_IN_CTZL:
8190     case BUILT_IN_CTZLL:
8191     case BUILT_IN_POPCOUNT:
8192     case BUILT_IN_POPCOUNTL:
8193     case BUILT_IN_POPCOUNTLL:
8194     case BUILT_IN_PARITY:
8195     case BUILT_IN_PARITYL:
8196     case BUILT_IN_PARITYLL:
8197       return fold_builtin_bitop (exp);
8198
8199     case BUILT_IN_MEMCPY:
8200       return fold_builtin_memcpy (exp);
8201
8202     case BUILT_IN_MEMPCPY:
8203       return fold_builtin_mempcpy (exp);
8204
8205     case BUILT_IN_MEMMOVE:
8206       return fold_builtin_memmove (exp);
8207
8208     case BUILT_IN_STRCPY:
8209       return fold_builtin_strcpy (exp);
8210
8211     case BUILT_IN_STRNCPY:
8212       return fold_builtin_strncpy (exp);
8213
8214     case BUILT_IN_INDEX:
8215     case BUILT_IN_STRCHR:
8216       return fold_builtin_strchr (exp, false);
8217
8218     case BUILT_IN_RINDEX:
8219     case BUILT_IN_STRRCHR:
8220       return fold_builtin_strchr (exp, true);
8221
8222     case BUILT_IN_MEMCMP:
8223       return fold_builtin_memcmp (exp);
8224
8225     case BUILT_IN_STRCMP:
8226       return fold_builtin_strcmp (exp);
8227
8228     case BUILT_IN_STRNCMP:
8229       return fold_builtin_strncmp (exp);
8230
8231     case BUILT_IN_SIGNBIT:
8232     case BUILT_IN_SIGNBITF:
8233     case BUILT_IN_SIGNBITL:
8234       return fold_builtin_signbit (exp);
8235
8236     case BUILT_IN_ISASCII:
8237       return fold_builtin_isascii (arglist);
8238
8239     case BUILT_IN_TOASCII:
8240       return fold_builtin_toascii (arglist);
8241
8242     case BUILT_IN_ISDIGIT:
8243       return fold_builtin_isdigit (arglist);
8244
8245     case BUILT_IN_COPYSIGN:
8246     case BUILT_IN_COPYSIGNF:
8247     case BUILT_IN_COPYSIGNL:
8248       return fold_builtin_copysign (arglist, type);
8249
8250     case BUILT_IN_ISGREATER:
8251       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
8252     case BUILT_IN_ISGREATEREQUAL:
8253       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
8254     case BUILT_IN_ISLESS:
8255       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8256     case BUILT_IN_ISLESSEQUAL:
8257       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8258     case BUILT_IN_ISLESSGREATER:
8259       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8260     case BUILT_IN_ISUNORDERED:
8261       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8262
8263     default:
8264       break;
8265     }
8266
8267   return 0;
8268 }
8269
8270 /* A wrapper function for builtin folding that prevents warnings for
8271    "statement without effect" and the like, caused by removing the 
8272    call node earlier than the warning is generated.  */
8273
8274 tree
8275 fold_builtin (tree exp)
8276 {
8277   exp = fold_builtin_1 (exp);
8278   if (exp)
8279     {
8280       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8281       if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
8282         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8283       TREE_NO_WARNING (exp) = 1;
8284     }
8285   return exp;
8286 }
8287
8288 /* Conveniently construct a function call expression.  */
8289
8290 tree
8291 build_function_call_expr (tree fn, tree arglist)
8292 {
8293   tree call_expr;
8294
8295   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8296   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8297                       call_expr, arglist, NULL_TREE);
8298   return fold (call_expr);
8299 }
8300
8301 /* This function validates the types of a function call argument list
8302    represented as a tree chain of parameters against a specified list
8303    of tree_codes.  If the last specifier is a 0, that represents an
8304    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8305
8306 static int
8307 validate_arglist (tree arglist, ...)
8308 {
8309   enum tree_code code;
8310   int res = 0;
8311   va_list ap;
8312
8313   va_start (ap, arglist);
8314
8315   do
8316     {
8317       code = va_arg (ap, enum tree_code);
8318       switch (code)
8319         {
8320         case 0:
8321           /* This signifies an ellipses, any further arguments are all ok.  */
8322           res = 1;
8323           goto end;
8324         case VOID_TYPE:
8325           /* This signifies an endlink, if no arguments remain, return
8326              true, otherwise return false.  */
8327           res = arglist == 0;
8328           goto end;
8329         default:
8330           /* If no parameters remain or the parameter's code does not
8331              match the specified code, return false.  Otherwise continue
8332              checking any remaining arguments.  */
8333           if (arglist == 0
8334               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8335             goto end;
8336           break;
8337         }
8338       arglist = TREE_CHAIN (arglist);
8339     }
8340   while (1);
8341
8342   /* We need gotos here since we can only have one VA_CLOSE in a
8343      function.  */
8344  end: ;
8345   va_end (ap);
8346
8347   return res;
8348 }
8349
8350 /* Default target-specific builtin expander that does nothing.  */
8351
8352 rtx
8353 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8354                         rtx target ATTRIBUTE_UNUSED,
8355                         rtx subtarget ATTRIBUTE_UNUSED,
8356                         enum machine_mode mode ATTRIBUTE_UNUSED,
8357                         int ignore ATTRIBUTE_UNUSED)
8358 {
8359   return NULL_RTX;
8360 }
8361
8362 /* Returns true is EXP represents data that would potentially reside
8363    in a readonly section.  */
8364
8365 static bool
8366 readonly_data_expr (tree exp)
8367 {
8368   STRIP_NOPS (exp);
8369
8370   if (TREE_CODE (exp) != ADDR_EXPR)
8371     return false;
8372
8373   exp = get_base_address (TREE_OPERAND (exp, 0));
8374   if (!exp)
8375     return false;
8376
8377   /* Make sure we call decl_readonly_section only for trees it
8378      can handle (since it returns true for everything it doesn't
8379      understand).  */
8380   if (TREE_CODE (exp) == STRING_CST 
8381       || TREE_CODE (exp) == CONSTRUCTOR
8382       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8383     return decl_readonly_section (exp, 0);
8384   else
8385     return false;
8386 }
8387
8388 /* Front-end to the simplify_builtin_XXX routines.
8389
8390    EXP is a call to a builtin function.  If possible try to simplify
8391    that into a constant, expression or call to a more efficient
8392    builtin function.
8393
8394    If IGNORE is nonzero, then the result of this builtin function
8395    call is ignored.
8396
8397    If simplification is possible, return the simplified tree, otherwise
8398    return NULL_TREE.  */
8399
8400 tree
8401 simplify_builtin (tree exp, int ignore)
8402 {
8403   tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8404   tree arglist = TREE_OPERAND (exp, 1);
8405   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
8406   tree val;
8407
8408   switch (fcode)
8409     {
8410     case BUILT_IN_FPUTS:
8411       val = simplify_builtin_fputs (arglist, ignore, 0, NULL_TREE);
8412       break;
8413     case BUILT_IN_FPUTS_UNLOCKED:
8414       val = simplify_builtin_fputs (arglist, ignore, 1, NULL_TREE);
8415       break;
8416     case BUILT_IN_STRSTR:
8417       val = simplify_builtin_strstr (arglist);
8418       break;
8419     case BUILT_IN_STRCAT:
8420       val = simplify_builtin_strcat (arglist);
8421       break;
8422     case BUILT_IN_STRNCAT:
8423       val = simplify_builtin_strncat (arglist);
8424       break;
8425     case BUILT_IN_STRSPN:
8426       val = simplify_builtin_strspn (arglist);
8427       break;
8428     case BUILT_IN_STRCSPN:
8429       val = simplify_builtin_strcspn (arglist);
8430       break;
8431     case BUILT_IN_STRCHR:
8432     case BUILT_IN_INDEX:
8433       val = simplify_builtin_strchr (arglist);
8434       break;
8435     case BUILT_IN_STRRCHR:
8436     case BUILT_IN_RINDEX:
8437       val = simplify_builtin_strrchr (arglist);
8438       break;
8439     case BUILT_IN_STRCPY:
8440       val = simplify_builtin_strcpy (arglist, NULL_TREE);
8441       break;
8442     case BUILT_IN_STRNCPY:
8443       val = simplify_builtin_strncpy (arglist, NULL_TREE);
8444       break;
8445     case BUILT_IN_STRCMP:
8446       val = simplify_builtin_strcmp (arglist);
8447       break;
8448     case BUILT_IN_STRNCMP:
8449       val = simplify_builtin_strncmp (arglist);
8450       break;
8451     case BUILT_IN_STRPBRK:
8452       val = simplify_builtin_strpbrk (arglist);
8453       break;
8454     case BUILT_IN_BCMP:
8455     case BUILT_IN_MEMCMP:
8456       val = simplify_builtin_memcmp (arglist);
8457       break;
8458     case BUILT_IN_VA_START:
8459       simplify_builtin_va_start (arglist);
8460       val = NULL_TREE;
8461       break;
8462     case BUILT_IN_SPRINTF:
8463       val = simplify_builtin_sprintf (arglist, ignore);
8464       break;
8465     case BUILT_IN_CONSTANT_P:
8466       val = fold_builtin_constant_p (arglist);
8467       /* Gimplification will pull the CALL_EXPR for the builtin out of
8468          an if condition.  When not optimizing, we'll not CSE it back.
8469          To avoid link error types of regressions, return false now.  */
8470       if (!val && !optimize)
8471         val = integer_zero_node;
8472       break;
8473     default:
8474       val = NULL_TREE;
8475       break;
8476     }
8477
8478   if (val)
8479     val = fold_convert (TREE_TYPE (exp), val);
8480   return val;
8481 }
8482
8483 /* Simplify a call to the strstr builtin.
8484
8485    Return 0 if no simplification was possible, otherwise return the
8486    simplified form of the call as a tree.
8487
8488    The simplified form may be a constant or other expression which
8489    computes the same value, but in a more efficient manner (including
8490    calls to other builtin functions).
8491
8492    The call may contain arguments which need to be evaluated, but
8493    which are not useful to determine the result of the call.  In
8494    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8495    COMPOUND_EXPR will be an argument which must be evaluated.
8496    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8497    COMPOUND_EXPR in the chain will contain the tree for the simplified
8498    form of the builtin function call.  */
8499
8500 static tree
8501 simplify_builtin_strstr (tree arglist)
8502 {
8503   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8504     return 0;
8505   else
8506     {
8507       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8508       tree fn;
8509       const char *p1, *p2;
8510
8511       p2 = c_getstr (s2);
8512       if (p2 == NULL)
8513         return 0;
8514
8515       p1 = c_getstr (s1);
8516       if (p1 != NULL)
8517         {
8518           const char *r = strstr (p1, p2);
8519
8520           if (r == NULL)
8521             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8522
8523           /* Return an offset into the constant string argument.  */
8524           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8525                                s1, fold_convert (TREE_TYPE (s1),
8526                                                  ssize_int (r - p1))));
8527         }
8528
8529       if (p2[0] == '\0')
8530         return s1;
8531
8532       if (p2[1] != '\0')
8533         return 0;
8534
8535       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8536       if (!fn)
8537         return 0;
8538
8539       /* New argument list transforming strstr(s1, s2) to
8540          strchr(s1, s2[0]).  */
8541       arglist = build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8542       arglist = tree_cons (NULL_TREE, s1, arglist);
8543       return build_function_call_expr (fn, arglist);
8544     }
8545 }
8546
8547 /* Simplify a call to the strstr builtin.
8548
8549    Return 0 if no simplification was possible, otherwise return the
8550    simplified form of the call as a tree.
8551
8552    The simplified form may be a constant or other expression which
8553    computes the same value, but in a more efficient manner (including
8554    calls to other builtin functions).
8555
8556    The call may contain arguments which need to be evaluated, but
8557    which are not useful to determine the result of the call.  In
8558    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8559    COMPOUND_EXPR will be an argument which must be evaluated.
8560    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8561    COMPOUND_EXPR in the chain will contain the tree for the simplified
8562    form of the builtin function call.  */
8563
8564 static tree
8565 simplify_builtin_strchr (tree arglist)
8566 {
8567   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8568     return 0;
8569   else
8570     {
8571       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8572       const char *p1;
8573
8574       if (TREE_CODE (s2) != INTEGER_CST)
8575         return 0;
8576
8577       p1 = c_getstr (s1);
8578       if (p1 != NULL)
8579         {
8580           char c;
8581           const char *r;
8582
8583           if (target_char_cast (s2, &c))
8584             return 0;
8585
8586           r = strchr (p1, c);
8587
8588           if (r == NULL)
8589             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8590
8591           /* Return an offset into the constant string argument.  */
8592           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8593                                s1, fold_convert (TREE_TYPE (s1),
8594                                                  ssize_int (r - p1))));
8595         }
8596
8597       /* FIXME: Should use here strchrM optab so that ports can optimize
8598          this.  */
8599       return 0;
8600     }
8601 }
8602
8603 /* Simplify a call to the strrchr builtin.
8604
8605    Return 0 if no simplification was possible, otherwise return the
8606    simplified form of the call as a tree.
8607
8608    The simplified form may be a constant or other expression which
8609    computes the same value, but in a more efficient manner (including
8610    calls to other builtin functions).
8611
8612    The call may contain arguments which need to be evaluated, but
8613    which are not useful to determine the result of the call.  In
8614    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8615    COMPOUND_EXPR will be an argument which must be evaluated.
8616    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8617    COMPOUND_EXPR in the chain will contain the tree for the simplified
8618    form of the builtin function call.  */
8619
8620 static tree
8621 simplify_builtin_strrchr (tree arglist)
8622 {
8623   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8624     return 0;
8625   else
8626     {
8627       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8628       tree fn;
8629       const char *p1;
8630
8631       if (TREE_CODE (s2) != INTEGER_CST)
8632         return 0;
8633
8634       p1 = c_getstr (s1);
8635       if (p1 != NULL)
8636         {
8637           char c;
8638           const char *r;
8639
8640           if (target_char_cast (s2, &c))
8641             return 0;
8642
8643           r = strrchr (p1, c);
8644
8645           if (r == NULL)
8646             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8647
8648           /* Return an offset into the constant string argument.  */
8649           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8650                                s1, fold_convert (TREE_TYPE (s1),
8651                                                  ssize_int (r - p1))));
8652         }
8653
8654       if (! integer_zerop (s2))
8655         return 0;
8656
8657       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8658       if (!fn)
8659         return 0;
8660
8661       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8662       return build_function_call_expr (fn, arglist);
8663     }
8664 }
8665
8666 /* Simplify a call to the strpbrk builtin.
8667
8668    Return 0 if no simplification was possible, otherwise return the
8669    simplified form of the call as a tree.
8670
8671    The simplified form may be a constant or other expression which
8672    computes the same value, but in a more efficient manner (including
8673    calls to other builtin functions).
8674
8675    The call may contain arguments which need to be evaluated, but
8676    which are not useful to determine the result of the call.  In
8677    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8678    COMPOUND_EXPR will be an argument which must be evaluated.
8679    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8680    COMPOUND_EXPR in the chain will contain the tree for the simplified
8681    form of the builtin function call.  */
8682
8683 static tree
8684 simplify_builtin_strpbrk (tree arglist)
8685 {
8686   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8687     return 0;
8688   else
8689     {
8690       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8691       tree fn;
8692       const char *p1, *p2;
8693
8694       p2 = c_getstr (s2);
8695       if (p2 == NULL)
8696         return 0;
8697
8698       p1 = c_getstr (s1);
8699       if (p1 != NULL)
8700         {
8701           const char *r = strpbrk (p1, p2);
8702
8703           if (r == NULL)
8704             return fold_convert (TREE_TYPE (s1), integer_zero_node);
8705
8706           /* Return an offset into the constant string argument.  */
8707           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8708                                s1, fold_convert (TREE_TYPE (s1),
8709                                                  ssize_int (r - p1))));
8710         }
8711
8712       if (p2[0] == '\0')
8713         /* strpbrk(x, "") == NULL.
8714            Evaluate and ignore s1 in case it had side-effects.  */
8715         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8716
8717       if (p2[1] != '\0')
8718         return 0;  /* Really call strpbrk.  */
8719
8720       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8721       if (!fn)
8722         return 0;
8723
8724       /* New argument list transforming strpbrk(s1, s2) to
8725          strchr(s1, s2[0]).  */
8726       arglist =
8727         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
8728       arglist = tree_cons (NULL_TREE, s1, arglist);
8729       return build_function_call_expr (fn, arglist);
8730     }
8731 }
8732
8733 /* Simplify a call to the strcpy builtin.
8734
8735    Return 0 if no simplification was possible, otherwise return the
8736    simplified form of the call as a tree.
8737
8738    The simplified form may be a constant or other expression which
8739    computes the same value, but in a more efficient manner (including
8740    calls to other builtin functions).
8741
8742    The call may contain arguments which need to be evaluated, but
8743    which are not useful to determine the result of the call.  In
8744    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8745    COMPOUND_EXPR will be an argument which must be evaluated.
8746    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8747    COMPOUND_EXPR in the chain will contain the tree for the simplified
8748    form of the builtin function call.  */
8749
8750 tree
8751 simplify_builtin_strcpy (tree arglist, tree len)
8752 {
8753   tree fn, src, dst;
8754
8755   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8756     return 0;
8757
8758   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8759   if (!fn)
8760     return 0;
8761
8762   src = TREE_VALUE (TREE_CHAIN (arglist));
8763   dst = TREE_VALUE (arglist);
8764
8765   if (!len)
8766     {
8767       len = c_strlen (src, 1);
8768       if (!len || TREE_SIDE_EFFECTS (len))
8769         return 0;
8770     }
8771
8772   len = size_binop (PLUS_EXPR, len, ssize_int (1));
8773   arglist = build_tree_list (NULL_TREE, len);
8774   arglist = tree_cons (NULL_TREE, src, arglist);
8775   arglist = tree_cons (NULL_TREE, dst, arglist);
8776   return build_function_call_expr (fn, arglist);
8777 }
8778
8779 /* Simplify a call to the strncpy builtin.
8780
8781    Return 0 if no simplification was possible, otherwise return the
8782    simplified form of the call as a tree.
8783
8784    The simplified form may be a constant or other expression which
8785    computes the same value, but in a more efficient manner (including
8786    calls to other builtin functions).
8787
8788    The call may contain arguments which need to be evaluated, but
8789    which are not useful to determine the result of the call.  In
8790    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8791    COMPOUND_EXPR will be an argument which must be evaluated.
8792    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8793    COMPOUND_EXPR in the chain will contain the tree for the simplified
8794    form of the builtin function call.  */
8795
8796 tree
8797 simplify_builtin_strncpy (tree arglist, tree slen)
8798 {
8799   if (!validate_arglist (arglist,
8800                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8801     return 0;
8802   else
8803     {
8804       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8805       tree fn;
8806
8807       /* We must be passed a constant len parameter.  */
8808       if (TREE_CODE (len) != INTEGER_CST)
8809         return 0;
8810
8811       /* If the len parameter is zero, return the dst parameter.  */
8812       if (integer_zerop (len))
8813         /* Evaluate and ignore the src argument in case it has
8814            side-effects and return the dst parameter.  */
8815         return omit_one_operand (TREE_TYPE (TREE_VALUE (arglist)),
8816                                  TREE_VALUE (arglist),
8817                                  TREE_VALUE (TREE_CHAIN (arglist)));
8818
8819       if (!slen)
8820         slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 0);
8821
8822       /* Now, we must be passed a constant src ptr parameter.  */
8823       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
8824         return 0;
8825
8826       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
8827
8828       /* We do not support simplification of this case, though we do
8829          support it when expanding trees into RTL.  */
8830       /* FIXME: generate a call to __builtin_memset.  */
8831       if (tree_int_cst_lt (slen, len))
8832         return 0;
8833
8834       /* OK transform into builtin memcpy.  */
8835       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
8836       if (!fn)
8837         return 0;
8838       return build_function_call_expr (fn, arglist);
8839     }
8840 }
8841
8842 /* Simplify a call to the memcmp builtin.
8843
8844    Return 0 if no simplification was possible, otherwise return the
8845    simplified form of the call as a tree.
8846
8847    The simplified form may be a constant or other expression which
8848    computes the same value, but in a more efficient manner (including
8849    calls to other builtin functions).
8850
8851    The call may contain arguments which need to be evaluated, but
8852    which are not useful to determine the result of the call.  In
8853    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8854    COMPOUND_EXPR will be an argument which must be evaluated.
8855    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8856    COMPOUND_EXPR in the chain will contain the tree for the simplified
8857    form of the builtin function call.  */
8858
8859 static tree
8860 simplify_builtin_memcmp (tree arglist)
8861 {
8862   tree arg1, arg2, len;
8863   const char *p1, *p2;
8864
8865   if (!validate_arglist (arglist,
8866                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8867     return 0;
8868
8869   arg1 = TREE_VALUE (arglist);
8870   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8871   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8872
8873   /* If the len parameter is zero, return zero.  */
8874   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
8875     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
8876     return omit_two_operands (integer_type_node, integer_zero_node,
8877                               arg1, arg2);
8878
8879   p1 = c_getstr (arg1);
8880   p2 = c_getstr (arg2);
8881
8882   /* If all arguments are constant, and the value of len is not greater
8883      than the lengths of arg1 and arg2, evaluate at compile-time.  */
8884   if (host_integerp (len, 1) && p1 && p2
8885       && compare_tree_int (len, strlen (p1) + 1) <= 0
8886       && compare_tree_int (len, strlen (p2) + 1) <= 0)
8887     {
8888       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
8889
8890       return (r < 0
8891               ? integer_minus_one_node
8892               : (r > 0 ? integer_one_node : integer_zero_node));
8893     }
8894
8895   /* If len parameter is one, return an expression corresponding to
8896      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8897   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
8898     {
8899       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8900       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8901       tree ind1 =
8902       fold (build1 (CONVERT_EXPR, integer_type_node,
8903                     build1 (INDIRECT_REF, cst_uchar_node,
8904                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
8905       tree ind2 =
8906       fold (build1 (CONVERT_EXPR, integer_type_node,
8907                     build1 (INDIRECT_REF, cst_uchar_node,
8908                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
8909       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
8910     }
8911
8912   return 0;
8913 }
8914
8915 /* Simplify a call to the strcmp builtin.
8916
8917    Return 0 if no simplification was possible, otherwise return the
8918    simplified form of the call as a tree.
8919
8920    The simplified form may be a constant or other expression which
8921    computes the same value, but in a more efficient manner (including
8922    calls to other builtin functions).
8923
8924    The call may contain arguments which need to be evaluated, but
8925    which are not useful to determine the result of the call.  In
8926    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8927    COMPOUND_EXPR will be an argument which must be evaluated.
8928    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8929    COMPOUND_EXPR in the chain will contain the tree for the simplified
8930    form of the builtin function call.  */
8931
8932 static tree
8933 simplify_builtin_strcmp (tree arglist)
8934 {
8935   tree arg1, arg2;
8936   const char *p1, *p2;
8937
8938   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8939     return 0;
8940
8941   arg1 = TREE_VALUE (arglist);
8942   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
8943
8944   /* If both arguments are equal (and not volatile), return zero.  */
8945   if (operand_equal_p (arg1, arg2, 0))
8946     return integer_zero_node;
8947
8948   p1 = c_getstr (arg1);
8949   p2 = c_getstr (arg2);
8950
8951   if (p1 && p2)
8952     {
8953       const int i = strcmp (p1, p2);
8954       return (i < 0
8955               ? integer_minus_one_node
8956               : (i > 0 ? integer_one_node : integer_zero_node));
8957     }
8958
8959   /* If either arg is "", return an expression corresponding to
8960      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
8961   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8962     {
8963       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
8964       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
8965       tree ind1 =
8966         fold (build1 (CONVERT_EXPR, integer_type_node,
8967                       build1 (INDIRECT_REF, cst_uchar_node,
8968                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
8969       tree ind2 =
8970         fold (build1 (CONVERT_EXPR, integer_type_node,
8971                       build1 (INDIRECT_REF, cst_uchar_node,
8972                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
8973       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
8974     }
8975
8976   return 0;
8977 }
8978
8979 /* Simplify a call to the strncmp builtin.
8980
8981    Return 0 if no simplification was possible, otherwise return the
8982    simplified form of the call as a tree.
8983
8984    The simplified form may be a constant or other expression which
8985    computes the same value, but in a more efficient manner (including
8986    calls to other builtin functions).
8987
8988    The call may contain arguments which need to be evaluated, but
8989    which are not useful to determine the result of the call.  In
8990    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8991    COMPOUND_EXPR will be an argument which must be evaluated.
8992    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8993    COMPOUND_EXPR in the chain will contain the tree for the simplified
8994    form of the builtin function call.  */
8995
8996 static tree
8997 simplify_builtin_strncmp (tree arglist)
8998 {
8999   tree arg1, arg2, arg3;
9000   const char *p1, *p2;
9001
9002   if (!validate_arglist (arglist,
9003                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9004     return 0;
9005
9006   arg1 = TREE_VALUE (arglist);
9007   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
9008   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9009
9010   /* If the len parameter is zero, return zero.  */
9011   if (integer_zerop (arg3))
9012     /* Evaluate and ignore arg1 and arg2 in case they have side-effects.  */
9013     return omit_two_operands (integer_type_node, integer_zero_node,
9014                               arg1, arg2);
9015
9016   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
9017   if (operand_equal_p (arg1, arg2, 0))
9018     /* Evaluate and ignore arg3 in case it has side-effects.  */
9019     return omit_one_operand (integer_type_node, integer_zero_node, arg3);
9020
9021   p1 = c_getstr (arg1);
9022   p2 = c_getstr (arg2);
9023
9024   /* If all arguments are constant, evaluate at compile-time.  */
9025   if (host_integerp (arg3, 1) && p1 && p2)
9026     {
9027       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
9028       return (r < 0
9029               ? integer_minus_one_node
9030               : (r > 0 ? integer_one_node : integer_zero_node));
9031     }
9032
9033   /* If len == 1 or (either string parameter is "" and (len >= 1)),
9034       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
9035   if (host_integerp (arg3, 1)
9036       && (tree_low_cst (arg3, 1) == 1
9037           || (tree_low_cst (arg3, 1) > 1
9038               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
9039     {
9040       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
9041       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
9042       tree ind1 =
9043         fold (build1 (CONVERT_EXPR, integer_type_node,
9044                       build1 (INDIRECT_REF, cst_uchar_node,
9045                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
9046       tree ind2 =
9047         fold (build1 (CONVERT_EXPR, integer_type_node,
9048                       build1 (INDIRECT_REF, cst_uchar_node,
9049                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
9050       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
9051     }
9052
9053   return 0;
9054 }
9055
9056 /* Simplify a call to the strcat builtin.
9057
9058    Return 0 if no simplification was possible, otherwise return the
9059    simplified form of the call as a tree.
9060
9061    The simplified form may be a constant or other expression which
9062    computes the same value, but in a more efficient manner (including
9063    calls to other builtin functions).
9064
9065    The call may contain arguments which need to be evaluated, but
9066    which are not useful to determine the result of the call.  In
9067    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9068    COMPOUND_EXPR will be an argument which must be evaluated.
9069    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9070    COMPOUND_EXPR in the chain will contain the tree for the simplified
9071    form of the builtin function call.  */
9072
9073 static tree
9074 simplify_builtin_strcat (tree arglist)
9075 {
9076   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9077     return 0;
9078   else
9079     {
9080       tree dst = TREE_VALUE (arglist),
9081         src = TREE_VALUE (TREE_CHAIN (arglist));
9082       const char *p = c_getstr (src);
9083
9084       /* If the string length is zero, return the dst parameter.  */
9085       if (p && *p == '\0')
9086         return dst;
9087
9088       return 0;
9089     }
9090 }
9091
9092 /* Simplify a call to the strncat builtin.
9093
9094    Return 0 if no simplification was possible, otherwise return the
9095    simplified form of the call as a tree.
9096
9097    The simplified form may be a constant or other expression which
9098    computes the same value, but in a more efficient manner (including
9099    calls to other builtin functions).
9100
9101    The call may contain arguments which need to be evaluated, but
9102    which are not useful to determine the result of the call.  In
9103    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9104    COMPOUND_EXPR will be an argument which must be evaluated.
9105    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9106    COMPOUND_EXPR in the chain will contain the tree for the simplified
9107    form of the builtin function call.  */
9108
9109 static tree
9110 simplify_builtin_strncat (tree arglist)
9111 {
9112   if (!validate_arglist (arglist,
9113                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
9114     return 0;
9115   else
9116     {
9117       tree dst = TREE_VALUE (arglist);
9118       tree src = TREE_VALUE (TREE_CHAIN (arglist));
9119       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9120       const char *p = c_getstr (src);
9121
9122       /* If the requested length is zero, or the src parameter string
9123           length is zero, return the dst parameter.  */
9124       if (integer_zerop (len) || (p && *p == '\0'))
9125         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
9126
9127       /* If the requested len is greater than or equal to the string
9128          length, call strcat.  */
9129       if (TREE_CODE (len) == INTEGER_CST && p
9130           && compare_tree_int (len, strlen (p)) >= 0)
9131         {
9132           tree newarglist
9133             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
9134           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
9135
9136           /* If the replacement _DECL isn't initialized, don't do the
9137              transformation.  */
9138           if (!fn)
9139             return 0;
9140
9141           return build_function_call_expr (fn, newarglist);
9142         }
9143       return 0;
9144     }
9145 }
9146
9147 /* Simplify a call to the strspn builtin.
9148
9149    Return 0 if no simplification was possible, otherwise return the
9150    simplified form of the call as a tree.
9151
9152    The simplified form may be a constant or other expression which
9153    computes the same value, but in a more efficient manner (including
9154    calls to other builtin functions).
9155
9156    The call may contain arguments which need to be evaluated, but
9157    which are not useful to determine the result of the call.  In
9158    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9159    COMPOUND_EXPR will be an argument which must be evaluated.
9160    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9161    COMPOUND_EXPR in the chain will contain the tree for the simplified
9162    form of the builtin function call.  */
9163
9164 static tree
9165 simplify_builtin_strspn (tree arglist)
9166 {
9167   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9168     return 0;
9169   else
9170     {
9171       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9172       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9173
9174       /* If both arguments are constants, evaluate at compile-time.  */
9175       if (p1 && p2)
9176         {
9177           const size_t r = strspn (p1, p2);
9178           return size_int (r);
9179         }
9180
9181       /* If either argument is "", return 0.  */
9182       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
9183         /* Evaluate and ignore both arguments in case either one has
9184            side-effects.  */
9185         return omit_two_operands (integer_type_node, integer_zero_node,
9186                                   s1, s2);
9187       return 0;
9188     }
9189 }
9190
9191 /* Simplify a call to the strcspn builtin.
9192
9193    Return 0 if no simplification was possible, otherwise return the
9194    simplified form of the call as a tree.
9195
9196    The simplified form may be a constant or other expression which
9197    computes the same value, but in a more efficient manner (including
9198    calls to other builtin functions).
9199
9200    The call may contain arguments which need to be evaluated, but
9201    which are not useful to determine the result of the call.  In
9202    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9203    COMPOUND_EXPR will be an argument which must be evaluated.
9204    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9205    COMPOUND_EXPR in the chain will contain the tree for the simplified
9206    form of the builtin function call.  */
9207
9208 static tree
9209 simplify_builtin_strcspn (tree arglist)
9210 {
9211   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9212     return 0;
9213   else
9214     {
9215       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
9216       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
9217
9218       /* If both arguments are constants, evaluate at compile-time.  */
9219       if (p1 && p2)
9220         {
9221           const size_t r = strcspn (p1, p2);
9222           return size_int (r);
9223         }
9224
9225       /* If the first argument is "", return 0.  */
9226       if (p1 && *p1 == '\0')
9227         {
9228           /* Evaluate and ignore argument s2 in case it has
9229              side-effects.  */
9230           return omit_one_operand (integer_type_node,
9231                                    integer_zero_node, s2);
9232         }
9233
9234       /* If the second argument is "", return __builtin_strlen(s1).  */
9235       if (p2 && *p2 == '\0')
9236         {
9237           tree newarglist = build_tree_list (NULL_TREE, s1),
9238             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
9239
9240           /* If the replacement _DECL isn't initialized, don't do the
9241              transformation.  */
9242           if (!fn)
9243             return 0;
9244
9245           return build_function_call_expr (fn, newarglist);
9246         }
9247       return 0;
9248     }
9249 }
9250
9251 /* Simplify a call to the fputs builtin.
9252
9253    Return 0 if no simplification was possible, otherwise return the
9254    simplified form of the call as a tree.
9255
9256    The simplified form may be a constant or other expression which
9257    computes the same value, but in a more efficient manner (including
9258    calls to other builtin functions).
9259
9260    The call may contain arguments which need to be evaluated, but
9261    which are not useful to determine the result of the call.  In
9262    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
9263    COMPOUND_EXPR will be an argument which must be evaluated.
9264    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
9265    COMPOUND_EXPR in the chain will contain the tree for the simplified
9266    form of the builtin function call.
9267
9268    If KNOWN_LEN is non-NULL, it represents the known length of the string.
9269    This is determined by SSA-CCP in cases where the string itself is not
9270    known to be constant but its length is always the same constant.  */
9271
9272 tree
9273 simplify_builtin_fputs (tree arglist, int ignore, int unlocked, tree known_len)
9274 {
9275   tree len, fn;
9276   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
9277     : implicit_built_in_decls[BUILT_IN_FPUTC];
9278   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
9279     : implicit_built_in_decls[BUILT_IN_FWRITE];
9280
9281   /* If the return value is used, or the replacement _DECL isn't
9282      initialized, don't do the transformation.  */
9283   if (!ignore || !fn_fputc || !fn_fwrite)
9284     return 0;
9285
9286   /* Verify the arguments in the original call.  */
9287   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
9288     return 0;
9289
9290   len = (known_len) ? known_len : c_strlen (TREE_VALUE (arglist), 0);
9291
9292   /* Get the length of the string passed to fputs.  If the length
9293      can't be determined, punt.  */
9294   if (!len
9295       || TREE_CODE (len) != INTEGER_CST)
9296     return 0;
9297
9298   switch (compare_tree_int (len, 1))
9299     {
9300     case -1: /* length is 0, delete the call entirely .  */
9301       return omit_one_operand (integer_type_node, integer_zero_node,
9302                                TREE_VALUE (TREE_CHAIN (arglist)));
9303
9304     case 0: /* length is 1, call fputc.  */
9305       {
9306         const char *p = c_getstr (TREE_VALUE (arglist));
9307
9308         if (p != NULL)
9309           {
9310             /* New argument list transforming fputs(string, stream) to
9311                fputc(string[0], stream).  */
9312             arglist =
9313               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9314             arglist =
9315               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
9316             fn = fn_fputc;
9317             break;
9318           }
9319       }
9320       /* FALLTHROUGH */
9321     case 1: /* length is greater than 1, call fwrite.  */
9322       {
9323         tree string_arg;
9324
9325         /* If optimizing for size keep fputs.  */
9326         if (optimize_size)
9327           return 0;
9328         string_arg = TREE_VALUE (arglist);
9329         /* New argument list transforming fputs(string, stream) to
9330            fwrite(string, 1, len, stream).  */
9331         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
9332         arglist = tree_cons (NULL_TREE, len, arglist);
9333         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
9334         arglist = tree_cons (NULL_TREE, string_arg, arglist);
9335         fn = fn_fwrite;
9336         break;
9337       }
9338     default:
9339       abort ();
9340     }
9341
9342   return build_function_call_expr (fn, arglist);
9343 }
9344
9345 static void
9346 simplify_builtin_va_start (tree arglist)
9347 {
9348   tree chain = TREE_CHAIN (arglist);
9349
9350   if (TREE_CHAIN (chain))
9351     error ("too many arguments to function `va_start'");
9352
9353   simplify_builtin_next_arg (chain);
9354 }
9355
9356 static void
9357 simplify_builtin_next_arg (tree arglist)
9358 {
9359   tree fntype = TREE_TYPE (current_function_decl);
9360
9361   if (TYPE_ARG_TYPES (fntype) == 0
9362       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
9363           == void_type_node))
9364     error ("`va_start' used in function with fixed args");
9365   else if (arglist)
9366     {
9367       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
9368       tree arg = TREE_VALUE (arglist);
9369
9370       /* Strip off all nops for the sake of the comparison.  This
9371          is not quite the same as STRIP_NOPS.  It does more.
9372          We must also strip off INDIRECT_EXPR for C++ reference
9373          parameters.  */
9374       while (TREE_CODE (arg) == NOP_EXPR
9375              || TREE_CODE (arg) == CONVERT_EXPR
9376              || TREE_CODE (arg) == NON_LVALUE_EXPR
9377              || TREE_CODE (arg) == INDIRECT_REF)
9378         arg = TREE_OPERAND (arg, 0);
9379       if (arg != last_parm)
9380         warning ("second parameter of `va_start' not last named argument");
9381       TREE_VALUE (arglist) = arg;
9382     }
9383   else
9384     /* Evidently an out of date version of <stdarg.h>; can't validate
9385        va_start's second argument, but can still work as intended.  */
9386     warning ("`__builtin_next_arg' called without an argument");
9387 }
9388
9389
9390 /* Simplify a call to the sprintf builtin.
9391
9392    Return 0 if no simplification was possible, otherwise return the
9393    simplified form of the call as a tree.  If IGNORED is true, it means that
9394    the caller does not use the returned value of the function.  */
9395
9396 static tree
9397 simplify_builtin_sprintf (tree arglist, int ignored)
9398 {
9399   tree call, retval, dest, fmt;
9400   const char *fmt_str = NULL;
9401
9402   /* Verify the required arguments in the original call.  We deal with two
9403      types of sprintf() calls: 'sprintf (str, fmt)' and
9404      'sprintf (dest, "%s", orig)'.  */
9405   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
9406       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
9407                             VOID_TYPE))
9408     return NULL_TREE;
9409
9410   /* Get the destination string and the format specifier.  */
9411   dest = TREE_VALUE (arglist);
9412   fmt = TREE_VALUE (TREE_CHAIN (arglist));
9413
9414   /* Check whether the format is a literal string constant.  */
9415   fmt_str = c_getstr (fmt);
9416   if (fmt_str == NULL)
9417     return NULL_TREE;
9418
9419   call = NULL_TREE;
9420   retval = NULL_TREE;
9421
9422   /* If the format doesn't contain % args or %%, use strcpy.  */
9423   if (strchr (fmt_str, '%') == NULL)
9424     {
9425       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9426
9427       if (!fn)
9428         return NULL_TREE;
9429
9430       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
9431          'format' is known to contain no % formats.  */
9432       arglist = build_tree_list (NULL_TREE, fmt);
9433       arglist = tree_cons (NULL_TREE, dest, arglist);
9434       call = build_function_call_expr (fn, arglist);
9435       if (!ignored)
9436         retval = build_int_2 (strlen (fmt_str), 0);
9437     }
9438
9439   /* If the format is "%s", use strcpy if the result isn't used.  */
9440   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
9441     {
9442       tree fn, orig;
9443       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
9444
9445       if (!fn)
9446         return NULL_TREE;
9447
9448       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
9449       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
9450       arglist = build_tree_list (NULL_TREE, orig);
9451       arglist = tree_cons (NULL_TREE, dest, arglist);
9452       if (!ignored)
9453         {
9454           retval = c_strlen (orig, 1);
9455           if (!retval || TREE_CODE (retval) != INTEGER_CST)
9456             return NULL_TREE;
9457         }
9458       call = build_function_call_expr (fn, arglist);
9459     }
9460
9461   if (call && retval)
9462     {
9463       retval = convert
9464         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
9465          retval);
9466       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
9467     }
9468   else
9469     return call;
9470 }