OSDN Git Service

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