OSDN Git Service

* c-lex.c (interpret_float): Give a pedwarn rather than a warning
[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   /* __builtin_inff is intended to be usable to define INFINITY on all
5829      targets.  If an infinity is not available, INFINITY expands "to a
5830      positive constant of type float that overflows at translation
5831      time", footnote "In this case, using INFINITY will violate the
5832      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
5833      Thus we pedwarn to ensure this constraint violation is
5834      diagnosed.  */
5835   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5836     pedwarn ("target format does not support infinity");
5837
5838   real_inf (&real);
5839   return build_real (type, real);
5840 }
5841
5842 /* Fold a call to __builtin_nan or __builtin_nans.  */
5843
5844 static tree
5845 fold_builtin_nan (tree arglist, tree type, int quiet)
5846 {
5847   REAL_VALUE_TYPE real;
5848   const char *str;
5849
5850   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5851     return 0;
5852   str = c_getstr (TREE_VALUE (arglist));
5853   if (!str)
5854     return 0;
5855
5856   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5857     return 0;
5858
5859   return build_real (type, real);
5860 }
5861
5862 /* Return true if the floating point expression T has an integer value.
5863    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5864
5865 static bool
5866 integer_valued_real_p (tree t)
5867 {
5868   switch (TREE_CODE (t))
5869     {
5870     case FLOAT_EXPR:
5871       return true;
5872
5873     case ABS_EXPR:
5874     case SAVE_EXPR:
5875     case NON_LVALUE_EXPR:
5876       return integer_valued_real_p (TREE_OPERAND (t, 0));
5877
5878     case COMPOUND_EXPR:
5879     case MODIFY_EXPR:
5880     case BIND_EXPR:
5881       return integer_valued_real_p (TREE_OPERAND (t, 1));
5882
5883     case PLUS_EXPR:
5884     case MINUS_EXPR:
5885     case MULT_EXPR:
5886     case MIN_EXPR:
5887     case MAX_EXPR:
5888       return integer_valued_real_p (TREE_OPERAND (t, 0))
5889              && integer_valued_real_p (TREE_OPERAND (t, 1));
5890
5891     case COND_EXPR:
5892       return integer_valued_real_p (TREE_OPERAND (t, 1))
5893              && integer_valued_real_p (TREE_OPERAND (t, 2));
5894
5895     case REAL_CST:
5896       if (! TREE_CONSTANT_OVERFLOW (t))
5897       {
5898         REAL_VALUE_TYPE c, cint;
5899
5900         c = TREE_REAL_CST (t);
5901         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5902         return real_identical (&c, &cint);
5903       }
5904
5905     case NOP_EXPR:
5906       {
5907         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5908         if (TREE_CODE (type) == INTEGER_TYPE)
5909           return true;
5910         if (TREE_CODE (type) == REAL_TYPE)
5911           return integer_valued_real_p (TREE_OPERAND (t, 0));
5912         break;
5913       }
5914
5915     case CALL_EXPR:
5916       switch (builtin_mathfn_code (t))
5917         {
5918         case BUILT_IN_CEIL:
5919         case BUILT_IN_CEILF:
5920         case BUILT_IN_CEILL:
5921         case BUILT_IN_FLOOR:
5922         case BUILT_IN_FLOORF:
5923         case BUILT_IN_FLOORL:
5924         case BUILT_IN_NEARBYINT:
5925         case BUILT_IN_NEARBYINTF:
5926         case BUILT_IN_NEARBYINTL:
5927         case BUILT_IN_RINT:
5928         case BUILT_IN_RINTF:
5929         case BUILT_IN_RINTL:
5930         case BUILT_IN_ROUND:
5931         case BUILT_IN_ROUNDF:
5932         case BUILT_IN_ROUNDL:
5933         case BUILT_IN_TRUNC:
5934         case BUILT_IN_TRUNCF:
5935         case BUILT_IN_TRUNCL:
5936           return true;
5937
5938         default:
5939           break;
5940         }
5941       break;
5942
5943     default:
5944       break;
5945     }
5946   return false;
5947 }
5948
5949 /* EXP is assumed to be builtin call where truncation can be propagated
5950    across (for instance floor((double)f) == (double)floorf (f).
5951    Do the transformation.  */
5952
5953 static tree
5954 fold_trunc_transparent_mathfn (tree exp)
5955 {
5956   tree fndecl = get_callee_fndecl (exp);
5957   tree arglist = TREE_OPERAND (exp, 1);
5958   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5959   tree arg;
5960
5961   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5962     return 0;
5963
5964   arg = TREE_VALUE (arglist);
5965   /* Integer rounding functions are idempotent.  */
5966   if (fcode == builtin_mathfn_code (arg))
5967     return arg;
5968
5969   /* If argument is already integer valued, and we don't need to worry
5970      about setting errno, there's no need to perform rounding.  */
5971   if (! flag_errno_math && integer_valued_real_p (arg))
5972     return arg;
5973
5974   if (optimize)
5975     {
5976       tree arg0 = strip_float_extensions (arg);
5977       tree ftype = TREE_TYPE (exp);
5978       tree newtype = TREE_TYPE (arg0);
5979       tree decl;
5980
5981       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5982           && (decl = mathfn_built_in (newtype, fcode)))
5983         {
5984           arglist =
5985             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
5986           return fold_convert (ftype,
5987                                build_function_call_expr (decl, arglist));
5988         }
5989     }
5990   return 0;
5991 }
5992
5993 /* EXP is assumed to be builtin call which can narrow the FP type of
5994    the argument, for instance lround((double)f) -> lroundf (f).  */
5995
5996 static tree
5997 fold_fixed_mathfn (tree exp)
5998 {
5999   tree fndecl = get_callee_fndecl (exp);
6000   tree arglist = TREE_OPERAND (exp, 1);
6001   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6002   tree arg;
6003
6004   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6005     return 0;
6006
6007   arg = TREE_VALUE (arglist);
6008
6009   /* If argument is already integer valued, and we don't need to worry
6010      about setting errno, there's no need to perform rounding.  */
6011   if (! flag_errno_math && integer_valued_real_p (arg))
6012     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6013
6014   if (optimize)
6015     {
6016       tree ftype = TREE_TYPE (arg);
6017       tree arg0 = strip_float_extensions (arg);
6018       tree newtype = TREE_TYPE (arg0);
6019       tree decl;
6020
6021       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6022           && (decl = mathfn_built_in (newtype, fcode)))
6023         {
6024           arglist =
6025             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6026           return build_function_call_expr (decl, arglist);
6027         }
6028     }
6029   return 0;
6030 }
6031
6032 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6033    is the argument list and TYPE is the return type.  Return
6034    NULL_TREE if no if no simplification can be made.  */
6035
6036 static tree
6037 fold_builtin_cabs (tree arglist, tree type)
6038 {
6039   tree arg;
6040
6041   if (!arglist || TREE_CHAIN (arglist))
6042     return NULL_TREE;
6043
6044   arg = TREE_VALUE (arglist);
6045   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6046       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6047     return NULL_TREE;
6048
6049   /* Evaluate cabs of a constant at compile-time.  */
6050   if (flag_unsafe_math_optimizations
6051       && TREE_CODE (arg) == COMPLEX_CST
6052       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6053       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6054       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6055       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6056     {
6057       REAL_VALUE_TYPE r, i;
6058
6059       r = TREE_REAL_CST (TREE_REALPART (arg));
6060       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6061
6062       real_arithmetic (&r, MULT_EXPR, &r, &r);
6063       real_arithmetic (&i, MULT_EXPR, &i, &i);
6064       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6065       if (real_sqrt (&r, TYPE_MODE (type), &r)
6066           || ! flag_trapping_math)
6067         return build_real (type, r);
6068     }
6069
6070   /* If either part is zero, cabs is fabs of the other.  */
6071   if (TREE_CODE (arg) == COMPLEX_EXPR
6072       && real_zerop (TREE_OPERAND (arg, 0)))
6073     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6074   if (TREE_CODE (arg) == COMPLEX_EXPR
6075       && real_zerop (TREE_OPERAND (arg, 1)))
6076     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6077
6078   /* Don't do this when optimizing for size.  */
6079   if (flag_unsafe_math_optimizations
6080       && optimize && !optimize_size)
6081     {
6082       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6083
6084       if (sqrtfn != NULL_TREE)
6085         {
6086           tree rpart, ipart, result, arglist;
6087
6088           arg = builtin_save_expr (arg);
6089
6090           rpart = fold (build1 (REALPART_EXPR, type, arg));
6091           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6092
6093           rpart = builtin_save_expr (rpart);
6094           ipart = builtin_save_expr (ipart);
6095
6096           result = fold (build2 (PLUS_EXPR, type,
6097                                  fold (build2 (MULT_EXPR, type,
6098                                                rpart, rpart)),
6099                                  fold (build2 (MULT_EXPR, type,
6100                                                ipart, ipart))));
6101
6102           arglist = build_tree_list (NULL_TREE, result);
6103           return build_function_call_expr (sqrtfn, arglist);
6104         }
6105     }
6106
6107   return NULL_TREE;
6108 }
6109
6110 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6111    NULL_TREE if no simplification can be made.  */
6112
6113 static tree
6114 fold_builtin_sqrt (tree arglist, tree type)
6115 {
6116
6117   enum built_in_function fcode;
6118   tree arg = TREE_VALUE (arglist);
6119
6120   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6121     return NULL_TREE;
6122
6123   /* Optimize sqrt of constant value.  */
6124   if (TREE_CODE (arg) == REAL_CST
6125       && ! TREE_CONSTANT_OVERFLOW (arg))
6126     {
6127       REAL_VALUE_TYPE r, x;
6128
6129       x = TREE_REAL_CST (arg);
6130       if (real_sqrt (&r, TYPE_MODE (type), &x)
6131           || (!flag_trapping_math && !flag_errno_math))
6132         return build_real (type, r);
6133     }
6134
6135   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6136   fcode = builtin_mathfn_code (arg);
6137   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6138     {
6139       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6140       arg = fold (build2 (MULT_EXPR, type,
6141                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6142                           build_real (type, dconsthalf)));
6143       arglist = build_tree_list (NULL_TREE, arg);
6144       return build_function_call_expr (expfn, arglist);
6145     }
6146
6147   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6148   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6149     {
6150       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6151
6152       if (powfn)
6153         {
6154           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6155           tree tree_root;
6156           /* The inner root was either sqrt or cbrt.  */
6157           REAL_VALUE_TYPE dconstroot =
6158             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6159
6160           /* Adjust for the outer root.  */
6161           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6162           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6163           tree_root = build_real (type, dconstroot);
6164           arglist = tree_cons (NULL_TREE, arg0,
6165                                build_tree_list (NULL_TREE, tree_root));
6166           return build_function_call_expr (powfn, arglist);
6167         }
6168     }
6169
6170   /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6171   if (flag_unsafe_math_optimizations
6172       && (fcode == BUILT_IN_POW
6173           || fcode == BUILT_IN_POWF
6174           || fcode == BUILT_IN_POWL))
6175     {
6176       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6177       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6178       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6179       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6180                                  build_real (type, dconsthalf)));
6181       arglist = tree_cons (NULL_TREE, arg0,
6182                            build_tree_list (NULL_TREE, narg1));
6183       return build_function_call_expr (powfn, arglist);
6184     }
6185
6186   return NULL_TREE;
6187 }
6188
6189 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6190    NULL_TREE if no simplification can be made.  */
6191 static tree
6192 fold_builtin_cbrt (tree arglist, tree type)
6193 {
6194   tree arg = TREE_VALUE (arglist);
6195   const enum built_in_function fcode = builtin_mathfn_code (arg);
6196
6197   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6198     return NULL_TREE;
6199
6200   /* Optimize cbrt of constant value.  */
6201   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6202     return arg;
6203
6204   /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6205   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6206     {
6207       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6208       const REAL_VALUE_TYPE third_trunc =
6209         real_value_truncate (TYPE_MODE (type), dconstthird);
6210       arg = fold (build2 (MULT_EXPR, type,
6211                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6212                           build_real (type, third_trunc)));
6213       arglist = build_tree_list (NULL_TREE, arg);
6214       return build_function_call_expr (expfn, arglist);
6215     }
6216
6217   /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6218   /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6219      x is negative pow will error but cbrt won't.  */
6220   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6221     {
6222       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6223
6224       if (powfn)
6225         {
6226           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6227           tree tree_root;
6228           REAL_VALUE_TYPE dconstroot = dconstthird;
6229
6230           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6231           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6232           tree_root = build_real (type, dconstroot);
6233           arglist = tree_cons (NULL_TREE, arg0,
6234                                build_tree_list (NULL_TREE, tree_root));
6235           return build_function_call_expr (powfn, arglist);
6236         }
6237
6238     }
6239   return NULL_TREE;
6240 }
6241
6242 /* Fold function call to builtin sin, sinf, or sinl.  Return
6243    NULL_TREE if no simplification can be made.  */
6244 static tree
6245 fold_builtin_sin (tree arglist)
6246 {
6247   tree arg = TREE_VALUE (arglist);
6248
6249   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6250     return NULL_TREE;
6251
6252   /* Optimize sin (0.0) = 0.0.  */
6253   if (real_zerop (arg))
6254     return arg;
6255
6256   return NULL_TREE;
6257 }
6258
6259 /* Fold function call to builtin cos, cosf, or cosl.  Return
6260    NULL_TREE if no simplification can be made.  */
6261 static tree
6262 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6263 {
6264   tree arg = TREE_VALUE (arglist);
6265
6266   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6267     return NULL_TREE;
6268
6269   /* Optimize cos (0.0) = 1.0.  */
6270   if (real_zerop (arg))
6271     return build_real (type, dconst1);
6272
6273   /* Optimize cos(-x) into cos (x).  */
6274   if (TREE_CODE (arg) == NEGATE_EXPR)
6275     {
6276       tree args = build_tree_list (NULL_TREE,
6277                                    TREE_OPERAND (arg, 0));
6278       return build_function_call_expr (fndecl, args);
6279     }
6280
6281   return NULL_TREE;
6282 }
6283
6284 /* Fold function call to builtin tan, tanf, or tanl.  Return
6285    NULL_TREE if no simplification can be made.  */
6286 static tree
6287 fold_builtin_tan (tree arglist)
6288 {
6289   enum built_in_function fcode;
6290   tree arg = TREE_VALUE (arglist);
6291
6292   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6293     return NULL_TREE;
6294
6295   /* Optimize tan(0.0) = 0.0.  */
6296   if (real_zerop (arg))
6297     return arg;
6298
6299   /* Optimize tan(atan(x)) = x.  */
6300   fcode = builtin_mathfn_code (arg);
6301   if (flag_unsafe_math_optimizations
6302       && (fcode == BUILT_IN_ATAN
6303           || fcode == BUILT_IN_ATANF
6304           || fcode == BUILT_IN_ATANL))
6305     return TREE_VALUE (TREE_OPERAND (arg, 1));
6306
6307   return NULL_TREE;
6308 }
6309
6310 /* Fold function call to builtin atan, atanf, or atanl.  Return
6311    NULL_TREE if no simplification can be made.  */
6312
6313 static tree
6314 fold_builtin_atan (tree arglist, tree type)
6315 {
6316
6317   tree arg = TREE_VALUE (arglist);
6318
6319   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6320     return NULL_TREE;
6321
6322   /* Optimize atan(0.0) = 0.0.  */
6323   if (real_zerop (arg))
6324     return arg;
6325
6326   /* Optimize atan(1.0) = pi/4.  */
6327   if (real_onep (arg))
6328     {
6329       REAL_VALUE_TYPE cst;
6330
6331       real_convert (&cst, TYPE_MODE (type), &dconstpi);
6332       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6333       return build_real (type, cst);
6334     }
6335
6336   return NULL_TREE;
6337 }
6338
6339 /* Fold function call to builtin trunc, truncf or truncl.  Return
6340    NULL_TREE if no simplification can be made.  */
6341
6342 static tree
6343 fold_builtin_trunc (tree exp)
6344 {
6345   tree arglist = TREE_OPERAND (exp, 1);
6346   tree arg;
6347
6348   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6349     return 0;
6350
6351   /* Optimize trunc of constant value.  */
6352   arg = TREE_VALUE (arglist);
6353   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6354     {
6355       REAL_VALUE_TYPE r, x;
6356       tree type = TREE_TYPE (exp);
6357
6358       x = TREE_REAL_CST (arg);
6359       real_trunc (&r, TYPE_MODE (type), &x);
6360       return build_real (type, r);
6361     }
6362
6363   return fold_trunc_transparent_mathfn (exp);
6364 }
6365
6366 /* Fold function call to builtin floor, floorf or floorl.  Return
6367    NULL_TREE if no simplification can be made.  */
6368
6369 static tree
6370 fold_builtin_floor (tree exp)
6371 {
6372   tree arglist = TREE_OPERAND (exp, 1);
6373   tree arg;
6374
6375   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6376     return 0;
6377
6378   /* Optimize floor of constant value.  */
6379   arg = TREE_VALUE (arglist);
6380   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6381     {
6382       REAL_VALUE_TYPE x;
6383
6384       x = TREE_REAL_CST (arg);
6385       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6386         {
6387           tree type = TREE_TYPE (exp);
6388           REAL_VALUE_TYPE r;
6389
6390           real_floor (&r, TYPE_MODE (type), &x);
6391           return build_real (type, r);
6392         }
6393     }
6394
6395   return fold_trunc_transparent_mathfn (exp);
6396 }
6397
6398 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6399    NULL_TREE if no simplification can be made.  */
6400
6401 static tree
6402 fold_builtin_ceil (tree exp)
6403 {
6404   tree arglist = TREE_OPERAND (exp, 1);
6405   tree arg;
6406
6407   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6408     return 0;
6409
6410   /* Optimize ceil of constant value.  */
6411   arg = TREE_VALUE (arglist);
6412   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6413     {
6414       REAL_VALUE_TYPE x;
6415
6416       x = TREE_REAL_CST (arg);
6417       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6418         {
6419           tree type = TREE_TYPE (exp);
6420           REAL_VALUE_TYPE r;
6421
6422           real_ceil (&r, TYPE_MODE (type), &x);
6423           return build_real (type, r);
6424         }
6425     }
6426
6427   return fold_trunc_transparent_mathfn (exp);
6428 }
6429
6430 /* Fold function call to builtin round, roundf or roundl.  Return
6431    NULL_TREE if no simplification can be made.  */
6432
6433 static tree
6434 fold_builtin_round (tree exp)
6435 {
6436   tree arglist = TREE_OPERAND (exp, 1);
6437   tree arg;
6438
6439   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6440     return 0;
6441
6442   /* Optimize round of constant value.  */
6443   arg = TREE_VALUE (arglist);
6444   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6445     {
6446       REAL_VALUE_TYPE x;
6447
6448       x = TREE_REAL_CST (arg);
6449       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6450         {
6451           tree type = TREE_TYPE (exp);
6452           REAL_VALUE_TYPE r;
6453
6454           real_round (&r, TYPE_MODE (type), &x);
6455           return build_real (type, r);
6456         }
6457     }
6458
6459   return fold_trunc_transparent_mathfn (exp);
6460 }
6461
6462 /* Fold function call to builtin lround, lroundf or lroundl (or the
6463    corresponding long long versions).  Return NULL_TREE if no
6464    simplification can be made.  */
6465
6466 static tree
6467 fold_builtin_lround (tree exp)
6468 {
6469   tree arglist = TREE_OPERAND (exp, 1);
6470   tree arg;
6471
6472   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6473     return 0;
6474
6475   /* Optimize lround of constant value.  */
6476   arg = TREE_VALUE (arglist);
6477   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6478     {
6479       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6480
6481       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6482         {
6483           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6484           HOST_WIDE_INT hi, lo;
6485           REAL_VALUE_TYPE r;
6486
6487           real_round (&r, TYPE_MODE (ftype), &x);
6488           REAL_VALUE_TO_INT (&lo, &hi, r);
6489           result = build_int_cst_wide (NULL_TREE, lo, hi);
6490           if (int_fits_type_p (result, itype))
6491             return fold_convert (itype, result);
6492         }
6493     }
6494
6495   return fold_fixed_mathfn (exp);
6496 }
6497
6498 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6499    and their long and long long variants (i.e. ffsl and ffsll).
6500    Return NULL_TREE if no simplification can be made.  */
6501
6502 static tree
6503 fold_builtin_bitop (tree exp)
6504 {
6505   tree fndecl = get_callee_fndecl (exp);
6506   tree arglist = TREE_OPERAND (exp, 1);
6507   tree arg;
6508
6509   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6510     return NULL_TREE;
6511
6512   /* Optimize for constant argument.  */
6513   arg = TREE_VALUE (arglist);
6514   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6515     {
6516       HOST_WIDE_INT hi, width, result;
6517       unsigned HOST_WIDE_INT lo;
6518       tree type;
6519
6520       type = TREE_TYPE (arg);
6521       width = TYPE_PRECISION (type);
6522       lo = TREE_INT_CST_LOW (arg);
6523
6524       /* Clear all the bits that are beyond the type's precision.  */
6525       if (width > HOST_BITS_PER_WIDE_INT)
6526         {
6527           hi = TREE_INT_CST_HIGH (arg);
6528           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6529             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6530         }
6531       else
6532         {
6533           hi = 0;
6534           if (width < HOST_BITS_PER_WIDE_INT)
6535             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6536         }
6537
6538       switch (DECL_FUNCTION_CODE (fndecl))
6539         {
6540         case BUILT_IN_FFS:
6541         case BUILT_IN_FFSL:
6542         case BUILT_IN_FFSLL:
6543           if (lo != 0)
6544             result = exact_log2 (lo & -lo) + 1;
6545           else if (hi != 0)
6546             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6547           else
6548             result = 0;
6549           break;
6550
6551         case BUILT_IN_CLZ:
6552         case BUILT_IN_CLZL:
6553         case BUILT_IN_CLZLL:
6554           if (hi != 0)
6555             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6556           else if (lo != 0)
6557             result = width - floor_log2 (lo) - 1;
6558           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6559             result = width;
6560           break;
6561
6562         case BUILT_IN_CTZ:
6563         case BUILT_IN_CTZL:
6564         case BUILT_IN_CTZLL:
6565           if (lo != 0)
6566             result = exact_log2 (lo & -lo);
6567           else if (hi != 0)
6568             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6569           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6570             result = width;
6571           break;
6572
6573         case BUILT_IN_POPCOUNT:
6574         case BUILT_IN_POPCOUNTL:
6575         case BUILT_IN_POPCOUNTLL:
6576           result = 0;
6577           while (lo)
6578             result++, lo &= lo - 1;
6579           while (hi)
6580             result++, hi &= hi - 1;
6581           break;
6582
6583         case BUILT_IN_PARITY:
6584         case BUILT_IN_PARITYL:
6585         case BUILT_IN_PARITYLL:
6586           result = 0;
6587           while (lo)
6588             result++, lo &= lo - 1;
6589           while (hi)
6590             result++, hi &= hi - 1;
6591           result &= 1;
6592           break;
6593
6594         default:
6595           gcc_unreachable ();
6596         }
6597
6598       return build_int_cst (TREE_TYPE (exp), result);
6599     }
6600
6601   return NULL_TREE;
6602 }
6603
6604 /* Return true if EXPR is the real constant contained in VALUE.  */
6605
6606 static bool
6607 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6608 {
6609   STRIP_NOPS (expr);
6610
6611   return ((TREE_CODE (expr) == REAL_CST
6612            && ! TREE_CONSTANT_OVERFLOW (expr)
6613            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6614           || (TREE_CODE (expr) == COMPLEX_CST
6615               && real_dconstp (TREE_REALPART (expr), value)
6616               && real_zerop (TREE_IMAGPART (expr))));
6617 }
6618
6619 /* A subroutine of fold_builtin to fold the various logarithmic
6620    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6621    function.  VALUE is the base of the logN function.  */
6622
6623 static tree
6624 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6625 {
6626   tree arglist = TREE_OPERAND (exp, 1);
6627
6628   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6629     {
6630       tree fndecl = get_callee_fndecl (exp);
6631       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6632       tree arg = TREE_VALUE (arglist);
6633       const enum built_in_function fcode = builtin_mathfn_code (arg);
6634
6635       /* Optimize logN(1.0) = 0.0.  */
6636       if (real_onep (arg))
6637         return build_real (type, dconst0);
6638
6639       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6640          exactly, then only do this if flag_unsafe_math_optimizations.  */
6641       if (exact_real_truncate (TYPE_MODE (type), value)
6642           || flag_unsafe_math_optimizations)
6643         {
6644           const REAL_VALUE_TYPE value_truncate =
6645             real_value_truncate (TYPE_MODE (type), *value);
6646           if (real_dconstp (arg, &value_truncate))
6647             return build_real (type, dconst1);
6648         }
6649
6650       /* Special case, optimize logN(expN(x)) = x.  */
6651       if (flag_unsafe_math_optimizations
6652           && ((value == &dconste
6653                && (fcode == BUILT_IN_EXP
6654                    || fcode == BUILT_IN_EXPF
6655                    || fcode == BUILT_IN_EXPL))
6656               || (value == &dconst2
6657                   && (fcode == BUILT_IN_EXP2
6658                       || fcode == BUILT_IN_EXP2F
6659                       || fcode == BUILT_IN_EXP2L))
6660               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6661         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6662
6663       /* Optimize logN(func()) for various exponential functions.  We
6664          want to determine the value "x" and the power "exponent" in
6665          order to transform logN(x**exponent) into exponent*logN(x).  */
6666       if (flag_unsafe_math_optimizations)
6667         {
6668           tree exponent = 0, x = 0;
6669
6670           switch (fcode)
6671           {
6672           case BUILT_IN_EXP:
6673           case BUILT_IN_EXPF:
6674           case BUILT_IN_EXPL:
6675             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6676             x = build_real (type,
6677                             real_value_truncate (TYPE_MODE (type), dconste));
6678             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6679             break;
6680           case BUILT_IN_EXP2:
6681           case BUILT_IN_EXP2F:
6682           case BUILT_IN_EXP2L:
6683             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6684             x = build_real (type, dconst2);
6685             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6686             break;
6687           case BUILT_IN_EXP10:
6688           case BUILT_IN_EXP10F:
6689           case BUILT_IN_EXP10L:
6690           case BUILT_IN_POW10:
6691           case BUILT_IN_POW10F:
6692           case BUILT_IN_POW10L:
6693             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6694             x = build_real (type, dconst10);
6695             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6696             break;
6697           case BUILT_IN_SQRT:
6698           case BUILT_IN_SQRTF:
6699           case BUILT_IN_SQRTL:
6700             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6701             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6702             exponent = build_real (type, dconsthalf);
6703             break;
6704           case BUILT_IN_CBRT:
6705           case BUILT_IN_CBRTF:
6706           case BUILT_IN_CBRTL:
6707             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6708             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6709             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6710                                                               dconstthird));
6711             break;
6712           case BUILT_IN_POW:
6713           case BUILT_IN_POWF:
6714           case BUILT_IN_POWL:
6715             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6716             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6717             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6718             break;
6719           default:
6720             break;
6721           }
6722
6723           /* Now perform the optimization.  */
6724           if (x && exponent)
6725             {
6726               tree logfn;
6727               arglist = build_tree_list (NULL_TREE, x);
6728               logfn = build_function_call_expr (fndecl, arglist);
6729               return fold (build2 (MULT_EXPR, type, exponent, logfn));
6730             }
6731         }
6732     }
6733
6734   return 0;
6735 }
6736
6737 /* Fold a builtin function call to pow, powf, or powl.  Return
6738    NULL_TREE if no simplification can be made.  */
6739 static tree
6740 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6741 {
6742   enum built_in_function fcode;
6743   tree arg0 = TREE_VALUE (arglist);
6744   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6745
6746   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6747     return NULL_TREE;
6748
6749   /* Optimize pow(1.0,y) = 1.0.  */
6750   if (real_onep (arg0))
6751     return omit_one_operand (type, build_real (type, dconst1), arg1);
6752
6753   if (TREE_CODE (arg1) == REAL_CST
6754       && ! TREE_CONSTANT_OVERFLOW (arg1))
6755     {
6756       REAL_VALUE_TYPE c;
6757       c = TREE_REAL_CST (arg1);
6758
6759       /* Optimize pow(x,0.0) = 1.0.  */
6760       if (REAL_VALUES_EQUAL (c, dconst0))
6761         return omit_one_operand (type, build_real (type, dconst1),
6762                                  arg0);
6763
6764       /* Optimize pow(x,1.0) = x.  */
6765       if (REAL_VALUES_EQUAL (c, dconst1))
6766         return arg0;
6767
6768       /* Optimize pow(x,-1.0) = 1.0/x.  */
6769       if (REAL_VALUES_EQUAL (c, dconstm1))
6770         return fold (build2 (RDIV_EXPR, type,
6771                              build_real (type, dconst1), arg0));
6772
6773       /* Optimize pow(x,0.5) = sqrt(x).  */
6774       if (flag_unsafe_math_optimizations
6775           && REAL_VALUES_EQUAL (c, dconsthalf))
6776         {
6777           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6778
6779           if (sqrtfn != NULL_TREE)
6780             {
6781               tree arglist = build_tree_list (NULL_TREE, arg0);
6782               return build_function_call_expr (sqrtfn, arglist);
6783             }
6784         }
6785
6786       /* Attempt to evaluate pow at compile-time.  */
6787       if (TREE_CODE (arg0) == REAL_CST
6788           && ! TREE_CONSTANT_OVERFLOW (arg0))
6789         {
6790           REAL_VALUE_TYPE cint;
6791           HOST_WIDE_INT n;
6792
6793           n = real_to_integer (&c);
6794           real_from_integer (&cint, VOIDmode, n,
6795                              n < 0 ? -1 : 0, 0);
6796           if (real_identical (&c, &cint))
6797             {
6798               REAL_VALUE_TYPE x;
6799               bool inexact;
6800
6801               x = TREE_REAL_CST (arg0);
6802               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6803               if (flag_unsafe_math_optimizations || !inexact)
6804                 return build_real (type, x);
6805             }
6806         }
6807     }
6808
6809   /* Optimize pow(expN(x),y) = expN(x*y).  */
6810   fcode = builtin_mathfn_code (arg0);
6811   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6812     {
6813       tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6814       tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6815       arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6816       arglist = build_tree_list (NULL_TREE, arg);
6817       return build_function_call_expr (expfn, arglist);
6818     }
6819
6820   /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6821   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6822     {
6823       tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6824       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6825                                  build_real (type, dconsthalf)));
6826
6827       arglist = tree_cons (NULL_TREE, narg0,
6828                            build_tree_list (NULL_TREE, narg1));
6829       return build_function_call_expr (fndecl, arglist);
6830     }
6831
6832   /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6833   if (flag_unsafe_math_optimizations
6834       && (fcode == BUILT_IN_POW
6835           || fcode == BUILT_IN_POWF
6836           || fcode == BUILT_IN_POWL))
6837     {
6838       tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6839       tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6840       tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
6841       arglist = tree_cons (NULL_TREE, arg00,
6842                            build_tree_list (NULL_TREE, narg1));
6843       return build_function_call_expr (fndecl, arglist);
6844     }
6845   return NULL_TREE;
6846 }
6847
6848 /* A subroutine of fold_builtin to fold the various exponent
6849    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6850    VALUE is the value which will be raised to a power.  */
6851
6852 static tree
6853 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6854 {
6855   tree arglist = TREE_OPERAND (exp, 1);
6856
6857   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6858     {
6859       tree fndecl = get_callee_fndecl (exp);
6860       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6861       tree arg = TREE_VALUE (arglist);
6862
6863       /* Optimize exp*(0.0) = 1.0.  */
6864       if (real_zerop (arg))
6865         return build_real (type, dconst1);
6866
6867       /* Optimize expN(1.0) = N.  */
6868       if (real_onep (arg))
6869         {
6870           REAL_VALUE_TYPE cst;
6871
6872           real_convert (&cst, TYPE_MODE (type), value);
6873           return build_real (type, cst);
6874         }
6875
6876       /* Attempt to evaluate expN(integer) at compile-time.  */
6877       if (flag_unsafe_math_optimizations
6878           && TREE_CODE (arg) == REAL_CST
6879           && ! TREE_CONSTANT_OVERFLOW (arg))
6880         {
6881           REAL_VALUE_TYPE cint;
6882           REAL_VALUE_TYPE c;
6883           HOST_WIDE_INT n;
6884
6885           c = TREE_REAL_CST (arg);
6886           n = real_to_integer (&c);
6887           real_from_integer (&cint, VOIDmode, n,
6888                              n < 0 ? -1 : 0, 0);
6889           if (real_identical (&c, &cint))
6890             {
6891               REAL_VALUE_TYPE x;
6892
6893               real_powi (&x, TYPE_MODE (type), value, n);
6894               return build_real (type, x);
6895             }
6896         }
6897
6898       /* Optimize expN(logN(x)) = x.  */
6899       if (flag_unsafe_math_optimizations)
6900         {
6901           const enum built_in_function fcode = builtin_mathfn_code (arg);
6902
6903           if ((value == &dconste
6904                && (fcode == BUILT_IN_LOG
6905                    || fcode == BUILT_IN_LOGF
6906                    || fcode == BUILT_IN_LOGL))
6907               || (value == &dconst2
6908                   && (fcode == BUILT_IN_LOG2
6909                       || fcode == BUILT_IN_LOG2F
6910                       || fcode == BUILT_IN_LOG2L))
6911               || (value == &dconst10
6912                   && (fcode == BUILT_IN_LOG10
6913                       || fcode == BUILT_IN_LOG10F
6914                       || fcode == BUILT_IN_LOG10L)))
6915             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6916         }
6917     }
6918
6919   return 0;
6920 }
6921
6922 /* Fold function call to builtin memcpy.  Return
6923    NULL_TREE if no simplification can be made.  */
6924
6925 static tree
6926 fold_builtin_memcpy (tree exp)
6927 {
6928   tree arglist = TREE_OPERAND (exp, 1);
6929   tree dest, src, len;
6930
6931   if (!validate_arglist (arglist,
6932                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6933     return 0;
6934
6935   dest = TREE_VALUE (arglist);
6936   src = TREE_VALUE (TREE_CHAIN (arglist));
6937   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6938
6939   /* If the LEN parameter is zero, return DEST.  */
6940   if (integer_zerop (len))
6941     return omit_one_operand (TREE_TYPE (exp), dest, src);
6942
6943   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6944   if (operand_equal_p (src, dest, 0))
6945     return omit_one_operand (TREE_TYPE (exp), dest, len);
6946
6947   return 0;
6948 }
6949
6950 /* Fold function call to builtin mempcpy.  Return
6951    NULL_TREE if no simplification can be made.  */
6952
6953 static tree
6954 fold_builtin_mempcpy (tree arglist, tree type, int endp)
6955 {
6956   if (validate_arglist (arglist,
6957                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6958     {
6959       tree dest = TREE_VALUE (arglist);
6960       tree src = TREE_VALUE (TREE_CHAIN (arglist));
6961       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6962
6963       /* If the LEN parameter is zero, return DEST.  */
6964       if (integer_zerop (len))
6965         return omit_one_operand (type, dest, src);
6966
6967       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6968       if (operand_equal_p (src, dest, 0))
6969         {
6970           if (endp == 0)
6971             return omit_one_operand (type, dest, len);
6972
6973           if (endp == 2)
6974             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
6975                                 ssize_int (1)));
6976       
6977           len = fold_convert (TREE_TYPE (dest), len);
6978           len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6979           return fold_convert (type, len);
6980         }
6981     }
6982   return 0;
6983 }
6984
6985 /* Fold function call to builtin memmove.  Return
6986    NULL_TREE if no simplification can be made.  */
6987
6988 static tree
6989 fold_builtin_memmove (tree arglist, tree type)
6990 {
6991   tree dest, src, len;
6992
6993   if (!validate_arglist (arglist,
6994                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6995     return 0;
6996
6997   dest = TREE_VALUE (arglist);
6998   src = TREE_VALUE (TREE_CHAIN (arglist));
6999   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7000
7001   /* If the LEN parameter is zero, return DEST.  */
7002   if (integer_zerop (len))
7003     return omit_one_operand (type, dest, src);
7004
7005   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7006   if (operand_equal_p (src, dest, 0))
7007     return omit_one_operand (type, dest, len);
7008
7009   return 0;
7010 }
7011
7012 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7013    the length of the string to be copied.  Return NULL_TREE if no
7014    simplification can be made.  */
7015
7016 tree
7017 fold_builtin_strcpy (tree exp, tree len)
7018 {
7019   tree arglist = TREE_OPERAND (exp, 1);
7020   tree dest, src, fn;
7021
7022   if (!validate_arglist (arglist,
7023                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7024     return 0;
7025
7026   dest = TREE_VALUE (arglist);
7027   src = TREE_VALUE (TREE_CHAIN (arglist));
7028
7029   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7030   if (operand_equal_p (src, dest, 0))
7031     return fold_convert (TREE_TYPE (exp), dest);
7032
7033   if (optimize_size)
7034     return 0;
7035
7036   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7037   if (!fn)
7038     return 0;
7039
7040   if (!len)
7041     {
7042       len = c_strlen (src, 1);
7043       if (! len || TREE_SIDE_EFFECTS (len))
7044         return 0;
7045     }
7046
7047   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7048   arglist = build_tree_list (NULL_TREE, len);
7049   arglist = tree_cons (NULL_TREE, src, arglist);
7050   arglist = tree_cons (NULL_TREE, dest, arglist);
7051   return fold_convert (TREE_TYPE (exp),
7052                        build_function_call_expr (fn, arglist));
7053 }
7054
7055 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7056    the length of the source string.  Return NULL_TREE if no simplification
7057    can be made.  */
7058
7059 tree
7060 fold_builtin_strncpy (tree exp, tree slen)
7061 {
7062   tree arglist = TREE_OPERAND (exp, 1);
7063   tree dest, src, len, fn;
7064
7065   if (!validate_arglist (arglist,
7066                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7067     return 0;
7068
7069   dest = TREE_VALUE (arglist);
7070   src = TREE_VALUE (TREE_CHAIN (arglist));
7071   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7072
7073   /* If the LEN parameter is zero, return DEST.  */
7074   if (integer_zerop (len))
7075     return omit_one_operand (TREE_TYPE (exp), dest, src);
7076
7077   /* We can't compare slen with len as constants below if len is not a
7078      constant.  */
7079   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7080     return 0;
7081
7082   if (!slen)
7083     slen = c_strlen (src, 1);
7084
7085   /* Now, we must be passed a constant src ptr parameter.  */
7086   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7087     return 0;
7088
7089   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7090
7091   /* We do not support simplification of this case, though we do
7092      support it when expanding trees into RTL.  */
7093   /* FIXME: generate a call to __builtin_memset.  */
7094   if (tree_int_cst_lt (slen, len))
7095     return 0;
7096
7097   /* OK transform into builtin memcpy.  */
7098   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7099   if (!fn)
7100     return 0;
7101   return fold_convert (TREE_TYPE (exp),
7102                        build_function_call_expr (fn, arglist));
7103 }
7104
7105 /* Fold function call to builtin memcmp.  Return
7106    NULL_TREE if no simplification can be made.  */
7107
7108 static tree
7109 fold_builtin_memcmp (tree arglist)
7110 {
7111   tree arg1, arg2, len;
7112   const char *p1, *p2;
7113
7114   if (!validate_arglist (arglist,
7115                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7116     return 0;
7117
7118   arg1 = TREE_VALUE (arglist);
7119   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7120   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7121
7122   /* If the LEN parameter is zero, return zero.  */
7123   if (integer_zerop (len))
7124     return omit_two_operands (integer_type_node, integer_zero_node,
7125                               arg1, arg2);
7126
7127   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7128   if (operand_equal_p (arg1, arg2, 0))
7129     return omit_one_operand (integer_type_node, integer_zero_node, len);
7130
7131   p1 = c_getstr (arg1);
7132   p2 = c_getstr (arg2);
7133
7134   /* If all arguments are constant, and the value of len is not greater
7135      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7136   if (host_integerp (len, 1) && p1 && p2
7137       && compare_tree_int (len, strlen (p1) + 1) <= 0
7138       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7139     {
7140       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7141
7142       if (r > 0)
7143         return integer_one_node;
7144       else if (r < 0)
7145         return integer_minus_one_node;
7146       else
7147         return integer_zero_node;
7148     }
7149
7150   /* If len parameter is one, return an expression corresponding to
7151      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7152   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7153     {
7154       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7155       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7156       tree ind1 = fold_convert (integer_type_node,
7157                                 build1 (INDIRECT_REF, cst_uchar_node,
7158                                         fold_convert (cst_uchar_ptr_node,
7159                                                       arg1)));
7160       tree ind2 = fold_convert (integer_type_node,
7161                                 build1 (INDIRECT_REF, cst_uchar_node,
7162                                         fold_convert (cst_uchar_ptr_node,
7163                                                       arg2)));
7164       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7165     }
7166
7167   return 0;
7168 }
7169
7170 /* Fold function call to builtin strcmp.  Return
7171    NULL_TREE if no simplification can be made.  */
7172
7173 static tree
7174 fold_builtin_strcmp (tree arglist)
7175 {
7176   tree arg1, arg2;
7177   const char *p1, *p2;
7178
7179   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7180     return 0;
7181
7182   arg1 = TREE_VALUE (arglist);
7183   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7184
7185   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7186   if (operand_equal_p (arg1, arg2, 0))
7187     return integer_zero_node;
7188
7189   p1 = c_getstr (arg1);
7190   p2 = c_getstr (arg2);
7191
7192   if (p1 && p2)
7193     {
7194       const int i = strcmp (p1, p2);
7195       if (i < 0)
7196         return integer_minus_one_node;
7197       else if (i > 0)
7198         return integer_one_node;
7199       else
7200         return integer_zero_node;
7201     }
7202
7203   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7204   if (p2 && *p2 == '\0')
7205     {
7206       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7207       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7208       return fold_convert (integer_type_node,
7209                            build1 (INDIRECT_REF, cst_uchar_node,
7210                                    fold_convert (cst_uchar_ptr_node,
7211                                                  arg1)));
7212     }
7213
7214   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7215   if (p1 && *p1 == '\0')
7216     {
7217       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7218       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7219       tree temp = fold_convert (integer_type_node,
7220                                 build1 (INDIRECT_REF, cst_uchar_node,
7221                                         fold_convert (cst_uchar_ptr_node,
7222                                                       arg2)));
7223       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7224     }
7225
7226   return 0;
7227 }
7228
7229 /* Fold function call to builtin strncmp.  Return
7230    NULL_TREE if no simplification can be made.  */
7231
7232 static tree
7233 fold_builtin_strncmp (tree arglist)
7234 {
7235   tree arg1, arg2, len;
7236   const char *p1, *p2;
7237
7238   if (!validate_arglist (arglist,
7239                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7240     return 0;
7241
7242   arg1 = TREE_VALUE (arglist);
7243   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7244   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7245
7246   /* If the LEN parameter is zero, return zero.  */
7247   if (integer_zerop (len))
7248     return omit_two_operands (integer_type_node, integer_zero_node,
7249                               arg1, arg2);
7250
7251   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7252   if (operand_equal_p (arg1, arg2, 0))
7253     return omit_one_operand (integer_type_node, integer_zero_node, len);
7254
7255   p1 = c_getstr (arg1);
7256   p2 = c_getstr (arg2);
7257
7258   if (host_integerp (len, 1) && p1 && p2)
7259     {
7260       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7261       if (i > 0)
7262         return integer_one_node;
7263       else if (i < 0)
7264         return integer_minus_one_node;
7265       else
7266         return integer_zero_node;
7267     }
7268
7269   /* If the second arg is "", and the length is greater than zero,
7270      return *(const unsigned char*)arg1.  */
7271   if (p2 && *p2 == '\0'
7272       && TREE_CODE (len) == INTEGER_CST
7273       && tree_int_cst_sgn (len) == 1)
7274     {
7275       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7276       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7277       return fold_convert (integer_type_node,
7278                            build1 (INDIRECT_REF, cst_uchar_node,
7279                                    fold_convert (cst_uchar_ptr_node,
7280                                                  arg1)));
7281     }
7282
7283   /* If the first arg is "", and the length is greater than zero,
7284      return -*(const unsigned char*)arg2.  */
7285   if (p1 && *p1 == '\0'
7286       && TREE_CODE (len) == INTEGER_CST
7287       && tree_int_cst_sgn (len) == 1)
7288     {
7289       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7290       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7291       tree temp = fold_convert (integer_type_node,
7292                                 build1 (INDIRECT_REF, cst_uchar_node,
7293                                         fold_convert (cst_uchar_ptr_node,
7294                                                       arg2)));
7295       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7296     }
7297
7298   /* If len parameter is one, return an expression corresponding to
7299      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7300   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7301     {
7302       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7303       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7304       tree ind1 = fold_convert (integer_type_node,
7305                                 build1 (INDIRECT_REF, cst_uchar_node,
7306                                         fold_convert (cst_uchar_ptr_node,
7307                                                       arg1)));
7308       tree ind2 = fold_convert (integer_type_node,
7309                                 build1 (INDIRECT_REF, cst_uchar_node,
7310                                         fold_convert (cst_uchar_ptr_node,
7311                                                       arg2)));
7312       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7313     }
7314
7315   return 0;
7316 }
7317
7318 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7319    NULL_TREE if no simplification can be made.  */
7320
7321 static tree
7322 fold_builtin_signbit (tree exp)
7323 {
7324   tree arglist = TREE_OPERAND (exp, 1);
7325   tree arg, temp;
7326
7327   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7328     return NULL_TREE;
7329
7330   arg = TREE_VALUE (arglist);
7331
7332   /* If ARG is a compile-time constant, determine the result.  */
7333   if (TREE_CODE (arg) == REAL_CST
7334       && !TREE_CONSTANT_OVERFLOW (arg))
7335     {
7336       REAL_VALUE_TYPE c;
7337
7338       c = TREE_REAL_CST (arg);
7339       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7340       return fold_convert (TREE_TYPE (exp), temp);
7341     }
7342
7343   /* If ARG is non-negative, the result is always zero.  */
7344   if (tree_expr_nonnegative_p (arg))
7345     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7346
7347   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7348   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7349     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7350                          build_real (TREE_TYPE (arg), dconst0)));
7351
7352   return NULL_TREE;
7353 }
7354
7355 /* Fold function call to builtin copysign, copysignf or copysignl.
7356    Return NULL_TREE if no simplification can be made.  */
7357
7358 static tree
7359 fold_builtin_copysign (tree arglist, tree type)
7360 {
7361   tree arg1, arg2;
7362
7363   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7364     return NULL_TREE;
7365
7366   arg1 = TREE_VALUE (arglist);
7367   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7368
7369   /* copysign(X,X) is X.  */
7370   if (operand_equal_p (arg1, arg2, 0))
7371     return fold_convert (type, arg1);
7372
7373   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7374   if (TREE_CODE (arg1) == REAL_CST
7375       && TREE_CODE (arg2) == REAL_CST
7376       && !TREE_CONSTANT_OVERFLOW (arg1)
7377       && !TREE_CONSTANT_OVERFLOW (arg2))
7378     {
7379       REAL_VALUE_TYPE c1, c2;
7380
7381       c1 = TREE_REAL_CST (arg1);
7382       c2 = TREE_REAL_CST (arg2);
7383       real_copysign (&c1, &c2);
7384       return build_real (type, c1);
7385       c1.sign = c2.sign;
7386     }
7387
7388   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7389      Remember to evaluate Y for side-effects.  */
7390   if (tree_expr_nonnegative_p (arg2))
7391     return omit_one_operand (type,
7392                              fold (build1 (ABS_EXPR, type, arg1)),
7393                              arg2);
7394
7395   return NULL_TREE;
7396 }
7397
7398 /* Fold a call to builtin isascii.  */
7399
7400 static tree
7401 fold_builtin_isascii (tree arglist)
7402 {
7403   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7404     return 0;
7405   else
7406     {
7407       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7408       tree arg = TREE_VALUE (arglist);
7409
7410       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7411                     build_int_cst (NULL_TREE,
7412                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
7413       arg = fold (build2 (EQ_EXPR, integer_type_node,
7414                           arg, integer_zero_node));
7415
7416       if (in_gimple_form && !TREE_CONSTANT (arg))
7417         return NULL_TREE;
7418       else
7419         return arg;
7420     }
7421 }
7422
7423 /* Fold a call to builtin toascii.  */
7424
7425 static tree
7426 fold_builtin_toascii (tree arglist)
7427 {
7428   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7429     return 0;
7430   else
7431     {
7432       /* Transform toascii(c) -> (c & 0x7f).  */
7433       tree arg = TREE_VALUE (arglist);
7434
7435       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7436                            build_int_cst (NULL_TREE, 0x7f)));
7437     }
7438 }
7439
7440 /* Fold a call to builtin isdigit.  */
7441
7442 static tree
7443 fold_builtin_isdigit (tree arglist)
7444 {
7445   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7446     return 0;
7447   else
7448     {
7449       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7450       /* According to the C standard, isdigit is unaffected by locale.  */
7451       tree arg = TREE_VALUE (arglist);
7452       arg = fold_convert (unsigned_type_node, arg);
7453       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7454                     build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7455       arg = build2 (LE_EXPR, integer_type_node, arg,
7456                     build_int_cst (unsigned_type_node, 9));
7457       arg = fold (arg);
7458       if (in_gimple_form && !TREE_CONSTANT (arg))
7459         return NULL_TREE;
7460       else
7461         return arg;
7462     }
7463 }
7464
7465 /* Fold a call to fabs, fabsf or fabsl.  */
7466
7467 static tree
7468 fold_builtin_fabs (tree arglist, tree type)
7469 {
7470   tree arg;
7471
7472   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7473     return 0;
7474
7475   arg = TREE_VALUE (arglist);
7476   if (TREE_CODE (arg) == REAL_CST)
7477     return fold_abs_const (arg, type);
7478   return fold (build1 (ABS_EXPR, type, arg));
7479 }
7480
7481 /* Fold a call to abs, labs, llabs or imaxabs.  */
7482
7483 static tree
7484 fold_builtin_abs (tree arglist, tree type)
7485 {
7486   tree arg;
7487
7488   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7489     return 0;
7490
7491   arg = TREE_VALUE (arglist);
7492   if (TREE_CODE (arg) == INTEGER_CST)
7493     return fold_abs_const (arg, type);
7494   return fold (build1 (ABS_EXPR, type, arg));
7495 }
7496
7497 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7498    EXP is the CALL_EXPR for the call.  */
7499
7500 static tree
7501 fold_builtin_classify (tree exp, int builtin_index)
7502 {
7503   tree fndecl = get_callee_fndecl (exp);
7504   tree arglist = TREE_OPERAND (exp, 1);
7505   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7506   tree arg;
7507   REAL_VALUE_TYPE r;
7508
7509   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7510     {
7511       /* Check that we have exactly one argument.  */
7512       if (arglist == 0)
7513         {
7514           error ("too few arguments to function %qs",
7515                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7516           return error_mark_node;
7517         }
7518       else if (TREE_CHAIN (arglist) != 0)
7519         {
7520           error ("too many arguments to function %qs",
7521                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7522           return error_mark_node;
7523         }
7524       else
7525         {
7526           error ("non-floating-point argument to function %qs",
7527                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7528           return error_mark_node;
7529         }
7530     }
7531
7532   arg = TREE_VALUE (arglist);
7533   switch (builtin_index)
7534     {
7535     case BUILT_IN_ISINF:
7536       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7537         return omit_one_operand (type, integer_zero_node, arg);
7538
7539       if (TREE_CODE (arg) == REAL_CST)
7540         {
7541           r = TREE_REAL_CST (arg);
7542           if (real_isinf (&r))
7543             return real_compare (GT_EXPR, &r, &dconst0)
7544                    ? integer_one_node : integer_minus_one_node;
7545           else
7546             return integer_zero_node;
7547         }
7548
7549       return NULL_TREE;
7550
7551     case BUILT_IN_FINITE:
7552       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7553           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7554         return omit_one_operand (type, integer_zero_node, arg);
7555
7556       if (TREE_CODE (arg) == REAL_CST)
7557         {
7558           r = TREE_REAL_CST (arg);
7559           return real_isinf (&r) || real_isnan (&r)
7560                  ? integer_zero_node : integer_one_node;
7561         }
7562
7563       return NULL_TREE;
7564
7565     case BUILT_IN_ISNAN:
7566       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7567         return omit_one_operand (type, integer_zero_node, arg);
7568
7569       if (TREE_CODE (arg) == REAL_CST)
7570         {
7571           r = TREE_REAL_CST (arg);
7572           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7573         }
7574
7575       arg = builtin_save_expr (arg);
7576       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7577
7578     default:
7579       gcc_unreachable ();
7580     }
7581 }
7582
7583 /* Fold a call to an unordered comparison function such as
7584    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7585    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7586    the opposite of the desired result.  UNORDERED_CODE is used
7587    for modes that can hold NaNs and ORDERED_CODE is used for
7588    the rest.  */
7589
7590 static tree
7591 fold_builtin_unordered_cmp (tree exp,
7592                             enum tree_code unordered_code,
7593                             enum tree_code ordered_code)
7594 {
7595   tree fndecl = get_callee_fndecl (exp);
7596   tree arglist = TREE_OPERAND (exp, 1);
7597   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7598   enum tree_code code;
7599   tree arg0, arg1;
7600
7601   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7602     {
7603       enum tree_code code0, code1;
7604       tree type0, type1;
7605       tree cmp_type = 0;
7606
7607       /* Check that we have exactly two arguments.  */
7608       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7609         {
7610           error ("too few arguments to function %qs",
7611                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7612           return error_mark_node;
7613         }
7614       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7615         {
7616           error ("too many arguments to function %qs",
7617                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7618           return error_mark_node;
7619         }
7620
7621       arg0 = TREE_VALUE (arglist);
7622       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7623
7624       type0 = TREE_TYPE (arg0);
7625       type1 = TREE_TYPE (arg1);
7626
7627       code0 = TREE_CODE (type0);
7628       code1 = TREE_CODE (type1);
7629
7630       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7631         /* Choose the wider of two real types.  */
7632         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7633                    ? type0 : type1;
7634       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7635         cmp_type = type0;
7636       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7637         cmp_type = type1;
7638       else
7639         {
7640           error ("non-floating-point argument to function %qs",
7641                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7642           return error_mark_node;
7643         }
7644
7645       arg0 = fold_convert (cmp_type, arg0);
7646       arg1 = fold_convert (cmp_type, arg1);
7647     }
7648   else
7649     {
7650       arg0 = TREE_VALUE (arglist);
7651       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7652     }
7653
7654   if (unordered_code == UNORDERED_EXPR)
7655     {
7656       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7657         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7658       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7659     }
7660
7661   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7662                                                       : ordered_code;
7663   return fold (build1 (TRUTH_NOT_EXPR, type,
7664                        fold (build2 (code, type, arg0, arg1))));
7665 }
7666
7667 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7668    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7669    result of the function call is ignored.  This function returns NULL_TREE
7670    if no simplification was possible.  */
7671
7672 static tree
7673 fold_builtin_1 (tree exp, bool ignore)
7674 {
7675   tree fndecl = get_callee_fndecl (exp);
7676   tree arglist = TREE_OPERAND (exp, 1);
7677   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7678
7679   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7680     return targetm.fold_builtin (exp, ignore);
7681
7682   switch (DECL_FUNCTION_CODE (fndecl))
7683     {
7684     case BUILT_IN_FPUTS:
7685       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7686
7687     case BUILT_IN_FPUTS_UNLOCKED:
7688       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7689
7690     case BUILT_IN_STRSTR:
7691       return fold_builtin_strstr (arglist);
7692
7693     case BUILT_IN_STRCAT:
7694       return fold_builtin_strcat (arglist);
7695
7696     case BUILT_IN_STRNCAT:
7697       return fold_builtin_strncat (arglist);
7698
7699     case BUILT_IN_STRSPN:
7700       return fold_builtin_strspn (arglist);
7701
7702     case BUILT_IN_STRCSPN:
7703       return fold_builtin_strcspn (arglist);
7704
7705     case BUILT_IN_STRCHR:
7706     case BUILT_IN_INDEX:
7707       return fold_builtin_strchr (arglist);
7708
7709     case BUILT_IN_STRRCHR:
7710     case BUILT_IN_RINDEX:
7711       return fold_builtin_strrchr (arglist);
7712
7713     case BUILT_IN_STRCPY:
7714       return fold_builtin_strcpy (exp, NULL_TREE);
7715
7716     case BUILT_IN_STRNCPY:
7717       return fold_builtin_strncpy (exp, NULL_TREE);
7718
7719     case BUILT_IN_STRCMP:
7720       return fold_builtin_strcmp (arglist);
7721
7722     case BUILT_IN_STRNCMP:
7723       return fold_builtin_strncmp (arglist);
7724
7725     case BUILT_IN_STRPBRK:
7726       return fold_builtin_strpbrk (arglist);
7727
7728     case BUILT_IN_BCMP:
7729     case BUILT_IN_MEMCMP:
7730       return fold_builtin_memcmp (arglist);
7731
7732     case BUILT_IN_SPRINTF:
7733       return fold_builtin_sprintf (arglist, ignore);
7734
7735     case BUILT_IN_CONSTANT_P:
7736       {
7737         tree val;
7738
7739         val = fold_builtin_constant_p (arglist);
7740         /* Gimplification will pull the CALL_EXPR for the builtin out of
7741            an if condition.  When not optimizing, we'll not CSE it back.
7742            To avoid link error types of regressions, return false now.  */
7743         if (!val && !optimize)
7744           val = integer_zero_node;
7745
7746         return val;
7747       }
7748
7749     case BUILT_IN_EXPECT:
7750       return fold_builtin_expect (arglist);
7751
7752     case BUILT_IN_CLASSIFY_TYPE:
7753       return fold_builtin_classify_type (arglist);
7754
7755     case BUILT_IN_STRLEN:
7756       return fold_builtin_strlen (arglist);
7757
7758     case BUILT_IN_FABS:
7759     case BUILT_IN_FABSF:
7760     case BUILT_IN_FABSL:
7761       return fold_builtin_fabs (arglist, type);
7762
7763     case BUILT_IN_ABS:
7764     case BUILT_IN_LABS:
7765     case BUILT_IN_LLABS:
7766     case BUILT_IN_IMAXABS:
7767       return fold_builtin_abs (arglist, type);
7768
7769     case BUILT_IN_CONJ:
7770     case BUILT_IN_CONJF:
7771     case BUILT_IN_CONJL:
7772       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7773         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7774       break;
7775
7776     case BUILT_IN_CREAL:
7777     case BUILT_IN_CREALF:
7778     case BUILT_IN_CREALL:
7779       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7780         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7781                                          TREE_VALUE (arglist))));
7782       break;
7783
7784     case BUILT_IN_CIMAG:
7785     case BUILT_IN_CIMAGF:
7786     case BUILT_IN_CIMAGL:
7787       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7788         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7789                                          TREE_VALUE (arglist))));
7790       break;
7791
7792     case BUILT_IN_CABS:
7793     case BUILT_IN_CABSF:
7794     case BUILT_IN_CABSL:
7795       return fold_builtin_cabs (arglist, type);
7796
7797     case BUILT_IN_SQRT:
7798     case BUILT_IN_SQRTF:
7799     case BUILT_IN_SQRTL:
7800       return fold_builtin_sqrt (arglist, type);
7801
7802     case BUILT_IN_CBRT:
7803     case BUILT_IN_CBRTF:
7804     case BUILT_IN_CBRTL:
7805       return fold_builtin_cbrt (arglist, type);
7806
7807     case BUILT_IN_SIN:
7808     case BUILT_IN_SINF:
7809     case BUILT_IN_SINL:
7810       return fold_builtin_sin (arglist);
7811
7812     case BUILT_IN_COS:
7813     case BUILT_IN_COSF:
7814     case BUILT_IN_COSL:
7815       return fold_builtin_cos (arglist, type, fndecl);
7816
7817     case BUILT_IN_EXP:
7818     case BUILT_IN_EXPF:
7819     case BUILT_IN_EXPL:
7820       return fold_builtin_exponent (exp, &dconste);
7821
7822     case BUILT_IN_EXP2:
7823     case BUILT_IN_EXP2F:
7824     case BUILT_IN_EXP2L:
7825       return fold_builtin_exponent (exp, &dconst2);
7826
7827     case BUILT_IN_EXP10:
7828     case BUILT_IN_EXP10F:
7829     case BUILT_IN_EXP10L:
7830     case BUILT_IN_POW10:
7831     case BUILT_IN_POW10F:
7832     case BUILT_IN_POW10L:
7833       return fold_builtin_exponent (exp, &dconst10);
7834
7835     case BUILT_IN_LOG:
7836     case BUILT_IN_LOGF:
7837     case BUILT_IN_LOGL:
7838       return fold_builtin_logarithm (exp, &dconste);
7839
7840     case BUILT_IN_LOG2:
7841     case BUILT_IN_LOG2F:
7842     case BUILT_IN_LOG2L:
7843       return fold_builtin_logarithm (exp, &dconst2);
7844
7845     case BUILT_IN_LOG10:
7846     case BUILT_IN_LOG10F:
7847     case BUILT_IN_LOG10L:
7848       return fold_builtin_logarithm (exp, &dconst10);
7849
7850     case BUILT_IN_TAN:
7851     case BUILT_IN_TANF:
7852     case BUILT_IN_TANL:
7853       return fold_builtin_tan (arglist);
7854
7855     case BUILT_IN_ATAN:
7856     case BUILT_IN_ATANF:
7857     case BUILT_IN_ATANL:
7858       return fold_builtin_atan (arglist, type);
7859
7860     case BUILT_IN_POW:
7861     case BUILT_IN_POWF:
7862     case BUILT_IN_POWL:
7863       return fold_builtin_pow (fndecl, arglist, type);
7864
7865     case BUILT_IN_INF:
7866     case BUILT_IN_INFF:
7867     case BUILT_IN_INFL:
7868       return fold_builtin_inf (type, true);
7869
7870     case BUILT_IN_HUGE_VAL:
7871     case BUILT_IN_HUGE_VALF:
7872     case BUILT_IN_HUGE_VALL:
7873       return fold_builtin_inf (type, false);
7874
7875     case BUILT_IN_NAN:
7876     case BUILT_IN_NANF:
7877     case BUILT_IN_NANL:
7878       return fold_builtin_nan (arglist, type, true);
7879
7880     case BUILT_IN_NANS:
7881     case BUILT_IN_NANSF:
7882     case BUILT_IN_NANSL:
7883       return fold_builtin_nan (arglist, type, false);
7884
7885     case BUILT_IN_FLOOR:
7886     case BUILT_IN_FLOORF:
7887     case BUILT_IN_FLOORL:
7888       return fold_builtin_floor (exp);
7889
7890     case BUILT_IN_CEIL:
7891     case BUILT_IN_CEILF:
7892     case BUILT_IN_CEILL:
7893       return fold_builtin_ceil (exp);
7894
7895     case BUILT_IN_TRUNC:
7896     case BUILT_IN_TRUNCF:
7897     case BUILT_IN_TRUNCL:
7898       return fold_builtin_trunc (exp);
7899
7900     case BUILT_IN_ROUND:
7901     case BUILT_IN_ROUNDF:
7902     case BUILT_IN_ROUNDL:
7903       return fold_builtin_round (exp);
7904
7905     case BUILT_IN_NEARBYINT:
7906     case BUILT_IN_NEARBYINTF:
7907     case BUILT_IN_NEARBYINTL:
7908     case BUILT_IN_RINT:
7909     case BUILT_IN_RINTF:
7910     case BUILT_IN_RINTL:
7911       return fold_trunc_transparent_mathfn (exp);
7912
7913     case BUILT_IN_LROUND:
7914     case BUILT_IN_LROUNDF:
7915     case BUILT_IN_LROUNDL:
7916     case BUILT_IN_LLROUND:
7917     case BUILT_IN_LLROUNDF:
7918     case BUILT_IN_LLROUNDL:
7919       return fold_builtin_lround (exp);
7920
7921     case BUILT_IN_LRINT:
7922     case BUILT_IN_LRINTF:
7923     case BUILT_IN_LRINTL:
7924     case BUILT_IN_LLRINT:
7925     case BUILT_IN_LLRINTF:
7926     case BUILT_IN_LLRINTL:
7927       return fold_fixed_mathfn (exp);
7928
7929     case BUILT_IN_FFS:
7930     case BUILT_IN_FFSL:
7931     case BUILT_IN_FFSLL:
7932     case BUILT_IN_CLZ:
7933     case BUILT_IN_CLZL:
7934     case BUILT_IN_CLZLL:
7935     case BUILT_IN_CTZ:
7936     case BUILT_IN_CTZL:
7937     case BUILT_IN_CTZLL:
7938     case BUILT_IN_POPCOUNT:
7939     case BUILT_IN_POPCOUNTL:
7940     case BUILT_IN_POPCOUNTLL:
7941     case BUILT_IN_PARITY:
7942     case BUILT_IN_PARITYL:
7943     case BUILT_IN_PARITYLL:
7944       return fold_builtin_bitop (exp);
7945
7946     case BUILT_IN_MEMCPY:
7947       return fold_builtin_memcpy (exp);
7948
7949     case BUILT_IN_MEMPCPY:
7950       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
7951
7952     case BUILT_IN_MEMMOVE:
7953       return fold_builtin_memmove (arglist, type);
7954
7955     case BUILT_IN_SIGNBIT:
7956     case BUILT_IN_SIGNBITF:
7957     case BUILT_IN_SIGNBITL:
7958       return fold_builtin_signbit (exp);
7959
7960     case BUILT_IN_ISASCII:
7961       return fold_builtin_isascii (arglist);
7962
7963     case BUILT_IN_TOASCII:
7964       return fold_builtin_toascii (arglist);
7965
7966     case BUILT_IN_ISDIGIT:
7967       return fold_builtin_isdigit (arglist);
7968
7969     case BUILT_IN_COPYSIGN:
7970     case BUILT_IN_COPYSIGNF:
7971     case BUILT_IN_COPYSIGNL:
7972       return fold_builtin_copysign (arglist, type);
7973
7974     case BUILT_IN_FINITE:
7975     case BUILT_IN_FINITEF:
7976     case BUILT_IN_FINITEL:
7977       return fold_builtin_classify (exp, BUILT_IN_FINITE);
7978
7979     case BUILT_IN_ISINF:
7980     case BUILT_IN_ISINFF:
7981     case BUILT_IN_ISINFL:
7982       return fold_builtin_classify (exp, BUILT_IN_ISINF);
7983
7984     case BUILT_IN_ISNAN:
7985     case BUILT_IN_ISNANF:
7986     case BUILT_IN_ISNANL:
7987       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
7988
7989     case BUILT_IN_ISGREATER:
7990       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
7991     case BUILT_IN_ISGREATEREQUAL:
7992       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
7993     case BUILT_IN_ISLESS:
7994       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
7995     case BUILT_IN_ISLESSEQUAL:
7996       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
7997     case BUILT_IN_ISLESSGREATER:
7998       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
7999     case BUILT_IN_ISUNORDERED:
8000       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8001
8002       /* We do the folding for va_start in the expander.  */
8003     case BUILT_IN_VA_START:
8004       break;
8005
8006     default:
8007       break;
8008     }
8009
8010   return 0;
8011 }
8012
8013 /* A wrapper function for builtin folding that prevents warnings for
8014    "statement without effect" and the like, caused by removing the
8015    call node earlier than the warning is generated.  */
8016
8017 tree
8018 fold_builtin (tree exp, bool ignore)
8019 {
8020   exp = fold_builtin_1 (exp, ignore);
8021   if (exp)
8022     {
8023       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8024       if (CONSTANT_CLASS_P (exp))
8025         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8026       TREE_NO_WARNING (exp) = 1;
8027     }
8028
8029   return exp;
8030 }
8031
8032 /* Conveniently construct a function call expression.  */
8033
8034 tree
8035 build_function_call_expr (tree fn, tree arglist)
8036 {
8037   tree call_expr;
8038
8039   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8040   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8041                       call_expr, arglist, NULL_TREE);
8042   return fold (call_expr);
8043 }
8044
8045 /* This function validates the types of a function call argument list
8046    represented as a tree chain of parameters against a specified list
8047    of tree_codes.  If the last specifier is a 0, that represents an
8048    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8049
8050 static int
8051 validate_arglist (tree arglist, ...)
8052 {
8053   enum tree_code code;
8054   int res = 0;
8055   va_list ap;
8056
8057   va_start (ap, arglist);
8058
8059   do
8060     {
8061       code = va_arg (ap, enum tree_code);
8062       switch (code)
8063         {
8064         case 0:
8065           /* This signifies an ellipses, any further arguments are all ok.  */
8066           res = 1;
8067           goto end;
8068         case VOID_TYPE:
8069           /* This signifies an endlink, if no arguments remain, return
8070              true, otherwise return false.  */
8071           res = arglist == 0;
8072           goto end;
8073         default:
8074           /* If no parameters remain or the parameter's code does not
8075              match the specified code, return false.  Otherwise continue
8076              checking any remaining arguments.  */
8077           if (arglist == 0
8078               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8079             goto end;
8080           break;
8081         }
8082       arglist = TREE_CHAIN (arglist);
8083     }
8084   while (1);
8085
8086   /* We need gotos here since we can only have one VA_CLOSE in a
8087      function.  */
8088  end: ;
8089   va_end (ap);
8090
8091   return res;
8092 }
8093
8094 /* Default target-specific builtin expander that does nothing.  */
8095
8096 rtx
8097 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8098                         rtx target ATTRIBUTE_UNUSED,
8099                         rtx subtarget ATTRIBUTE_UNUSED,
8100                         enum machine_mode mode ATTRIBUTE_UNUSED,
8101                         int ignore ATTRIBUTE_UNUSED)
8102 {
8103   return NULL_RTX;
8104 }
8105
8106 /* Returns true is EXP represents data that would potentially reside
8107    in a readonly section.  */
8108
8109 static bool
8110 readonly_data_expr (tree exp)
8111 {
8112   STRIP_NOPS (exp);
8113
8114   if (TREE_CODE (exp) != ADDR_EXPR)
8115     return false;
8116
8117   exp = get_base_address (TREE_OPERAND (exp, 0));
8118   if (!exp)
8119     return false;
8120
8121   /* Make sure we call decl_readonly_section only for trees it
8122      can handle (since it returns true for everything it doesn't
8123      understand).  */
8124   if (TREE_CODE (exp) == STRING_CST
8125       || TREE_CODE (exp) == CONSTRUCTOR
8126       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8127     return decl_readonly_section (exp, 0);
8128   else
8129     return false;
8130 }
8131
8132 /* Simplify a call to the strstr builtin.
8133
8134    Return 0 if no simplification was possible, otherwise return the
8135    simplified form of the call as a tree.
8136
8137    The simplified form may be a constant or other expression which
8138    computes the same value, but in a more efficient manner (including
8139    calls to other builtin functions).
8140
8141    The call may contain arguments which need to be evaluated, but
8142    which are not useful to determine the result of the call.  In
8143    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8144    COMPOUND_EXPR will be an argument which must be evaluated.
8145    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8146    COMPOUND_EXPR in the chain will contain the tree for the simplified
8147    form of the builtin function call.  */
8148
8149 static tree
8150 fold_builtin_strstr (tree arglist)
8151 {
8152   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8153     return 0;
8154   else
8155     {
8156       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8157       tree fn;
8158       const char *p1, *p2;
8159
8160       p2 = c_getstr (s2);
8161       if (p2 == NULL)
8162         return 0;
8163
8164       p1 = c_getstr (s1);
8165       if (p1 != NULL)
8166         {
8167           const char *r = strstr (p1, p2);
8168
8169           if (r == NULL)
8170             return build_int_cst (TREE_TYPE (s1), 0);
8171
8172           /* Return an offset into the constant string argument.  */
8173           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8174                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8175         }
8176
8177       if (p2[0] == '\0')
8178         return s1;
8179
8180       if (p2[1] != '\0')
8181         return 0;
8182
8183       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8184       if (!fn)
8185         return 0;
8186
8187       /* New argument list transforming strstr(s1, s2) to
8188          strchr(s1, s2[0]).  */
8189       arglist = build_tree_list (NULL_TREE,
8190                                  build_int_cst (NULL_TREE, p2[0]));
8191       arglist = tree_cons (NULL_TREE, s1, arglist);
8192       return build_function_call_expr (fn, arglist);
8193     }
8194 }
8195
8196 /* Simplify a call to the strchr builtin.
8197
8198    Return 0 if no simplification was possible, otherwise return the
8199    simplified form of the call as a tree.
8200
8201    The simplified form may be a constant or other expression which
8202    computes the same value, but in a more efficient manner (including
8203    calls to other builtin functions).
8204
8205    The call may contain arguments which need to be evaluated, but
8206    which are not useful to determine the result of the call.  In
8207    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8208    COMPOUND_EXPR will be an argument which must be evaluated.
8209    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8210    COMPOUND_EXPR in the chain will contain the tree for the simplified
8211    form of the builtin function call.  */
8212
8213 static tree
8214 fold_builtin_strchr (tree arglist)
8215 {
8216   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8217     return 0;
8218   else
8219     {
8220       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8221       const char *p1;
8222
8223       if (TREE_CODE (s2) != INTEGER_CST)
8224         return 0;
8225
8226       p1 = c_getstr (s1);
8227       if (p1 != NULL)
8228         {
8229           char c;
8230           const char *r;
8231
8232           if (target_char_cast (s2, &c))
8233             return 0;
8234
8235           r = strchr (p1, c);
8236
8237           if (r == NULL)
8238             return build_int_cst (TREE_TYPE (s1), 0);
8239
8240           /* Return an offset into the constant string argument.  */
8241           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8242                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8243         }
8244       return 0;
8245     }
8246 }
8247
8248 /* Simplify a call to the strrchr builtin.
8249
8250    Return 0 if no simplification was possible, otherwise return the
8251    simplified form of the call as a tree.
8252
8253    The simplified form may be a constant or other expression which
8254    computes the same value, but in a more efficient manner (including
8255    calls to other builtin functions).
8256
8257    The call may contain arguments which need to be evaluated, but
8258    which are not useful to determine the result of the call.  In
8259    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8260    COMPOUND_EXPR will be an argument which must be evaluated.
8261    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8262    COMPOUND_EXPR in the chain will contain the tree for the simplified
8263    form of the builtin function call.  */
8264
8265 static tree
8266 fold_builtin_strrchr (tree arglist)
8267 {
8268   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8269     return 0;
8270   else
8271     {
8272       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8273       tree fn;
8274       const char *p1;
8275
8276       if (TREE_CODE (s2) != INTEGER_CST)
8277         return 0;
8278
8279       p1 = c_getstr (s1);
8280       if (p1 != NULL)
8281         {
8282           char c;
8283           const char *r;
8284
8285           if (target_char_cast (s2, &c))
8286             return 0;
8287
8288           r = strrchr (p1, c);
8289
8290           if (r == NULL)
8291             return build_int_cst (TREE_TYPE (s1), 0);
8292
8293           /* Return an offset into the constant string argument.  */
8294           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8295                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8296         }
8297
8298       if (! integer_zerop (s2))
8299         return 0;
8300
8301       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8302       if (!fn)
8303         return 0;
8304
8305       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8306       return build_function_call_expr (fn, arglist);
8307     }
8308 }
8309
8310 /* Simplify a call to the strpbrk builtin.
8311
8312    Return 0 if no simplification was possible, otherwise return the
8313    simplified form of the call as a tree.
8314
8315    The simplified form may be a constant or other expression which
8316    computes the same value, but in a more efficient manner (including
8317    calls to other builtin functions).
8318
8319    The call may contain arguments which need to be evaluated, but
8320    which are not useful to determine the result of the call.  In
8321    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8322    COMPOUND_EXPR will be an argument which must be evaluated.
8323    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8324    COMPOUND_EXPR in the chain will contain the tree for the simplified
8325    form of the builtin function call.  */
8326
8327 static tree
8328 fold_builtin_strpbrk (tree arglist)
8329 {
8330   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8331     return 0;
8332   else
8333     {
8334       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8335       tree fn;
8336       const char *p1, *p2;
8337
8338       p2 = c_getstr (s2);
8339       if (p2 == NULL)
8340         return 0;
8341
8342       p1 = c_getstr (s1);
8343       if (p1 != NULL)
8344         {
8345           const char *r = strpbrk (p1, p2);
8346
8347           if (r == NULL)
8348             return build_int_cst (TREE_TYPE (s1), 0);
8349
8350           /* Return an offset into the constant string argument.  */
8351           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8352                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8353         }
8354
8355       if (p2[0] == '\0')
8356         /* strpbrk(x, "") == NULL.
8357            Evaluate and ignore s1 in case it had side-effects.  */
8358         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8359
8360       if (p2[1] != '\0')
8361         return 0;  /* Really call strpbrk.  */
8362
8363       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8364       if (!fn)
8365         return 0;
8366
8367       /* New argument list transforming strpbrk(s1, s2) to
8368          strchr(s1, s2[0]).  */
8369       arglist = build_tree_list (NULL_TREE,
8370                                  build_int_cst (NULL_TREE, p2[0]));
8371       arglist = tree_cons (NULL_TREE, s1, arglist);
8372       return build_function_call_expr (fn, arglist);
8373     }
8374 }
8375
8376 /* Simplify a call to the strcat builtin.
8377
8378    Return 0 if no simplification was possible, otherwise return the
8379    simplified form of the call as a tree.
8380
8381    The simplified form may be a constant or other expression which
8382    computes the same value, but in a more efficient manner (including
8383    calls to other builtin functions).
8384
8385    The call may contain arguments which need to be evaluated, but
8386    which are not useful to determine the result of the call.  In
8387    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8388    COMPOUND_EXPR will be an argument which must be evaluated.
8389    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8390    COMPOUND_EXPR in the chain will contain the tree for the simplified
8391    form of the builtin function call.  */
8392
8393 static tree
8394 fold_builtin_strcat (tree arglist)
8395 {
8396   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8397     return 0;
8398   else
8399     {
8400       tree dst = TREE_VALUE (arglist),
8401         src = TREE_VALUE (TREE_CHAIN (arglist));
8402       const char *p = c_getstr (src);
8403
8404       /* If the string length is zero, return the dst parameter.  */
8405       if (p && *p == '\0')
8406         return dst;
8407
8408       return 0;
8409     }
8410 }
8411
8412 /* Simplify a call to the strncat builtin.
8413
8414    Return 0 if no simplification was possible, otherwise return the
8415    simplified form of the call as a tree.
8416
8417    The simplified form may be a constant or other expression which
8418    computes the same value, but in a more efficient manner (including
8419    calls to other builtin functions).
8420
8421    The call may contain arguments which need to be evaluated, but
8422    which are not useful to determine the result of the call.  In
8423    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8424    COMPOUND_EXPR will be an argument which must be evaluated.
8425    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8426    COMPOUND_EXPR in the chain will contain the tree for the simplified
8427    form of the builtin function call.  */
8428
8429 static tree
8430 fold_builtin_strncat (tree arglist)
8431 {
8432   if (!validate_arglist (arglist,
8433                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8434     return 0;
8435   else
8436     {
8437       tree dst = TREE_VALUE (arglist);
8438       tree src = TREE_VALUE (TREE_CHAIN (arglist));
8439       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8440       const char *p = c_getstr (src);
8441
8442       /* If the requested length is zero, or the src parameter string
8443           length is zero, return the dst parameter.  */
8444       if (integer_zerop (len) || (p && *p == '\0'))
8445         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8446
8447       /* If the requested len is greater than or equal to the string
8448          length, call strcat.  */
8449       if (TREE_CODE (len) == INTEGER_CST && p
8450           && compare_tree_int (len, strlen (p)) >= 0)
8451         {
8452           tree newarglist
8453             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8454           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8455
8456           /* If the replacement _DECL isn't initialized, don't do the
8457              transformation.  */
8458           if (!fn)
8459             return 0;
8460
8461           return build_function_call_expr (fn, newarglist);
8462         }
8463       return 0;
8464     }
8465 }
8466
8467 /* Simplify a call to the strspn builtin.
8468
8469    Return 0 if no simplification was possible, otherwise return the
8470    simplified form of the call as a tree.
8471
8472    The simplified form may be a constant or other expression which
8473    computes the same value, but in a more efficient manner (including
8474    calls to other builtin functions).
8475
8476    The call may contain arguments which need to be evaluated, but
8477    which are not useful to determine the result of the call.  In
8478    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8479    COMPOUND_EXPR will be an argument which must be evaluated.
8480    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8481    COMPOUND_EXPR in the chain will contain the tree for the simplified
8482    form of the builtin function call.  */
8483
8484 static tree
8485 fold_builtin_strspn (tree arglist)
8486 {
8487   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8488     return 0;
8489   else
8490     {
8491       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8492       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8493
8494       /* If both arguments are constants, evaluate at compile-time.  */
8495       if (p1 && p2)
8496         {
8497           const size_t r = strspn (p1, p2);
8498           return size_int (r);
8499         }
8500
8501       /* If either argument is "", return 0.  */
8502       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8503         /* Evaluate and ignore both arguments in case either one has
8504            side-effects.  */
8505         return omit_two_operands (integer_type_node, integer_zero_node,
8506                                   s1, s2);
8507       return 0;
8508     }
8509 }
8510
8511 /* Simplify a call to the strcspn builtin.
8512
8513    Return 0 if no simplification was possible, otherwise return the
8514    simplified form of the call as a tree.
8515
8516    The simplified form may be a constant or other expression which
8517    computes the same value, but in a more efficient manner (including
8518    calls to other builtin functions).
8519
8520    The call may contain arguments which need to be evaluated, but
8521    which are not useful to determine the result of the call.  In
8522    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8523    COMPOUND_EXPR will be an argument which must be evaluated.
8524    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8525    COMPOUND_EXPR in the chain will contain the tree for the simplified
8526    form of the builtin function call.  */
8527
8528 static tree
8529 fold_builtin_strcspn (tree arglist)
8530 {
8531   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8532     return 0;
8533   else
8534     {
8535       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8536       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8537
8538       /* If both arguments are constants, evaluate at compile-time.  */
8539       if (p1 && p2)
8540         {
8541           const size_t r = strcspn (p1, p2);
8542           return size_int (r);
8543         }
8544
8545       /* If the first argument is "", return 0.  */
8546       if (p1 && *p1 == '\0')
8547         {
8548           /* Evaluate and ignore argument s2 in case it has
8549              side-effects.  */
8550           return omit_one_operand (integer_type_node,
8551                                    integer_zero_node, s2);
8552         }
8553
8554       /* If the second argument is "", return __builtin_strlen(s1).  */
8555       if (p2 && *p2 == '\0')
8556         {
8557           tree newarglist = build_tree_list (NULL_TREE, s1),
8558             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8559
8560           /* If the replacement _DECL isn't initialized, don't do the
8561              transformation.  */
8562           if (!fn)
8563             return 0;
8564
8565           return build_function_call_expr (fn, newarglist);
8566         }
8567       return 0;
8568     }
8569 }
8570
8571 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
8572    by the builtin will be ignored.  UNLOCKED is true is true if this
8573    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
8574    the known length of the string.  Return NULL_TREE if no simplification
8575    was possible.  */
8576
8577 tree
8578 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8579 {
8580   tree fn;
8581   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8582     : implicit_built_in_decls[BUILT_IN_FPUTC];
8583   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8584     : implicit_built_in_decls[BUILT_IN_FWRITE];
8585
8586   /* If the return value is used, or the replacement _DECL isn't
8587      initialized, don't do the transformation.  */
8588   if (!ignore || !fn_fputc || !fn_fwrite)
8589     return 0;
8590
8591   /* Verify the arguments in the original call.  */
8592   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8593     return 0;
8594
8595   if (! len)
8596     len = c_strlen (TREE_VALUE (arglist), 0);
8597
8598   /* Get the length of the string passed to fputs.  If the length
8599      can't be determined, punt.  */
8600   if (!len
8601       || TREE_CODE (len) != INTEGER_CST)
8602     return 0;
8603
8604   switch (compare_tree_int (len, 1))
8605     {
8606     case -1: /* length is 0, delete the call entirely .  */
8607       return omit_one_operand (integer_type_node, integer_zero_node,
8608                                TREE_VALUE (TREE_CHAIN (arglist)));
8609
8610     case 0: /* length is 1, call fputc.  */
8611       {
8612         const char *p = c_getstr (TREE_VALUE (arglist));
8613
8614         if (p != NULL)
8615           {
8616             /* New argument list transforming fputs(string, stream) to
8617                fputc(string[0], stream).  */
8618             arglist = build_tree_list (NULL_TREE,
8619                                        TREE_VALUE (TREE_CHAIN (arglist)));
8620             arglist = tree_cons (NULL_TREE,
8621                                  build_int_cst (NULL_TREE, p[0]),
8622                                  arglist);
8623             fn = fn_fputc;
8624             break;
8625           }
8626       }
8627       /* FALLTHROUGH */
8628     case 1: /* length is greater than 1, call fwrite.  */
8629       {
8630         tree string_arg;
8631
8632         /* If optimizing for size keep fputs.  */
8633         if (optimize_size)
8634           return 0;
8635         string_arg = TREE_VALUE (arglist);
8636         /* New argument list transforming fputs(string, stream) to
8637            fwrite(string, 1, len, stream).  */
8638         arglist = build_tree_list (NULL_TREE,
8639                                    TREE_VALUE (TREE_CHAIN (arglist)));
8640         arglist = tree_cons (NULL_TREE, len, arglist);
8641         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8642         arglist = tree_cons (NULL_TREE, string_arg, arglist);
8643         fn = fn_fwrite;
8644         break;
8645       }
8646     default:
8647       gcc_unreachable ();
8648     }
8649
8650   /* These optimizations are only performed when the result is ignored,
8651      hence there's no need to cast the result to integer_type_node.  */
8652   return build_function_call_expr (fn, arglist);
8653 }
8654
8655 static void
8656 fold_builtin_next_arg (tree arglist)
8657 {
8658   tree fntype = TREE_TYPE (current_function_decl);
8659
8660   if (TYPE_ARG_TYPES (fntype) == 0
8661       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8662           == void_type_node))
8663     error ("%<va_start%> used in function with fixed args");
8664   else if (arglist)
8665     {
8666       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8667       tree arg = TREE_VALUE (arglist);
8668
8669       /* Strip off all nops for the sake of the comparison.  This
8670          is not quite the same as STRIP_NOPS.  It does more.
8671          We must also strip off INDIRECT_EXPR for C++ reference
8672          parameters.  */
8673       while (TREE_CODE (arg) == NOP_EXPR
8674              || TREE_CODE (arg) == CONVERT_EXPR
8675              || TREE_CODE (arg) == NON_LVALUE_EXPR
8676              || TREE_CODE (arg) == INDIRECT_REF)
8677         arg = TREE_OPERAND (arg, 0);
8678       if (arg != last_parm)
8679         warning ("second parameter of %<va_start%> not last named argument");
8680       TREE_VALUE (arglist) = arg;
8681     }
8682   else
8683     /* Evidently an out of date version of <stdarg.h>; can't validate
8684        va_start's second argument, but can still work as intended.  */
8685     warning ("%<__builtin_next_arg%> called without an argument");
8686 }
8687
8688
8689 /* Simplify a call to the sprintf builtin.
8690
8691    Return 0 if no simplification was possible, otherwise return the
8692    simplified form of the call as a tree.  If IGNORED is true, it means that
8693    the caller does not use the returned value of the function.  */
8694
8695 static tree
8696 fold_builtin_sprintf (tree arglist, int ignored)
8697 {
8698   tree call, retval, dest, fmt;
8699   const char *fmt_str = NULL;
8700
8701   /* Verify the required arguments in the original call.  We deal with two
8702      types of sprintf() calls: 'sprintf (str, fmt)' and
8703      'sprintf (dest, "%s", orig)'.  */
8704   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8705       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8706                             VOID_TYPE))
8707     return NULL_TREE;
8708
8709   /* Get the destination string and the format specifier.  */
8710   dest = TREE_VALUE (arglist);
8711   fmt = TREE_VALUE (TREE_CHAIN (arglist));
8712
8713   /* Check whether the format is a literal string constant.  */
8714   fmt_str = c_getstr (fmt);
8715   if (fmt_str == NULL)
8716     return NULL_TREE;
8717
8718   call = NULL_TREE;
8719   retval = NULL_TREE;
8720
8721   /* If the format doesn't contain % args or %%, use strcpy.  */
8722   if (strchr (fmt_str, '%') == NULL)
8723     {
8724       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8725
8726       if (!fn)
8727         return NULL_TREE;
8728
8729       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8730          'format' is known to contain no % formats.  */
8731       arglist = build_tree_list (NULL_TREE, fmt);
8732       arglist = tree_cons (NULL_TREE, dest, arglist);
8733       call = build_function_call_expr (fn, arglist);
8734       if (!ignored)
8735         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
8736     }
8737
8738   /* If the format is "%s", use strcpy if the result isn't used.  */
8739   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
8740     {
8741       tree fn, orig;
8742       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8743
8744       if (!fn)
8745         return NULL_TREE;
8746
8747       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
8748       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8749       arglist = build_tree_list (NULL_TREE, orig);
8750       arglist = tree_cons (NULL_TREE, dest, arglist);
8751       if (!ignored)
8752         {
8753           retval = c_strlen (orig, 1);
8754           if (!retval || TREE_CODE (retval) != INTEGER_CST)
8755             return NULL_TREE;
8756         }
8757       call = build_function_call_expr (fn, arglist);
8758     }
8759
8760   if (call && retval)
8761     {
8762       retval = convert
8763         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
8764          retval);
8765       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
8766     }
8767   else
8768     return call;
8769 }