OSDN Git Service

PR c/17301
[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 (!chain)
3865     {
3866       error ("too few arguments to function %<va_start%>");
3867       return const0_rtx;
3868     }
3869   if (TREE_CHAIN (chain))
3870     error ("too many arguments to function %<va_start%>");
3871
3872   fold_builtin_next_arg (chain);
3873
3874   nextarg = expand_builtin_next_arg (chain);
3875   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3876
3877 #ifdef EXPAND_BUILTIN_VA_START
3878   EXPAND_BUILTIN_VA_START (valist, nextarg);
3879 #else
3880   std_expand_builtin_va_start (valist, nextarg);
3881 #endif
3882
3883   return const0_rtx;
3884 }
3885
3886 /* The "standard" implementation of va_arg: read the value from the
3887    current (padded) address and increment by the (padded) size.  */
3888
3889 tree
3890 std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
3891 {
3892   tree addr, t, type_size, rounded_size, valist_tmp;
3893   unsigned HOST_WIDE_INT align, boundary;
3894   bool indirect;
3895
3896 #ifdef ARGS_GROW_DOWNWARD
3897   /* All of the alignment and movement below is for args-grow-up machines.
3898      As of 2004, there are only 3 ARGS_GROW_DOWNWARD targets, and they all
3899      implement their own specialized gimplify_va_arg_expr routines.  */
3900   gcc_unreachable ();
3901 #endif
3902
3903   indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
3904   if (indirect)
3905     type = build_pointer_type (type);
3906
3907   align = PARM_BOUNDARY / BITS_PER_UNIT;
3908   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type) / BITS_PER_UNIT;
3909
3910   /* Hoist the valist value into a temporary for the moment.  */
3911   valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
3912
3913   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
3914      requires greater alignment, we must perform dynamic alignment.  */
3915   if (boundary > align)
3916     {
3917       t = fold_convert (TREE_TYPE (valist), size_int (boundary - 1));
3918       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3919                   build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t));
3920       gimplify_and_add (t, pre_p);
3921
3922       t = fold_convert (TREE_TYPE (valist), size_int (-boundary));
3923       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
3924                   build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp, t));
3925       gimplify_and_add (t, pre_p);
3926     }
3927
3928   /* Compute the rounded size of the type.  */
3929   type_size = size_in_bytes (type);
3930   rounded_size = round_up (type_size, align);
3931
3932   /* Reduce rounded_size so it's sharable with the postqueue.  */
3933   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
3934
3935   /* Get AP.  */
3936   addr = valist_tmp;
3937   if (PAD_VARARGS_DOWN && !integer_zerop (rounded_size))
3938     {
3939       /* Small args are padded downward.  */
3940       t = fold (build2 (GT_EXPR, sizetype, rounded_size, size_int (align)));
3941       t = fold (build3 (COND_EXPR, sizetype, t, size_zero_node,
3942                         size_binop (MINUS_EXPR, rounded_size, type_size)));
3943       t = fold_convert (TREE_TYPE (addr), t);
3944       addr = fold (build2 (PLUS_EXPR, TREE_TYPE (addr), addr, t));
3945     }
3946
3947   /* Compute new value for AP.  */
3948   t = fold_convert (TREE_TYPE (valist), rounded_size);
3949   t = build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp, t);
3950   t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
3951   gimplify_and_add (t, pre_p);
3952
3953   addr = fold_convert (build_pointer_type (type), addr);
3954
3955   if (indirect)
3956     addr = build_va_arg_indirect_ref (addr);
3957
3958   return build_va_arg_indirect_ref (addr);
3959 }
3960
3961 /* Build an indirect-ref expression over the given TREE, which represents a
3962    piece of a va_arg() expansion.  */
3963 tree
3964 build_va_arg_indirect_ref (tree addr)
3965 {
3966   addr = build_fold_indirect_ref (addr);
3967
3968   if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF.  */
3969     mf_mark (addr);
3970
3971   return addr;
3972 }
3973
3974 /* Return a dummy expression of type TYPE in order to keep going after an
3975    error.  */
3976
3977 static tree
3978 dummy_object (tree type)
3979 {
3980   tree t = convert (build_pointer_type (type), null_pointer_node);
3981   return build1 (INDIRECT_REF, type, t);
3982 }
3983
3984 /* Gimplify __builtin_va_arg, aka VA_ARG_EXPR, which is not really a
3985    builtin function, but a very special sort of operator.  */
3986
3987 enum gimplify_status
3988 gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
3989 {
3990   tree promoted_type, want_va_type, have_va_type;
3991   tree valist = TREE_OPERAND (*expr_p, 0);
3992   tree type = TREE_TYPE (*expr_p);
3993   tree t;
3994
3995   /* Verify that valist is of the proper type.  */
3996   want_va_type = va_list_type_node;
3997   have_va_type = TREE_TYPE (valist);
3998
3999   if (have_va_type == error_mark_node)
4000     return GS_ERROR;
4001
4002   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4003     {
4004       /* If va_list is an array type, the argument may have decayed
4005          to a pointer type, e.g. by being passed to another function.
4006          In that case, unwrap both types so that we can compare the
4007          underlying records.  */
4008       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4009           || TREE_CODE (have_va_type) == POINTER_TYPE)
4010         {
4011           want_va_type = TREE_TYPE (want_va_type);
4012           have_va_type = TREE_TYPE (have_va_type);
4013         }
4014     }
4015
4016   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4017     {
4018       error ("first argument to %<va_arg%> not of type %<va_list%>");
4019       return GS_ERROR;
4020     }
4021
4022   /* Generate a diagnostic for requesting data of a type that cannot
4023      be passed through `...' due to type promotion at the call site.  */
4024   else if ((promoted_type = lang_hooks.types.type_promotes_to (type))
4025            != type)
4026     {
4027       static bool gave_help;
4028
4029       /* Unfortunately, this is merely undefined, rather than a constraint
4030          violation, so we cannot make this an error.  If this call is never
4031          executed, the program is still strictly conforming.  */
4032       warning ("%qT is promoted to %qT when passed through %<...%>",
4033                type, promoted_type);
4034       if (! gave_help)
4035         {
4036           gave_help = true;
4037           warning ("(so you should pass %qT not %qT to %<va_arg%>)",
4038                    promoted_type, type);
4039         }
4040
4041       /* We can, however, treat "undefined" any way we please.
4042          Call abort to encourage the user to fix the program.  */
4043       inform ("if this code is reached, the program will abort");
4044       t = build_function_call_expr (implicit_built_in_decls[BUILT_IN_TRAP],
4045                                     NULL);
4046       append_to_statement_list (t, pre_p);
4047
4048       /* This is dead code, but go ahead and finish so that the
4049          mode of the result comes out right.  */
4050       *expr_p = dummy_object (type);
4051       return GS_ALL_DONE;
4052     }
4053   else
4054     {
4055       /* Make it easier for the backends by protecting the valist argument
4056          from multiple evaluations.  */
4057       if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
4058         {
4059           /* For this case, the backends will be expecting a pointer to
4060              TREE_TYPE (va_list_type_node), but it's possible we've
4061              actually been given an array (an actual va_list_type_node).
4062              So fix it.  */
4063           if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
4064             {
4065               tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
4066               valist = build_fold_addr_expr_with_type (valist, p1);
4067             }
4068           gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
4069         }
4070       else
4071         gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
4072
4073       if (!targetm.gimplify_va_arg_expr)
4074         /* Once most targets are converted this should abort.  */
4075         return GS_ALL_DONE;
4076
4077       *expr_p = targetm.gimplify_va_arg_expr (valist, type, pre_p, post_p);
4078       return GS_OK;
4079     }
4080 }
4081
4082 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4083
4084 static rtx
4085 expand_builtin_va_end (tree arglist)
4086 {
4087   tree valist = TREE_VALUE (arglist);
4088
4089   /* Evaluate for side effects, if needed.  I hate macros that don't
4090      do that.  */
4091   if (TREE_SIDE_EFFECTS (valist))
4092     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4093
4094   return const0_rtx;
4095 }
4096
4097 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4098    builtin rather than just as an assignment in stdarg.h because of the
4099    nastiness of array-type va_list types.  */
4100
4101 static rtx
4102 expand_builtin_va_copy (tree arglist)
4103 {
4104   tree dst, src, t;
4105
4106   dst = TREE_VALUE (arglist);
4107   src = TREE_VALUE (TREE_CHAIN (arglist));
4108
4109   dst = stabilize_va_list (dst, 1);
4110   src = stabilize_va_list (src, 0);
4111
4112   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4113     {
4114       t = build2 (MODIFY_EXPR, va_list_type_node, dst, src);
4115       TREE_SIDE_EFFECTS (t) = 1;
4116       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4117     }
4118   else
4119     {
4120       rtx dstb, srcb, size;
4121
4122       /* Evaluate to pointers.  */
4123       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4124       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4125       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4126                           VOIDmode, EXPAND_NORMAL);
4127
4128       dstb = convert_memory_address (Pmode, dstb);
4129       srcb = convert_memory_address (Pmode, srcb);
4130
4131       /* "Dereference" to BLKmode memories.  */
4132       dstb = gen_rtx_MEM (BLKmode, dstb);
4133       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4134       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4135       srcb = gen_rtx_MEM (BLKmode, srcb);
4136       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4137       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4138
4139       /* Copy.  */
4140       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4141     }
4142
4143   return const0_rtx;
4144 }
4145
4146 /* Expand a call to one of the builtin functions __builtin_frame_address or
4147    __builtin_return_address.  */
4148
4149 static rtx
4150 expand_builtin_frame_address (tree fndecl, tree arglist)
4151 {
4152   /* The argument must be a nonnegative integer constant.
4153      It counts the number of frames to scan up the stack.
4154      The value is the return address saved in that frame.  */
4155   if (arglist == 0)
4156     /* Warning about missing arg was already issued.  */
4157     return const0_rtx;
4158   else if (! host_integerp (TREE_VALUE (arglist), 1))
4159     {
4160       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4161         error ("invalid arg to %<__builtin_frame_address%>");
4162       else
4163         error ("invalid arg to %<__builtin_return_address%>");
4164       return const0_rtx;
4165     }
4166   else
4167     {
4168       rtx tem
4169         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4170                                       tree_low_cst (TREE_VALUE (arglist), 1),
4171                                       hard_frame_pointer_rtx);
4172
4173       /* Some ports cannot access arbitrary stack frames.  */
4174       if (tem == NULL)
4175         {
4176           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4177             warning ("unsupported arg to %<__builtin_frame_address%>");
4178           else
4179             warning ("unsupported arg to %<__builtin_return_address%>");
4180           return const0_rtx;
4181         }
4182
4183       /* For __builtin_frame_address, return what we've got.  */
4184       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4185         return tem;
4186
4187       if (!REG_P (tem)
4188           && ! CONSTANT_P (tem))
4189         tem = copy_to_mode_reg (Pmode, tem);
4190       return tem;
4191     }
4192 }
4193
4194 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4195    we failed and the caller should emit a normal call, otherwise try to get
4196    the result in TARGET, if convenient.  */
4197
4198 static rtx
4199 expand_builtin_alloca (tree arglist, rtx target)
4200 {
4201   rtx op0;
4202   rtx result;
4203
4204   /* In -fmudflap-instrumented code, alloca() and __builtin_alloca()
4205      should always expand to function calls.  These can be intercepted
4206      in libmudflap.  */
4207   if (flag_mudflap)
4208     return 0;
4209
4210   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4211     return 0;
4212
4213   /* Compute the argument.  */
4214   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4215
4216   /* Allocate the desired space.  */
4217   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4218   result = convert_memory_address (ptr_mode, result);
4219
4220   return result;
4221 }
4222
4223 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4224    Return 0 if a normal call should be emitted rather than expanding the
4225    function in-line.  If convenient, the result should be placed in TARGET.
4226    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4227
4228 static rtx
4229 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4230                      rtx subtarget, optab op_optab)
4231 {
4232   rtx op0;
4233   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4234     return 0;
4235
4236   /* Compute the argument.  */
4237   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4238   /* Compute op, into TARGET if possible.
4239      Set TARGET to wherever the result comes back.  */
4240   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4241                         op_optab, op0, target, 1);
4242   gcc_assert (target);
4243
4244   return convert_to_mode (target_mode, target, 0);
4245 }
4246
4247 /* If the string passed to fputs is a constant and is one character
4248    long, we attempt to transform this call into __builtin_fputc().  */
4249
4250 static rtx
4251 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4252 {
4253   /* Verify the arguments in the original call.  */
4254   if (validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4255     {
4256       tree result = fold_builtin_fputs (arglist, (target == const0_rtx),
4257                                         unlocked, NULL_TREE);
4258       if (result)
4259         return expand_expr (result, target, VOIDmode, EXPAND_NORMAL);
4260     }
4261   return 0;
4262 }
4263
4264 /* Expand a call to __builtin_expect.  We return our argument and emit a
4265    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4266    a non-jump context.  */
4267
4268 static rtx
4269 expand_builtin_expect (tree arglist, rtx target)
4270 {
4271   tree exp, c;
4272   rtx note, rtx_c;
4273
4274   if (arglist == NULL_TREE
4275       || TREE_CHAIN (arglist) == NULL_TREE)
4276     return const0_rtx;
4277   exp = TREE_VALUE (arglist);
4278   c = TREE_VALUE (TREE_CHAIN (arglist));
4279
4280   if (TREE_CODE (c) != INTEGER_CST)
4281     {
4282       error ("second arg to %<__builtin_expect%> must be a constant");
4283       c = integer_zero_node;
4284     }
4285
4286   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4287
4288   /* Don't bother with expected value notes for integral constants.  */
4289   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4290     {
4291       /* We do need to force this into a register so that we can be
4292          moderately sure to be able to correctly interpret the branch
4293          condition later.  */
4294       target = force_reg (GET_MODE (target), target);
4295
4296       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4297
4298       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4299       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4300     }
4301
4302   return target;
4303 }
4304
4305 /* Like expand_builtin_expect, except do this in a jump context.  This is
4306    called from do_jump if the conditional is a __builtin_expect.  Return either
4307    a list of insns to emit the jump or NULL if we cannot optimize
4308    __builtin_expect.  We need to optimize this at jump time so that machines
4309    like the PowerPC don't turn the test into a SCC operation, and then jump
4310    based on the test being 0/1.  */
4311
4312 rtx
4313 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4314 {
4315   tree arglist = TREE_OPERAND (exp, 1);
4316   tree arg0 = TREE_VALUE (arglist);
4317   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4318   rtx ret = NULL_RTX;
4319
4320   /* Only handle __builtin_expect (test, 0) and
4321      __builtin_expect (test, 1).  */
4322   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4323       && (integer_zerop (arg1) || integer_onep (arg1)))
4324     {
4325       rtx insn, drop_through_label, temp;
4326
4327       /* Expand the jump insns.  */
4328       start_sequence ();
4329       do_jump (arg0, if_false_label, if_true_label);
4330       ret = get_insns ();
4331
4332       drop_through_label = get_last_insn ();
4333       if (drop_through_label && NOTE_P (drop_through_label))
4334         drop_through_label = prev_nonnote_insn (drop_through_label);
4335       if (drop_through_label && !LABEL_P (drop_through_label))
4336         drop_through_label = NULL_RTX;
4337       end_sequence ();
4338
4339       if (! if_true_label)
4340         if_true_label = drop_through_label;
4341       if (! if_false_label)
4342         if_false_label = drop_through_label;
4343
4344       /* Go through and add the expect's to each of the conditional jumps.  */
4345       insn = ret;
4346       while (insn != NULL_RTX)
4347         {
4348           rtx next = NEXT_INSN (insn);
4349
4350           if (JUMP_P (insn) && any_condjump_p (insn))
4351             {
4352               rtx ifelse = SET_SRC (pc_set (insn));
4353               rtx then_dest = XEXP (ifelse, 1);
4354               rtx else_dest = XEXP (ifelse, 2);
4355               int taken = -1;
4356
4357               /* First check if we recognize any of the labels.  */
4358               if (GET_CODE (then_dest) == LABEL_REF
4359                   && XEXP (then_dest, 0) == if_true_label)
4360                 taken = 1;
4361               else if (GET_CODE (then_dest) == LABEL_REF
4362                        && XEXP (then_dest, 0) == if_false_label)
4363                 taken = 0;
4364               else if (GET_CODE (else_dest) == LABEL_REF
4365                        && XEXP (else_dest, 0) == if_false_label)
4366                 taken = 1;
4367               else if (GET_CODE (else_dest) == LABEL_REF
4368                        && XEXP (else_dest, 0) == if_true_label)
4369                 taken = 0;
4370               /* Otherwise check where we drop through.  */
4371               else if (else_dest == pc_rtx)
4372                 {
4373                   if (next && NOTE_P (next))
4374                     next = next_nonnote_insn (next);
4375
4376                   if (next && JUMP_P (next)
4377                       && any_uncondjump_p (next))
4378                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4379                   else
4380                     temp = next;
4381
4382                   /* TEMP is either a CODE_LABEL, NULL_RTX or something
4383                      else that can't possibly match either target label.  */
4384                   if (temp == if_false_label)
4385                     taken = 1;
4386                   else if (temp == if_true_label)
4387                     taken = 0;
4388                 }
4389               else if (then_dest == pc_rtx)
4390                 {
4391                   if (next && NOTE_P (next))
4392                     next = next_nonnote_insn (next);
4393
4394                   if (next && JUMP_P (next)
4395                       && any_uncondjump_p (next))
4396                     temp = XEXP (SET_SRC (pc_set (next)), 0);
4397                   else
4398                     temp = next;
4399
4400                   if (temp == if_false_label)
4401                     taken = 0;
4402                   else if (temp == if_true_label)
4403                     taken = 1;
4404                 }
4405
4406               if (taken != -1)
4407                 {
4408                   /* If the test is expected to fail, reverse the
4409                      probabilities.  */
4410                   if (integer_zerop (arg1))
4411                     taken = 1 - taken;
4412                   predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4413                 }
4414             }
4415
4416           insn = next;
4417         }
4418     }
4419
4420   return ret;
4421 }
4422
4423 void
4424 expand_builtin_trap (void)
4425 {
4426 #ifdef HAVE_trap
4427   if (HAVE_trap)
4428     emit_insn (gen_trap ());
4429   else
4430 #endif
4431     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4432   emit_barrier ();
4433 }
4434
4435 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4436    Return 0 if a normal call should be emitted rather than expanding
4437    the function inline.  If convenient, the result should be placed
4438    in TARGET.  SUBTARGET may be used as the target for computing
4439    the operand.  */
4440
4441 static rtx
4442 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4443 {
4444   enum machine_mode mode;
4445   tree arg;
4446   rtx op0;
4447
4448   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4449     return 0;
4450
4451   arg = TREE_VALUE (arglist);
4452   mode = TYPE_MODE (TREE_TYPE (arg));
4453   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4454   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4455 }
4456
4457 /* Create a new constant string literal and return a char* pointer to it.
4458    The STRING_CST value is the LEN characters at STR.  */
4459 static tree
4460 build_string_literal (int len, const char *str)
4461 {
4462   tree t, elem, index, type;
4463
4464   t = build_string (len, str);
4465   elem = build_type_variant (char_type_node, 1, 0);
4466   index = build_index_type (build_int_cst (NULL_TREE, len - 1));
4467   type = build_array_type (elem, index);
4468   TREE_TYPE (t) = type;
4469   TREE_CONSTANT (t) = 1;
4470   TREE_INVARIANT (t) = 1;
4471   TREE_READONLY (t) = 1;
4472   TREE_STATIC (t) = 1;
4473
4474   type = build_pointer_type (type);
4475   t = build1 (ADDR_EXPR, type, t);
4476
4477   type = build_pointer_type (elem);
4478   t = build1 (NOP_EXPR, type, t);
4479   return t;
4480 }
4481
4482 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4483    Return 0 if a normal call should be emitted rather than transforming
4484    the function inline.  If convenient, the result should be placed in
4485    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked
4486    call.  */
4487 static rtx
4488 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4489                        bool unlocked)
4490 {
4491   tree fn_putchar = unlocked
4492                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4493                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4494   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4495                           : implicit_built_in_decls[BUILT_IN_PUTS];
4496   const char *fmt_str;
4497   tree fn, fmt, arg;
4498
4499   /* If the return value is used, don't do the transformation.  */
4500   if (target != const0_rtx)
4501     return 0;
4502
4503   /* Verify the required arguments in the original call.  */
4504   if (! arglist)
4505     return 0;
4506   fmt = TREE_VALUE (arglist);
4507   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4508     return 0;
4509   arglist = TREE_CHAIN (arglist);
4510
4511   /* Check whether the format is a literal string constant.  */
4512   fmt_str = c_getstr (fmt);
4513   if (fmt_str == NULL)
4514     return 0;
4515
4516   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4517   if (strcmp (fmt_str, "%s\n") == 0)
4518     {
4519       if (! arglist
4520           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4521           || TREE_CHAIN (arglist))
4522         return 0;
4523       fn = fn_puts;
4524     }
4525   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4526   else if (strcmp (fmt_str, "%c") == 0)
4527     {
4528       if (! arglist
4529           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4530           || TREE_CHAIN (arglist))
4531         return 0;
4532       fn = fn_putchar;
4533     }
4534   else
4535     {
4536       /* We can't handle anything else with % args or %% ... yet.  */
4537       if (strchr (fmt_str, '%'))
4538         return 0;
4539
4540       if (arglist)
4541         return 0;
4542
4543       /* If the format specifier was "", printf does nothing.  */
4544       if (fmt_str[0] == '\0')
4545         return const0_rtx;
4546       /* If the format specifier has length of 1, call putchar.  */
4547       if (fmt_str[1] == '\0')
4548         {
4549           /* Given printf("c"), (where c is any one character,)
4550              convert "c"[0] to an int and pass that to the replacement
4551              function.  */
4552           arg = build_int_cst (NULL_TREE, fmt_str[0]);
4553           arglist = build_tree_list (NULL_TREE, arg);
4554           fn = fn_putchar;
4555         }
4556       else
4557         {
4558           /* If the format specifier was "string\n", call puts("string").  */
4559           size_t len = strlen (fmt_str);
4560           if (fmt_str[len - 1] == '\n')
4561             {
4562               /* Create a NUL-terminated string that's one char shorter
4563                  than the original, stripping off the trailing '\n'.  */
4564               char *newstr = alloca (len);
4565               memcpy (newstr, fmt_str, len - 1);
4566               newstr[len - 1] = 0;
4567
4568               arg = build_string_literal (len, newstr);
4569               arglist = build_tree_list (NULL_TREE, arg);
4570               fn = fn_puts;
4571             }
4572           else
4573             /* We'd like to arrange to call fputs(string,stdout) here,
4574                but we need stdout and don't have a way to get it yet.  */
4575             return 0;
4576         }
4577     }
4578
4579   if (!fn)
4580     return 0;
4581   return expand_expr (build_function_call_expr (fn, arglist),
4582                       target, mode, EXPAND_NORMAL);
4583 }
4584
4585 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4586    Return 0 if a normal call should be emitted rather than transforming
4587    the function inline.  If convenient, the result should be placed in
4588    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked
4589    call.  */
4590 static rtx
4591 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4592                         bool unlocked)
4593 {
4594   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4595                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4596   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4597                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4598   const char *fmt_str;
4599   tree fn, fmt, fp, arg;
4600
4601   /* If the return value is used, don't do the transformation.  */
4602   if (target != const0_rtx)
4603     return 0;
4604
4605   /* Verify the required arguments in the original call.  */
4606   if (! arglist)
4607     return 0;
4608   fp = TREE_VALUE (arglist);
4609   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4610     return 0;
4611   arglist = TREE_CHAIN (arglist);
4612   if (! arglist)
4613     return 0;
4614   fmt = TREE_VALUE (arglist);
4615   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4616     return 0;
4617   arglist = TREE_CHAIN (arglist);
4618
4619   /* Check whether the format is a literal string constant.  */
4620   fmt_str = c_getstr (fmt);
4621   if (fmt_str == NULL)
4622     return 0;
4623
4624   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4625   if (strcmp (fmt_str, "%s") == 0)
4626     {
4627       if (! arglist
4628           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4629           || TREE_CHAIN (arglist))
4630         return 0;
4631       arg = TREE_VALUE (arglist);
4632       arglist = build_tree_list (NULL_TREE, fp);
4633       arglist = tree_cons (NULL_TREE, arg, arglist);
4634       fn = fn_fputs;
4635     }
4636   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4637   else if (strcmp (fmt_str, "%c") == 0)
4638     {
4639       if (! arglist
4640           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4641           || TREE_CHAIN (arglist))
4642         return 0;
4643       arg = TREE_VALUE (arglist);
4644       arglist = build_tree_list (NULL_TREE, fp);
4645       arglist = tree_cons (NULL_TREE, arg, arglist);
4646       fn = fn_fputc;
4647     }
4648   else
4649     {
4650       /* We can't handle anything else with % args or %% ... yet.  */
4651       if (strchr (fmt_str, '%'))
4652         return 0;
4653
4654       if (arglist)
4655         return 0;
4656
4657       /* If the format specifier was "", fprintf does nothing.  */
4658       if (fmt_str[0] == '\0')
4659         {
4660           /* Evaluate and ignore FILE* argument for side-effects.  */
4661           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4662           return const0_rtx;
4663         }
4664
4665       /* When "string" doesn't contain %, replace all cases of
4666          fprintf(stream,string) with fputs(string,stream).  The fputs
4667          builtin will take care of special cases like length == 1.  */
4668       arglist = build_tree_list (NULL_TREE, fp);
4669       arglist = tree_cons (NULL_TREE, fmt, arglist);
4670       fn = fn_fputs;
4671     }
4672
4673   if (!fn)
4674     return 0;
4675   return expand_expr (build_function_call_expr (fn, arglist),
4676                       target, mode, EXPAND_NORMAL);
4677 }
4678
4679 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4680    a normal call should be emitted rather than expanding the function
4681    inline.  If convenient, the result should be placed in TARGET with
4682    mode MODE.  */
4683
4684 static rtx
4685 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4686 {
4687   tree orig_arglist, dest, fmt;
4688   const char *fmt_str;
4689
4690   orig_arglist = arglist;
4691
4692   /* Verify the required arguments in the original call.  */
4693   if (! arglist)
4694     return 0;
4695   dest = TREE_VALUE (arglist);
4696   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4697     return 0;
4698   arglist = TREE_CHAIN (arglist);
4699   if (! arglist)
4700     return 0;
4701   fmt = TREE_VALUE (arglist);
4702   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4703     return 0;
4704   arglist = TREE_CHAIN (arglist);
4705
4706   /* Check whether the format is a literal string constant.  */
4707   fmt_str = c_getstr (fmt);
4708   if (fmt_str == NULL)
4709     return 0;
4710
4711   /* If the format doesn't contain % args or %%, use strcpy.  */
4712   if (strchr (fmt_str, '%') == 0)
4713     {
4714       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4715       tree exp;
4716
4717       if (arglist || ! fn)
4718         return 0;
4719       expand_expr (build_function_call_expr (fn, orig_arglist),
4720                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4721       if (target == const0_rtx)
4722         return const0_rtx;
4723       exp = build_int_cst (NULL_TREE, strlen (fmt_str));
4724       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4725     }
4726   /* If the format is "%s", use strcpy if the result isn't used.  */
4727   else if (strcmp (fmt_str, "%s") == 0)
4728     {
4729       tree fn, arg, len;
4730       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4731
4732       if (! fn)
4733         return 0;
4734
4735       if (! arglist || TREE_CHAIN (arglist))
4736         return 0;
4737       arg = TREE_VALUE (arglist);
4738       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4739         return 0;
4740
4741       if (target != const0_rtx)
4742         {
4743           len = c_strlen (arg, 1);
4744           if (! len || TREE_CODE (len) != INTEGER_CST)
4745             return 0;
4746         }
4747       else
4748         len = NULL_TREE;
4749
4750       arglist = build_tree_list (NULL_TREE, arg);
4751       arglist = tree_cons (NULL_TREE, dest, arglist);
4752       expand_expr (build_function_call_expr (fn, arglist),
4753                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4754
4755       if (target == const0_rtx)
4756         return const0_rtx;
4757       return expand_expr (len, target, mode, EXPAND_NORMAL);
4758     }
4759
4760   return 0;
4761 }
4762
4763 /* Expand a call to either the entry or exit function profiler.  */
4764
4765 static rtx
4766 expand_builtin_profile_func (bool exitp)
4767 {
4768   rtx this, which;
4769
4770   this = DECL_RTL (current_function_decl);
4771   gcc_assert (MEM_P (this));
4772   this = XEXP (this, 0);
4773
4774   if (exitp)
4775     which = profile_function_exit_libfunc;
4776   else
4777     which = profile_function_entry_libfunc;
4778
4779   emit_library_call (which, LCT_NORMAL, VOIDmode, 2, this, Pmode,
4780                      expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
4781                                                  0, hard_frame_pointer_rtx),
4782                      Pmode);
4783
4784   return const0_rtx;
4785 }
4786
4787 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
4788
4789 static rtx
4790 round_trampoline_addr (rtx tramp)
4791 {
4792   rtx temp, addend, mask;
4793
4794   /* If we don't need too much alignment, we'll have been guaranteed
4795      proper alignment by get_trampoline_type.  */
4796   if (TRAMPOLINE_ALIGNMENT <= STACK_BOUNDARY)
4797     return tramp;
4798
4799   /* Round address up to desired boundary.  */
4800   temp = gen_reg_rtx (Pmode);
4801   addend = GEN_INT (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT - 1);
4802   mask = GEN_INT (-TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
4803
4804   temp  = expand_simple_binop (Pmode, PLUS, tramp, addend,
4805                                temp, 0, OPTAB_LIB_WIDEN);
4806   tramp = expand_simple_binop (Pmode, AND, temp, mask,
4807                                temp, 0, OPTAB_LIB_WIDEN);
4808
4809   return tramp;
4810 }
4811
4812 static rtx
4813 expand_builtin_init_trampoline (tree arglist)
4814 {
4815   tree t_tramp, t_func, t_chain;
4816   rtx r_tramp, r_func, r_chain;
4817 #ifdef TRAMPOLINE_TEMPLATE
4818   rtx blktramp;
4819 #endif
4820
4821   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE,
4822                          POINTER_TYPE, VOID_TYPE))
4823     return NULL_RTX;
4824
4825   t_tramp = TREE_VALUE (arglist);
4826   arglist = TREE_CHAIN (arglist);
4827   t_func = TREE_VALUE (arglist);
4828   arglist = TREE_CHAIN (arglist);
4829   t_chain = TREE_VALUE (arglist);
4830
4831   r_tramp = expand_expr (t_tramp, NULL_RTX, VOIDmode, 0);
4832   r_func = expand_expr (t_func, NULL_RTX, VOIDmode, 0);
4833   r_chain = expand_expr (t_chain, NULL_RTX, VOIDmode, 0);
4834
4835   /* Generate insns to initialize the trampoline.  */
4836   r_tramp = round_trampoline_addr (r_tramp);
4837 #ifdef TRAMPOLINE_TEMPLATE
4838   blktramp = gen_rtx_MEM (BLKmode, r_tramp);
4839   set_mem_align (blktramp, TRAMPOLINE_ALIGNMENT);
4840   emit_block_move (blktramp, assemble_trampoline_template (),
4841                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4842 #endif
4843   trampolines_created = 1;
4844   INITIALIZE_TRAMPOLINE (r_tramp, r_func, r_chain);
4845
4846   return const0_rtx;
4847 }
4848
4849 static rtx
4850 expand_builtin_adjust_trampoline (tree arglist)
4851 {
4852   rtx tramp;
4853
4854   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
4855     return NULL_RTX;
4856
4857   tramp = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4858   tramp = round_trampoline_addr (tramp);
4859 #ifdef TRAMPOLINE_ADJUST_ADDRESS
4860   TRAMPOLINE_ADJUST_ADDRESS (tramp);
4861 #endif
4862
4863   return tramp;
4864 }
4865
4866 /* Expand a call to the built-in signbit, signbitf or signbitl function.
4867    Return NULL_RTX if a normal call should be emitted rather than expanding
4868    the function in-line.  EXP is the expression that is a call to the builtin
4869    function; if convenient, the result should be placed in TARGET.  */
4870
4871 static rtx
4872 expand_builtin_signbit (tree exp, rtx target)
4873 {
4874   const struct real_format *fmt;
4875   enum machine_mode fmode, imode, rmode;
4876   HOST_WIDE_INT hi, lo;
4877   tree arg, arglist;
4878   int bitpos;
4879   rtx temp;
4880
4881   arglist = TREE_OPERAND (exp, 1);
4882   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4883     return 0;
4884
4885   arg = TREE_VALUE (arglist);
4886   fmode = TYPE_MODE (TREE_TYPE (arg));
4887   rmode = TYPE_MODE (TREE_TYPE (exp));
4888   fmt = REAL_MODE_FORMAT (fmode);
4889
4890   /* For floating point formats without a sign bit, implement signbit
4891      as "ARG < 0.0".  */
4892   if (fmt->signbit < 0)
4893   {
4894     /* But we can't do this if the format supports signed zero.  */
4895     if (fmt->has_signed_zero && HONOR_SIGNED_ZEROS (fmode))
4896       return 0;
4897
4898     arg = fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
4899                         build_real (TREE_TYPE (arg), dconst0)));
4900     return expand_expr (arg, target, VOIDmode, EXPAND_NORMAL);
4901   }
4902
4903   imode = int_mode_for_mode (fmode);
4904   if (imode == BLKmode)
4905     return 0;
4906
4907   bitpos = fmt->signbit;
4908   /* Handle targets with different FP word orders.  */
4909   if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
4910     {
4911       int nwords = GET_MODE_BITSIZE (fmode) / BITS_PER_WORD;
4912       int word = nwords - (bitpos / BITS_PER_WORD) - 1;
4913       bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
4914     }
4915
4916   /* If the sign bit is not in the lowpart and the floating point format
4917      is wider than an integer, check that is twice the size of an integer
4918      so that we can use gen_highpart below.  */
4919   if (bitpos >= GET_MODE_BITSIZE (rmode)
4920       && GET_MODE_BITSIZE (imode) != 2 * GET_MODE_BITSIZE (rmode))
4921     return 0;
4922
4923   temp = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4924   temp = gen_lowpart (imode, temp);
4925
4926   if (GET_MODE_BITSIZE (imode) > GET_MODE_BITSIZE (rmode))
4927     {
4928       if (BYTES_BIG_ENDIAN)
4929         bitpos = GET_MODE_BITSIZE (imode) - 1 - bitpos;
4930       temp = copy_to_mode_reg (imode, temp);
4931       temp = extract_bit_field (temp, 1, bitpos, 1,
4932                                 NULL_RTX, rmode, rmode);
4933     }
4934   else
4935     {
4936       if (GET_MODE_BITSIZE (imode) < GET_MODE_BITSIZE (rmode))
4937         temp = gen_lowpart (rmode, temp);
4938       if (bitpos < HOST_BITS_PER_WIDE_INT)
4939         {
4940           hi = 0;
4941           lo = (HOST_WIDE_INT) 1 << bitpos;
4942         }
4943       else
4944         {
4945           hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
4946           lo = 0;
4947         }
4948
4949       temp = force_reg (rmode, temp);
4950       temp = expand_binop (rmode, and_optab, temp,
4951                            immed_double_const (lo, hi, rmode),
4952                            target, 1, OPTAB_LIB_WIDEN);
4953     }
4954   return temp;
4955 }
4956
4957 /* Expand fork or exec calls.  TARGET is the desired target of the
4958    call.  ARGLIST is the list of arguments of the call.  FN is the
4959    identificator of the actual function.  IGNORE is nonzero if the
4960    value is to be ignored.  */
4961
4962 static rtx
4963 expand_builtin_fork_or_exec (tree fn, tree arglist, rtx target, int ignore)
4964 {
4965   tree id, decl;
4966   tree call;
4967
4968   /* If we are not profiling, just call the function.  */
4969   if (!profile_arc_flag)
4970     return NULL_RTX;
4971
4972   /* Otherwise call the wrapper.  This should be equivalent for the rest of
4973      compiler, so the code does not diverge, and the wrapper may run the
4974      code necessary for keeping the profiling sane.  */
4975
4976   switch (DECL_FUNCTION_CODE (fn))
4977     {
4978     case BUILT_IN_FORK:
4979       id = get_identifier ("__gcov_fork");
4980       break;
4981
4982     case BUILT_IN_EXECL:
4983       id = get_identifier ("__gcov_execl");
4984       break;
4985
4986     case BUILT_IN_EXECV:
4987       id = get_identifier ("__gcov_execv");
4988       break;
4989
4990     case BUILT_IN_EXECLP:
4991       id = get_identifier ("__gcov_execlp");
4992       break;
4993
4994     case BUILT_IN_EXECLE:
4995       id = get_identifier ("__gcov_execle");
4996       break;
4997
4998     case BUILT_IN_EXECVP:
4999       id = get_identifier ("__gcov_execvp");
5000       break;
5001
5002     case BUILT_IN_EXECVE:
5003       id = get_identifier ("__gcov_execve");
5004       break;
5005
5006     default:
5007       gcc_unreachable ();
5008     }
5009
5010   decl = build_decl (FUNCTION_DECL, id, TREE_TYPE (fn));
5011   DECL_EXTERNAL (decl) = 1;
5012   TREE_PUBLIC (decl) = 1;
5013   DECL_ARTIFICIAL (decl) = 1;
5014   TREE_NOTHROW (decl) = 1;
5015   call = build_function_call_expr (decl, arglist);
5016
5017   return expand_call (call, target, ignore);
5018 }
5019 \f
5020 /* Expand an expression EXP that calls a built-in function,
5021    with result going to TARGET if that's convenient
5022    (and in mode MODE if that's convenient).
5023    SUBTARGET may be used as the target for computing one of EXP's operands.
5024    IGNORE is nonzero if the value is to be ignored.  */
5025
5026 rtx
5027 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
5028                 int ignore)
5029 {
5030   tree fndecl = get_callee_fndecl (exp);
5031   tree arglist = TREE_OPERAND (exp, 1);
5032   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5033   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
5034
5035   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5036     return targetm.expand_builtin (exp, target, subtarget, mode, ignore);
5037
5038   /* When not optimizing, generate calls to library functions for a certain
5039      set of builtins.  */
5040   if (!optimize
5041       && !CALLED_AS_BUILT_IN (fndecl)
5042       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
5043       && fcode != BUILT_IN_ALLOCA)
5044     return expand_call (exp, target, ignore);
5045
5046   /* The built-in function expanders test for target == const0_rtx
5047      to determine whether the function's result will be ignored.  */
5048   if (ignore)
5049     target = const0_rtx;
5050
5051   /* If the result of a pure or const built-in function is ignored, and
5052      none of its arguments are volatile, we can avoid expanding the
5053      built-in call and just evaluate the arguments for side-effects.  */
5054   if (target == const0_rtx
5055       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
5056     {
5057       bool volatilep = false;
5058       tree arg;
5059
5060       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5061         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
5062           {
5063             volatilep = true;
5064             break;
5065           }
5066
5067       if (! volatilep)
5068         {
5069           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
5070             expand_expr (TREE_VALUE (arg), const0_rtx,
5071                          VOIDmode, EXPAND_NORMAL);
5072           return const0_rtx;
5073         }
5074     }
5075
5076   switch (fcode)
5077     {
5078     case BUILT_IN_FABS:
5079     case BUILT_IN_FABSF:
5080     case BUILT_IN_FABSL:
5081       target = expand_builtin_fabs (arglist, target, subtarget);
5082       if (target)
5083         return target;
5084       break;
5085
5086       /* Just do a normal library call if we were unable to fold
5087          the values.  */
5088     case BUILT_IN_CABS:
5089     case BUILT_IN_CABSF:
5090     case BUILT_IN_CABSL:
5091       break;
5092
5093     case BUILT_IN_EXP:
5094     case BUILT_IN_EXPF:
5095     case BUILT_IN_EXPL:
5096     case BUILT_IN_EXP10:
5097     case BUILT_IN_EXP10F:
5098     case BUILT_IN_EXP10L:
5099     case BUILT_IN_POW10:
5100     case BUILT_IN_POW10F:
5101     case BUILT_IN_POW10L:
5102     case BUILT_IN_EXP2:
5103     case BUILT_IN_EXP2F:
5104     case BUILT_IN_EXP2L:
5105     case BUILT_IN_EXPM1:
5106     case BUILT_IN_EXPM1F:
5107     case BUILT_IN_EXPM1L:
5108     case BUILT_IN_LOGB:
5109     case BUILT_IN_LOGBF:
5110     case BUILT_IN_LOGBL:
5111     case BUILT_IN_ILOGB:
5112     case BUILT_IN_ILOGBF:
5113     case BUILT_IN_ILOGBL:
5114     case BUILT_IN_LOG:
5115     case BUILT_IN_LOGF:
5116     case BUILT_IN_LOGL:
5117     case BUILT_IN_LOG10:
5118     case BUILT_IN_LOG10F:
5119     case BUILT_IN_LOG10L:
5120     case BUILT_IN_LOG2:
5121     case BUILT_IN_LOG2F:
5122     case BUILT_IN_LOG2L:
5123     case BUILT_IN_LOG1P:
5124     case BUILT_IN_LOG1PF:
5125     case BUILT_IN_LOG1PL:
5126     case BUILT_IN_TAN:
5127     case BUILT_IN_TANF:
5128     case BUILT_IN_TANL:
5129     case BUILT_IN_ASIN:
5130     case BUILT_IN_ASINF:
5131     case BUILT_IN_ASINL:
5132     case BUILT_IN_ACOS:
5133     case BUILT_IN_ACOSF:
5134     case BUILT_IN_ACOSL:
5135     case BUILT_IN_ATAN:
5136     case BUILT_IN_ATANF:
5137     case BUILT_IN_ATANL:
5138       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5139          because of possible accuracy problems.  */
5140       if (! flag_unsafe_math_optimizations)
5141         break;
5142     case BUILT_IN_SQRT:
5143     case BUILT_IN_SQRTF:
5144     case BUILT_IN_SQRTL:
5145     case BUILT_IN_FLOOR:
5146     case BUILT_IN_FLOORF:
5147     case BUILT_IN_FLOORL:
5148     case BUILT_IN_CEIL:
5149     case BUILT_IN_CEILF:
5150     case BUILT_IN_CEILL:
5151     case BUILT_IN_TRUNC:
5152     case BUILT_IN_TRUNCF:
5153     case BUILT_IN_TRUNCL:
5154     case BUILT_IN_ROUND:
5155     case BUILT_IN_ROUNDF:
5156     case BUILT_IN_ROUNDL:
5157     case BUILT_IN_NEARBYINT:
5158     case BUILT_IN_NEARBYINTF:
5159     case BUILT_IN_NEARBYINTL:
5160     case BUILT_IN_RINT:
5161     case BUILT_IN_RINTF:
5162     case BUILT_IN_RINTL:
5163       target = expand_builtin_mathfn (exp, target, subtarget);
5164       if (target)
5165         return target;
5166       break;
5167
5168     case BUILT_IN_POW:
5169     case BUILT_IN_POWF:
5170     case BUILT_IN_POWL:
5171       target = expand_builtin_pow (exp, target, subtarget);
5172       if (target)
5173         return target;
5174       break;
5175
5176     case BUILT_IN_ATAN2:
5177     case BUILT_IN_ATAN2F:
5178     case BUILT_IN_ATAN2L:
5179     case BUILT_IN_FMOD:
5180     case BUILT_IN_FMODF:
5181     case BUILT_IN_FMODL:
5182     case BUILT_IN_DREM:
5183     case BUILT_IN_DREMF:
5184     case BUILT_IN_DREML:
5185       if (! flag_unsafe_math_optimizations)
5186         break;
5187       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5188       if (target)
5189         return target;
5190       break;
5191
5192     case BUILT_IN_SIN:
5193     case BUILT_IN_SINF:
5194     case BUILT_IN_SINL:
5195     case BUILT_IN_COS:
5196     case BUILT_IN_COSF:
5197     case BUILT_IN_COSL:
5198       if (! flag_unsafe_math_optimizations)
5199         break;
5200       target = expand_builtin_mathfn_3 (exp, target, subtarget);
5201       if (target)
5202         return target;
5203       break;
5204
5205     case BUILT_IN_APPLY_ARGS:
5206       return expand_builtin_apply_args ();
5207
5208       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5209          FUNCTION with a copy of the parameters described by
5210          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5211          allocated on the stack into which is stored all the registers
5212          that might possibly be used for returning the result of a
5213          function.  ARGUMENTS is the value returned by
5214          __builtin_apply_args.  ARGSIZE is the number of bytes of
5215          arguments that must be copied.  ??? How should this value be
5216          computed?  We'll also need a safe worst case value for varargs
5217          functions.  */
5218     case BUILT_IN_APPLY:
5219       if (!validate_arglist (arglist, POINTER_TYPE,
5220                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5221           && !validate_arglist (arglist, REFERENCE_TYPE,
5222                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5223         return const0_rtx;
5224       else
5225         {
5226           int i;
5227           tree t;
5228           rtx ops[3];
5229
5230           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5231             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5232
5233           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5234         }
5235
5236       /* __builtin_return (RESULT) causes the function to return the
5237          value described by RESULT.  RESULT is address of the block of
5238          memory returned by __builtin_apply.  */
5239     case BUILT_IN_RETURN:
5240       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5241         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5242                                             NULL_RTX, VOIDmode, 0));
5243       return const0_rtx;
5244
5245     case BUILT_IN_SAVEREGS:
5246       return expand_builtin_saveregs ();
5247
5248     case BUILT_IN_ARGS_INFO:
5249       return expand_builtin_args_info (arglist);
5250
5251       /* Return the address of the first anonymous stack arg.  */
5252     case BUILT_IN_NEXT_ARG:
5253       fold_builtin_next_arg (arglist);
5254       return expand_builtin_next_arg (arglist);
5255
5256     case BUILT_IN_CLASSIFY_TYPE:
5257       return expand_builtin_classify_type (arglist);
5258
5259     case BUILT_IN_CONSTANT_P:
5260       return const0_rtx;
5261
5262     case BUILT_IN_FRAME_ADDRESS:
5263     case BUILT_IN_RETURN_ADDRESS:
5264       return expand_builtin_frame_address (fndecl, arglist);
5265
5266     /* Returns the address of the area where the structure is returned.
5267        0 otherwise.  */
5268     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5269       if (arglist != 0
5270           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5271           || !MEM_P (DECL_RTL (DECL_RESULT (current_function_decl))))
5272         return const0_rtx;
5273       else
5274         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5275
5276     case BUILT_IN_ALLOCA:
5277       target = expand_builtin_alloca (arglist, target);
5278       if (target)
5279         return target;
5280       break;
5281
5282     case BUILT_IN_STACK_SAVE:
5283       return expand_stack_save ();
5284
5285     case BUILT_IN_STACK_RESTORE:
5286       expand_stack_restore (TREE_VALUE (arglist));
5287       return const0_rtx;
5288
5289     case BUILT_IN_FFS:
5290     case BUILT_IN_FFSL:
5291     case BUILT_IN_FFSLL:
5292     case BUILT_IN_FFSIMAX:
5293       target = expand_builtin_unop (target_mode, arglist, target,
5294                                     subtarget, ffs_optab);
5295       if (target)
5296         return target;
5297       break;
5298
5299     case BUILT_IN_CLZ:
5300     case BUILT_IN_CLZL:
5301     case BUILT_IN_CLZLL:
5302     case BUILT_IN_CLZIMAX:
5303       target = expand_builtin_unop (target_mode, arglist, target,
5304                                     subtarget, clz_optab);
5305       if (target)
5306         return target;
5307       break;
5308
5309     case BUILT_IN_CTZ:
5310     case BUILT_IN_CTZL:
5311     case BUILT_IN_CTZLL:
5312     case BUILT_IN_CTZIMAX:
5313       target = expand_builtin_unop (target_mode, arglist, target,
5314                                     subtarget, ctz_optab);
5315       if (target)
5316         return target;
5317       break;
5318
5319     case BUILT_IN_POPCOUNT:
5320     case BUILT_IN_POPCOUNTL:
5321     case BUILT_IN_POPCOUNTLL:
5322     case BUILT_IN_POPCOUNTIMAX:
5323       target = expand_builtin_unop (target_mode, arglist, target,
5324                                     subtarget, popcount_optab);
5325       if (target)
5326         return target;
5327       break;
5328
5329     case BUILT_IN_PARITY:
5330     case BUILT_IN_PARITYL:
5331     case BUILT_IN_PARITYLL:
5332     case BUILT_IN_PARITYIMAX:
5333       target = expand_builtin_unop (target_mode, arglist, target,
5334                                     subtarget, parity_optab);
5335       if (target)
5336         return target;
5337       break;
5338
5339     case BUILT_IN_STRLEN:
5340       target = expand_builtin_strlen (arglist, target, target_mode);
5341       if (target)
5342         return target;
5343       break;
5344
5345     case BUILT_IN_STRCPY:
5346       target = expand_builtin_strcpy (exp, target, mode);
5347       if (target)
5348         return target;
5349       break;
5350
5351     case BUILT_IN_STRNCPY:
5352       target = expand_builtin_strncpy (exp, target, mode);
5353       if (target)
5354         return target;
5355       break;
5356
5357     case BUILT_IN_STPCPY:
5358       target = expand_builtin_stpcpy (exp, target, mode);
5359       if (target)
5360         return target;
5361       break;
5362
5363     case BUILT_IN_STRCAT:
5364       target = expand_builtin_strcat (arglist, TREE_TYPE (exp), target, mode);
5365       if (target)
5366         return target;
5367       break;
5368
5369     case BUILT_IN_STRNCAT:
5370       target = expand_builtin_strncat (arglist, target, mode);
5371       if (target)
5372         return target;
5373       break;
5374
5375     case BUILT_IN_STRSPN:
5376       target = expand_builtin_strspn (arglist, target, mode);
5377       if (target)
5378         return target;
5379       break;
5380
5381     case BUILT_IN_STRCSPN:
5382       target = expand_builtin_strcspn (arglist, target, mode);
5383       if (target)
5384         return target;
5385       break;
5386
5387     case BUILT_IN_STRSTR:
5388       target = expand_builtin_strstr (arglist, target, mode);
5389       if (target)
5390         return target;
5391       break;
5392
5393     case BUILT_IN_STRPBRK:
5394       target = expand_builtin_strpbrk (arglist, target, mode);
5395       if (target)
5396         return target;
5397       break;
5398
5399     case BUILT_IN_INDEX:
5400     case BUILT_IN_STRCHR:
5401       target = expand_builtin_strchr (arglist, target, mode);
5402       if (target)
5403         return target;
5404       break;
5405
5406     case BUILT_IN_RINDEX:
5407     case BUILT_IN_STRRCHR:
5408       target = expand_builtin_strrchr (arglist, target, mode);
5409       if (target)
5410         return target;
5411       break;
5412
5413     case BUILT_IN_MEMCPY:
5414       target = expand_builtin_memcpy (exp, target, mode);
5415       if (target)
5416         return target;
5417       break;
5418
5419     case BUILT_IN_MEMPCPY:
5420       target = expand_builtin_mempcpy (arglist, TREE_TYPE (exp), target, mode, /*endp=*/ 1);
5421       if (target)
5422         return target;
5423       break;
5424
5425     case BUILT_IN_MEMMOVE:
5426       target = expand_builtin_memmove (arglist, TREE_TYPE (exp), target, mode);
5427       if (target)
5428         return target;
5429       break;
5430
5431     case BUILT_IN_BCOPY:
5432       target = expand_builtin_bcopy (arglist, TREE_TYPE (exp));
5433       if (target)
5434         return target;
5435       break;
5436
5437     case BUILT_IN_MEMSET:
5438       target = expand_builtin_memset (arglist, target, mode);
5439       if (target)
5440         return target;
5441       break;
5442
5443     case BUILT_IN_BZERO:
5444       target = expand_builtin_bzero (arglist);
5445       if (target)
5446         return target;
5447       break;
5448
5449     case BUILT_IN_STRCMP:
5450       target = expand_builtin_strcmp (exp, target, mode);
5451       if (target)
5452         return target;
5453       break;
5454
5455     case BUILT_IN_STRNCMP:
5456       target = expand_builtin_strncmp (exp, target, mode);
5457       if (target)
5458         return target;
5459       break;
5460
5461     case BUILT_IN_BCMP:
5462     case BUILT_IN_MEMCMP:
5463       target = expand_builtin_memcmp (exp, arglist, target, mode);
5464       if (target)
5465         return target;
5466       break;
5467
5468     case BUILT_IN_SETJMP:
5469       target = expand_builtin_setjmp (arglist, target);
5470       if (target)
5471         return target;
5472       break;
5473
5474       /* __builtin_longjmp is passed a pointer to an array of five words.
5475          It's similar to the C library longjmp function but works with
5476          __builtin_setjmp above.  */
5477     case BUILT_IN_LONGJMP:
5478       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5479         break;
5480       else
5481         {
5482           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5483                                       VOIDmode, 0);
5484           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5485                                    NULL_RTX, VOIDmode, 0);
5486
5487           if (value != const1_rtx)
5488             {
5489               error ("__builtin_longjmp second argument must be 1");
5490               return const0_rtx;
5491             }
5492
5493           expand_builtin_longjmp (buf_addr, value);
5494           return const0_rtx;
5495         }
5496
5497     case BUILT_IN_NONLOCAL_GOTO:
5498       target = expand_builtin_nonlocal_goto (arglist);
5499       if (target)
5500         return target;
5501       break;
5502
5503       /* This updates the setjmp buffer that is its argument with the value
5504          of the current stack pointer.  */
5505     case BUILT_IN_UPDATE_SETJMP_BUF:
5506       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5507         {
5508           rtx buf_addr
5509             = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
5510
5511           expand_builtin_update_setjmp_buf (buf_addr);
5512           return const0_rtx;
5513         }
5514       break;
5515
5516     case BUILT_IN_TRAP:
5517       expand_builtin_trap ();
5518       return const0_rtx;
5519
5520     case BUILT_IN_PRINTF:
5521       target = expand_builtin_printf (arglist, target, mode, false);
5522       if (target)
5523         return target;
5524       break;
5525
5526     case BUILT_IN_PRINTF_UNLOCKED:
5527       target = expand_builtin_printf (arglist, target, mode, true);
5528       if (target)
5529         return target;
5530       break;
5531
5532     case BUILT_IN_FPUTS:
5533       target = expand_builtin_fputs (arglist, target, false);
5534       if (target)
5535         return target;
5536       break;
5537     case BUILT_IN_FPUTS_UNLOCKED:
5538       target = expand_builtin_fputs (arglist, target, true);
5539       if (target)
5540         return target;
5541       break;
5542
5543     case BUILT_IN_FPRINTF:
5544       target = expand_builtin_fprintf (arglist, target, mode, false);
5545       if (target)
5546         return target;
5547       break;
5548
5549     case BUILT_IN_FPRINTF_UNLOCKED:
5550       target = expand_builtin_fprintf (arglist, target, mode, true);
5551       if (target)
5552         return target;
5553       break;
5554
5555     case BUILT_IN_SPRINTF:
5556       target = expand_builtin_sprintf (arglist, target, mode);
5557       if (target)
5558         return target;
5559       break;
5560
5561     case BUILT_IN_SIGNBIT:
5562     case BUILT_IN_SIGNBITF:
5563     case BUILT_IN_SIGNBITL:
5564       target = expand_builtin_signbit (exp, target);
5565       if (target)
5566         return target;
5567       break;
5568
5569       /* Various hooks for the DWARF 2 __throw routine.  */
5570     case BUILT_IN_UNWIND_INIT:
5571       expand_builtin_unwind_init ();
5572       return const0_rtx;
5573     case BUILT_IN_DWARF_CFA:
5574       return virtual_cfa_rtx;
5575 #ifdef DWARF2_UNWIND_INFO
5576     case BUILT_IN_DWARF_SP_COLUMN:
5577       return expand_builtin_dwarf_sp_column ();
5578     case BUILT_IN_INIT_DWARF_REG_SIZES:
5579       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5580       return const0_rtx;
5581 #endif
5582     case BUILT_IN_FROB_RETURN_ADDR:
5583       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5584     case BUILT_IN_EXTRACT_RETURN_ADDR:
5585       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5586     case BUILT_IN_EH_RETURN:
5587       expand_builtin_eh_return (TREE_VALUE (arglist),
5588                                 TREE_VALUE (TREE_CHAIN (arglist)));
5589       return const0_rtx;
5590 #ifdef EH_RETURN_DATA_REGNO
5591     case BUILT_IN_EH_RETURN_DATA_REGNO:
5592       return expand_builtin_eh_return_data_regno (arglist);
5593 #endif
5594     case BUILT_IN_EXTEND_POINTER:
5595       return expand_builtin_extend_pointer (TREE_VALUE (arglist));
5596
5597     case BUILT_IN_VA_START:
5598     case BUILT_IN_STDARG_START:
5599       return expand_builtin_va_start (arglist);
5600     case BUILT_IN_VA_END:
5601       return expand_builtin_va_end (arglist);
5602     case BUILT_IN_VA_COPY:
5603       return expand_builtin_va_copy (arglist);
5604     case BUILT_IN_EXPECT:
5605       return expand_builtin_expect (arglist, target);
5606     case BUILT_IN_PREFETCH:
5607       expand_builtin_prefetch (arglist);
5608       return const0_rtx;
5609
5610     case BUILT_IN_PROFILE_FUNC_ENTER:
5611       return expand_builtin_profile_func (false);
5612     case BUILT_IN_PROFILE_FUNC_EXIT:
5613       return expand_builtin_profile_func (true);
5614
5615     case BUILT_IN_INIT_TRAMPOLINE:
5616       return expand_builtin_init_trampoline (arglist);
5617     case BUILT_IN_ADJUST_TRAMPOLINE:
5618       return expand_builtin_adjust_trampoline (arglist);
5619
5620     case BUILT_IN_FORK:
5621     case BUILT_IN_EXECL:
5622     case BUILT_IN_EXECV:
5623     case BUILT_IN_EXECLP:
5624     case BUILT_IN_EXECLE:
5625     case BUILT_IN_EXECVP:
5626     case BUILT_IN_EXECVE:
5627       target = expand_builtin_fork_or_exec (fndecl, arglist, target, ignore);
5628       if (target)
5629         return target;
5630       break;
5631
5632     default:    /* just do library call, if unknown builtin */
5633       break;
5634     }
5635
5636   /* The switch statement above can drop through to cause the function
5637      to be called normally.  */
5638   return expand_call (exp, target, ignore);
5639 }
5640
5641 /* Determine whether a tree node represents a call to a built-in
5642    function.  If the tree T is a call to a built-in function with
5643    the right number of arguments of the appropriate types, return
5644    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5645    Otherwise the return value is END_BUILTINS.  */
5646
5647 enum built_in_function
5648 builtin_mathfn_code (tree t)
5649 {
5650   tree fndecl, arglist, parmlist;
5651   tree argtype, parmtype;
5652
5653   if (TREE_CODE (t) != CALL_EXPR
5654       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5655     return END_BUILTINS;
5656
5657   fndecl = get_callee_fndecl (t);
5658   if (fndecl == NULL_TREE
5659       || TREE_CODE (fndecl) != FUNCTION_DECL
5660       || ! DECL_BUILT_IN (fndecl)
5661       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5662     return END_BUILTINS;
5663
5664   arglist = TREE_OPERAND (t, 1);
5665   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5666   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5667     {
5668       /* If a function doesn't take a variable number of arguments,
5669          the last element in the list will have type `void'.  */
5670       parmtype = TREE_VALUE (parmlist);
5671       if (VOID_TYPE_P (parmtype))
5672         {
5673           if (arglist)
5674             return END_BUILTINS;
5675           return DECL_FUNCTION_CODE (fndecl);
5676         }
5677
5678       if (! arglist)
5679         return END_BUILTINS;
5680
5681       argtype = TREE_TYPE (TREE_VALUE (arglist));
5682
5683       if (SCALAR_FLOAT_TYPE_P (parmtype))
5684         {
5685           if (! SCALAR_FLOAT_TYPE_P (argtype))
5686             return END_BUILTINS;
5687         }
5688       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5689         {
5690           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5691             return END_BUILTINS;
5692         }
5693       else if (POINTER_TYPE_P (parmtype))
5694         {
5695           if (! POINTER_TYPE_P (argtype))
5696             return END_BUILTINS;
5697         }
5698       else if (INTEGRAL_TYPE_P (parmtype))
5699         {
5700           if (! INTEGRAL_TYPE_P (argtype))
5701             return END_BUILTINS;
5702         }
5703       else
5704         return END_BUILTINS;
5705
5706       arglist = TREE_CHAIN (arglist);
5707     }
5708
5709   /* Variable-length argument list.  */
5710   return DECL_FUNCTION_CODE (fndecl);
5711 }
5712
5713 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5714    constant.  ARGLIST is the argument list of the call.  */
5715
5716 static tree
5717 fold_builtin_constant_p (tree arglist)
5718 {
5719   if (arglist == 0)
5720     return 0;
5721
5722   arglist = TREE_VALUE (arglist);
5723
5724   /* We return 1 for a numeric type that's known to be a constant
5725      value at compile-time or for an aggregate type that's a
5726      literal constant.  */
5727   STRIP_NOPS (arglist);
5728
5729   /* If we know this is a constant, emit the constant of one.  */
5730   if (CONSTANT_CLASS_P (arglist)
5731       || (TREE_CODE (arglist) == CONSTRUCTOR
5732           && TREE_CONSTANT (arglist))
5733       || (TREE_CODE (arglist) == ADDR_EXPR
5734           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5735     return integer_one_node;
5736
5737   /* If this expression has side effects, show we don't know it to be a
5738      constant.  Likewise if it's a pointer or aggregate type since in
5739      those case we only want literals, since those are only optimized
5740      when generating RTL, not later.
5741      And finally, if we are compiling an initializer, not code, we
5742      need to return a definite result now; there's not going to be any
5743      more optimization done.  */
5744   if (TREE_SIDE_EFFECTS (arglist)
5745       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5746       || POINTER_TYPE_P (TREE_TYPE (arglist))
5747       || cfun == 0)
5748     return integer_zero_node;
5749
5750   return 0;
5751 }
5752
5753 /* Fold a call to __builtin_expect, if we expect that a comparison against
5754    the argument will fold to a constant.  In practice, this means a true
5755    constant or the address of a non-weak symbol.  ARGLIST is the argument
5756    list of the call.  */
5757
5758 static tree
5759 fold_builtin_expect (tree arglist)
5760 {
5761   tree arg, inner;
5762
5763   if (arglist == 0)
5764     return 0;
5765
5766   arg = TREE_VALUE (arglist);
5767
5768   /* If the argument isn't invariant, then there's nothing we can do.  */
5769   if (!TREE_INVARIANT (arg))
5770     return 0;
5771
5772   /* If we're looking at an address of a weak decl, then do not fold.  */
5773   inner = arg;
5774   STRIP_NOPS (inner);
5775   if (TREE_CODE (inner) == ADDR_EXPR)
5776     {
5777       do
5778         {
5779           inner = TREE_OPERAND (inner, 0);
5780         }
5781       while (TREE_CODE (inner) == COMPONENT_REF
5782              || TREE_CODE (inner) == ARRAY_REF);
5783       if (DECL_P (inner) && DECL_WEAK (inner))
5784         return 0;
5785     }
5786
5787   /* Otherwise, ARG already has the proper type for the return value.  */
5788   return arg;
5789 }
5790
5791 /* Fold a call to __builtin_classify_type.  */
5792
5793 static tree
5794 fold_builtin_classify_type (tree arglist)
5795 {
5796   if (arglist == 0)
5797     return build_int_cst (NULL_TREE, no_type_class);
5798
5799   return build_int_cst (NULL_TREE,
5800                         type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
5801 }
5802
5803 /* Fold a call to __builtin_strlen.  */
5804
5805 static tree
5806 fold_builtin_strlen (tree arglist)
5807 {
5808   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5809     return NULL_TREE;
5810   else
5811     {
5812       tree len = c_strlen (TREE_VALUE (arglist), 0);
5813
5814       if (len)
5815         {
5816           /* Convert from the internal "sizetype" type to "size_t".  */
5817           if (size_type_node)
5818             len = fold_convert (size_type_node, len);
5819           return len;
5820         }
5821
5822       return NULL_TREE;
5823     }
5824 }
5825
5826 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5827
5828 static tree
5829 fold_builtin_inf (tree type, int warn)
5830 {
5831   REAL_VALUE_TYPE real;
5832
5833   /* __builtin_inff is intended to be usable to define INFINITY on all
5834      targets.  If an infinity is not available, INFINITY expands "to a
5835      positive constant of type float that overflows at translation
5836      time", footnote "In this case, using INFINITY will violate the
5837      constraint in 6.4.4 and thus require a diagnostic." (C99 7.12#4).
5838      Thus we pedwarn to ensure this constraint violation is
5839      diagnosed.  */
5840   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5841     pedwarn ("target format does not support infinity");
5842
5843   real_inf (&real);
5844   return build_real (type, real);
5845 }
5846
5847 /* Fold a call to __builtin_nan or __builtin_nans.  */
5848
5849 static tree
5850 fold_builtin_nan (tree arglist, tree type, int quiet)
5851 {
5852   REAL_VALUE_TYPE real;
5853   const char *str;
5854
5855   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5856     return 0;
5857   str = c_getstr (TREE_VALUE (arglist));
5858   if (!str)
5859     return 0;
5860
5861   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5862     return 0;
5863
5864   return build_real (type, real);
5865 }
5866
5867 /* Return true if the floating point expression T has an integer value.
5868    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5869
5870 static bool
5871 integer_valued_real_p (tree t)
5872 {
5873   switch (TREE_CODE (t))
5874     {
5875     case FLOAT_EXPR:
5876       return true;
5877
5878     case ABS_EXPR:
5879     case SAVE_EXPR:
5880     case NON_LVALUE_EXPR:
5881       return integer_valued_real_p (TREE_OPERAND (t, 0));
5882
5883     case COMPOUND_EXPR:
5884     case MODIFY_EXPR:
5885     case BIND_EXPR:
5886       return integer_valued_real_p (TREE_OPERAND (t, 1));
5887
5888     case PLUS_EXPR:
5889     case MINUS_EXPR:
5890     case MULT_EXPR:
5891     case MIN_EXPR:
5892     case MAX_EXPR:
5893       return integer_valued_real_p (TREE_OPERAND (t, 0))
5894              && integer_valued_real_p (TREE_OPERAND (t, 1));
5895
5896     case COND_EXPR:
5897       return integer_valued_real_p (TREE_OPERAND (t, 1))
5898              && integer_valued_real_p (TREE_OPERAND (t, 2));
5899
5900     case REAL_CST:
5901       if (! TREE_CONSTANT_OVERFLOW (t))
5902       {
5903         REAL_VALUE_TYPE c, cint;
5904
5905         c = TREE_REAL_CST (t);
5906         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5907         return real_identical (&c, &cint);
5908       }
5909
5910     case NOP_EXPR:
5911       {
5912         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5913         if (TREE_CODE (type) == INTEGER_TYPE)
5914           return true;
5915         if (TREE_CODE (type) == REAL_TYPE)
5916           return integer_valued_real_p (TREE_OPERAND (t, 0));
5917         break;
5918       }
5919
5920     case CALL_EXPR:
5921       switch (builtin_mathfn_code (t))
5922         {
5923         case BUILT_IN_CEIL:
5924         case BUILT_IN_CEILF:
5925         case BUILT_IN_CEILL:
5926         case BUILT_IN_FLOOR:
5927         case BUILT_IN_FLOORF:
5928         case BUILT_IN_FLOORL:
5929         case BUILT_IN_NEARBYINT:
5930         case BUILT_IN_NEARBYINTF:
5931         case BUILT_IN_NEARBYINTL:
5932         case BUILT_IN_RINT:
5933         case BUILT_IN_RINTF:
5934         case BUILT_IN_RINTL:
5935         case BUILT_IN_ROUND:
5936         case BUILT_IN_ROUNDF:
5937         case BUILT_IN_ROUNDL:
5938         case BUILT_IN_TRUNC:
5939         case BUILT_IN_TRUNCF:
5940         case BUILT_IN_TRUNCL:
5941           return true;
5942
5943         default:
5944           break;
5945         }
5946       break;
5947
5948     default:
5949       break;
5950     }
5951   return false;
5952 }
5953
5954 /* EXP is assumed to be builtin call where truncation can be propagated
5955    across (for instance floor((double)f) == (double)floorf (f).
5956    Do the transformation.  */
5957
5958 static tree
5959 fold_trunc_transparent_mathfn (tree exp)
5960 {
5961   tree fndecl = get_callee_fndecl (exp);
5962   tree arglist = TREE_OPERAND (exp, 1);
5963   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5964   tree arg;
5965
5966   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5967     return 0;
5968
5969   arg = TREE_VALUE (arglist);
5970   /* Integer rounding functions are idempotent.  */
5971   if (fcode == builtin_mathfn_code (arg))
5972     return arg;
5973
5974   /* If argument is already integer valued, and we don't need to worry
5975      about setting errno, there's no need to perform rounding.  */
5976   if (! flag_errno_math && integer_valued_real_p (arg))
5977     return arg;
5978
5979   if (optimize)
5980     {
5981       tree arg0 = strip_float_extensions (arg);
5982       tree ftype = TREE_TYPE (exp);
5983       tree newtype = TREE_TYPE (arg0);
5984       tree decl;
5985
5986       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5987           && (decl = mathfn_built_in (newtype, fcode)))
5988         {
5989           arglist =
5990             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
5991           return fold_convert (ftype,
5992                                build_function_call_expr (decl, arglist));
5993         }
5994     }
5995   return 0;
5996 }
5997
5998 /* EXP is assumed to be builtin call which can narrow the FP type of
5999    the argument, for instance lround((double)f) -> lroundf (f).  */
6000
6001 static tree
6002 fold_fixed_mathfn (tree exp)
6003 {
6004   tree fndecl = get_callee_fndecl (exp);
6005   tree arglist = TREE_OPERAND (exp, 1);
6006   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
6007   tree arg;
6008
6009   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6010     return 0;
6011
6012   arg = TREE_VALUE (arglist);
6013
6014   /* If argument is already integer valued, and we don't need to worry
6015      about setting errno, there's no need to perform rounding.  */
6016   if (! flag_errno_math && integer_valued_real_p (arg))
6017     return fold (build1 (FIX_TRUNC_EXPR, TREE_TYPE (exp), arg));
6018
6019   if (optimize)
6020     {
6021       tree ftype = TREE_TYPE (arg);
6022       tree arg0 = strip_float_extensions (arg);
6023       tree newtype = TREE_TYPE (arg0);
6024       tree decl;
6025
6026       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
6027           && (decl = mathfn_built_in (newtype, fcode)))
6028         {
6029           arglist =
6030             build_tree_list (NULL_TREE, fold_convert (newtype, arg0));
6031           return build_function_call_expr (decl, arglist);
6032         }
6033     }
6034   return 0;
6035 }
6036
6037 /* Fold function call to builtin cabs, cabsf or cabsl.  ARGLIST
6038    is the argument list and TYPE is the return type.  Return
6039    NULL_TREE if no if no simplification can be made.  */
6040
6041 static tree
6042 fold_builtin_cabs (tree arglist, tree type)
6043 {
6044   tree arg;
6045
6046   if (!arglist || TREE_CHAIN (arglist))
6047     return NULL_TREE;
6048
6049   arg = TREE_VALUE (arglist);
6050   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
6051       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
6052     return NULL_TREE;
6053
6054   /* Evaluate cabs of a constant at compile-time.  */
6055   if (flag_unsafe_math_optimizations
6056       && TREE_CODE (arg) == COMPLEX_CST
6057       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
6058       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
6059       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
6060       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
6061     {
6062       REAL_VALUE_TYPE r, i;
6063
6064       r = TREE_REAL_CST (TREE_REALPART (arg));
6065       i = TREE_REAL_CST (TREE_IMAGPART (arg));
6066
6067       real_arithmetic (&r, MULT_EXPR, &r, &r);
6068       real_arithmetic (&i, MULT_EXPR, &i, &i);
6069       real_arithmetic (&r, PLUS_EXPR, &r, &i);
6070       if (real_sqrt (&r, TYPE_MODE (type), &r)
6071           || ! flag_trapping_math)
6072         return build_real (type, r);
6073     }
6074
6075   /* If either part is zero, cabs is fabs of the other.  */
6076   if (TREE_CODE (arg) == COMPLEX_EXPR
6077       && real_zerop (TREE_OPERAND (arg, 0)))
6078     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
6079   if (TREE_CODE (arg) == COMPLEX_EXPR
6080       && real_zerop (TREE_OPERAND (arg, 1)))
6081     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
6082
6083   /* Don't do this when optimizing for size.  */
6084   if (flag_unsafe_math_optimizations
6085       && optimize && !optimize_size)
6086     {
6087       tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6088
6089       if (sqrtfn != NULL_TREE)
6090         {
6091           tree rpart, ipart, result, arglist;
6092
6093           arg = builtin_save_expr (arg);
6094
6095           rpart = fold (build1 (REALPART_EXPR, type, arg));
6096           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
6097
6098           rpart = builtin_save_expr (rpart);
6099           ipart = builtin_save_expr (ipart);
6100
6101           result = fold (build2 (PLUS_EXPR, type,
6102                                  fold (build2 (MULT_EXPR, type,
6103                                                rpart, rpart)),
6104                                  fold (build2 (MULT_EXPR, type,
6105                                                ipart, ipart))));
6106
6107           arglist = build_tree_list (NULL_TREE, result);
6108           return build_function_call_expr (sqrtfn, arglist);
6109         }
6110     }
6111
6112   return NULL_TREE;
6113 }
6114
6115 /* Fold a builtin function call to sqrt, sqrtf, or sqrtl.  Return
6116    NULL_TREE if no simplification can be made.  */
6117
6118 static tree
6119 fold_builtin_sqrt (tree arglist, tree type)
6120 {
6121
6122   enum built_in_function fcode;
6123   tree arg = TREE_VALUE (arglist);
6124
6125   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6126     return NULL_TREE;
6127
6128   /* Optimize sqrt of constant value.  */
6129   if (TREE_CODE (arg) == REAL_CST
6130       && ! TREE_CONSTANT_OVERFLOW (arg))
6131     {
6132       REAL_VALUE_TYPE r, x;
6133
6134       x = TREE_REAL_CST (arg);
6135       if (real_sqrt (&r, TYPE_MODE (type), &x)
6136           || (!flag_trapping_math && !flag_errno_math))
6137         return build_real (type, r);
6138     }
6139
6140   /* Optimize sqrt(expN(x)) = expN(x*0.5).  */
6141   fcode = builtin_mathfn_code (arg);
6142   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6143     {
6144       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6145       arg = fold (build2 (MULT_EXPR, type,
6146                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6147                           build_real (type, dconsthalf)));
6148       arglist = build_tree_list (NULL_TREE, arg);
6149       return build_function_call_expr (expfn, arglist);
6150     }
6151
6152   /* Optimize sqrt(Nroot(x)) -> pow(x,1/(2*N)).  */
6153   if (flag_unsafe_math_optimizations && BUILTIN_ROOT_P (fcode))
6154     {
6155       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6156
6157       if (powfn)
6158         {
6159           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6160           tree tree_root;
6161           /* The inner root was either sqrt or cbrt.  */
6162           REAL_VALUE_TYPE dconstroot =
6163             BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird;
6164
6165           /* Adjust for the outer root.  */
6166           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6167           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6168           tree_root = build_real (type, dconstroot);
6169           arglist = tree_cons (NULL_TREE, arg0,
6170                                build_tree_list (NULL_TREE, tree_root));
6171           return build_function_call_expr (powfn, arglist);
6172         }
6173     }
6174
6175   /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6176   if (flag_unsafe_math_optimizations
6177       && (fcode == BUILT_IN_POW
6178           || fcode == BUILT_IN_POWF
6179           || fcode == BUILT_IN_POWL))
6180     {
6181       tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6182       tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6183       tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6184       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6185                                  build_real (type, dconsthalf)));
6186       arglist = tree_cons (NULL_TREE, arg0,
6187                            build_tree_list (NULL_TREE, narg1));
6188       return build_function_call_expr (powfn, arglist);
6189     }
6190
6191   return NULL_TREE;
6192 }
6193
6194 /* Fold a builtin function call to cbrt, cbrtf, or cbrtl.  Return
6195    NULL_TREE if no simplification can be made.  */
6196 static tree
6197 fold_builtin_cbrt (tree arglist, tree type)
6198 {
6199   tree arg = TREE_VALUE (arglist);
6200   const enum built_in_function fcode = builtin_mathfn_code (arg);
6201
6202   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6203     return NULL_TREE;
6204
6205   /* Optimize cbrt of constant value.  */
6206   if (real_zerop (arg) || real_onep (arg) || real_minus_onep (arg))
6207     return arg;
6208
6209   /* Optimize cbrt(expN(x)) -> expN(x/3).  */
6210   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6211     {
6212       tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6213       const REAL_VALUE_TYPE third_trunc =
6214         real_value_truncate (TYPE_MODE (type), dconstthird);
6215       arg = fold (build2 (MULT_EXPR, type,
6216                           TREE_VALUE (TREE_OPERAND (arg, 1)),
6217                           build_real (type, third_trunc)));
6218       arglist = build_tree_list (NULL_TREE, arg);
6219       return build_function_call_expr (expfn, arglist);
6220     }
6221
6222   /* Optimize cbrt(sqrt(x)) -> pow(x,1/6).  */
6223   /* We don't optimize cbrt(cbrt(x)) -> pow(x,1/9) because if
6224      x is negative pow will error but cbrt won't.  */
6225   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6226     {
6227       tree powfn = mathfn_built_in (type, BUILT_IN_POW);
6228
6229       if (powfn)
6230         {
6231           tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6232           tree tree_root;
6233           REAL_VALUE_TYPE dconstroot = dconstthird;
6234
6235           SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
6236           dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
6237           tree_root = build_real (type, dconstroot);
6238           arglist = tree_cons (NULL_TREE, arg0,
6239                                build_tree_list (NULL_TREE, tree_root));
6240           return build_function_call_expr (powfn, arglist);
6241         }
6242
6243     }
6244   return NULL_TREE;
6245 }
6246
6247 /* Fold function call to builtin sin, sinf, or sinl.  Return
6248    NULL_TREE if no simplification can be made.  */
6249 static tree
6250 fold_builtin_sin (tree arglist)
6251 {
6252   tree arg = TREE_VALUE (arglist);
6253
6254   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6255     return NULL_TREE;
6256
6257   /* Optimize sin (0.0) = 0.0.  */
6258   if (real_zerop (arg))
6259     return arg;
6260
6261   return NULL_TREE;
6262 }
6263
6264 /* Fold function call to builtin cos, cosf, or cosl.  Return
6265    NULL_TREE if no simplification can be made.  */
6266 static tree
6267 fold_builtin_cos (tree arglist, tree type, tree fndecl)
6268 {
6269   tree arg = TREE_VALUE (arglist);
6270
6271   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6272     return NULL_TREE;
6273
6274   /* Optimize cos (0.0) = 1.0.  */
6275   if (real_zerop (arg))
6276     return build_real (type, dconst1);
6277
6278   /* Optimize cos(-x) into cos (x).  */
6279   if (TREE_CODE (arg) == NEGATE_EXPR)
6280     {
6281       tree args = build_tree_list (NULL_TREE,
6282                                    TREE_OPERAND (arg, 0));
6283       return build_function_call_expr (fndecl, args);
6284     }
6285
6286   return NULL_TREE;
6287 }
6288
6289 /* Fold function call to builtin tan, tanf, or tanl.  Return
6290    NULL_TREE if no simplification can be made.  */
6291 static tree
6292 fold_builtin_tan (tree arglist)
6293 {
6294   enum built_in_function fcode;
6295   tree arg = TREE_VALUE (arglist);
6296
6297   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6298     return NULL_TREE;
6299
6300   /* Optimize tan(0.0) = 0.0.  */
6301   if (real_zerop (arg))
6302     return arg;
6303
6304   /* Optimize tan(atan(x)) = x.  */
6305   fcode = builtin_mathfn_code (arg);
6306   if (flag_unsafe_math_optimizations
6307       && (fcode == BUILT_IN_ATAN
6308           || fcode == BUILT_IN_ATANF
6309           || fcode == BUILT_IN_ATANL))
6310     return TREE_VALUE (TREE_OPERAND (arg, 1));
6311
6312   return NULL_TREE;
6313 }
6314
6315 /* Fold function call to builtin atan, atanf, or atanl.  Return
6316    NULL_TREE if no simplification can be made.  */
6317
6318 static tree
6319 fold_builtin_atan (tree arglist, tree type)
6320 {
6321
6322   tree arg = TREE_VALUE (arglist);
6323
6324   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6325     return NULL_TREE;
6326
6327   /* Optimize atan(0.0) = 0.0.  */
6328   if (real_zerop (arg))
6329     return arg;
6330
6331   /* Optimize atan(1.0) = pi/4.  */
6332   if (real_onep (arg))
6333     {
6334       REAL_VALUE_TYPE cst;
6335
6336       real_convert (&cst, TYPE_MODE (type), &dconstpi);
6337       SET_REAL_EXP (&cst, REAL_EXP (&cst) - 2);
6338       return build_real (type, cst);
6339     }
6340
6341   return NULL_TREE;
6342 }
6343
6344 /* Fold function call to builtin trunc, truncf or truncl.  Return
6345    NULL_TREE if no simplification can be made.  */
6346
6347 static tree
6348 fold_builtin_trunc (tree exp)
6349 {
6350   tree arglist = TREE_OPERAND (exp, 1);
6351   tree arg;
6352
6353   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6354     return 0;
6355
6356   /* Optimize trunc of constant value.  */
6357   arg = TREE_VALUE (arglist);
6358   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6359     {
6360       REAL_VALUE_TYPE r, x;
6361       tree type = TREE_TYPE (exp);
6362
6363       x = TREE_REAL_CST (arg);
6364       real_trunc (&r, TYPE_MODE (type), &x);
6365       return build_real (type, r);
6366     }
6367
6368   return fold_trunc_transparent_mathfn (exp);
6369 }
6370
6371 /* Fold function call to builtin floor, floorf or floorl.  Return
6372    NULL_TREE if no simplification can be made.  */
6373
6374 static tree
6375 fold_builtin_floor (tree exp)
6376 {
6377   tree arglist = TREE_OPERAND (exp, 1);
6378   tree arg;
6379
6380   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6381     return 0;
6382
6383   /* Optimize floor of constant value.  */
6384   arg = TREE_VALUE (arglist);
6385   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6386     {
6387       REAL_VALUE_TYPE x;
6388
6389       x = TREE_REAL_CST (arg);
6390       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6391         {
6392           tree type = TREE_TYPE (exp);
6393           REAL_VALUE_TYPE r;
6394
6395           real_floor (&r, TYPE_MODE (type), &x);
6396           return build_real (type, r);
6397         }
6398     }
6399
6400   return fold_trunc_transparent_mathfn (exp);
6401 }
6402
6403 /* Fold function call to builtin ceil, ceilf or ceill.  Return
6404    NULL_TREE if no simplification can be made.  */
6405
6406 static tree
6407 fold_builtin_ceil (tree exp)
6408 {
6409   tree arglist = TREE_OPERAND (exp, 1);
6410   tree arg;
6411
6412   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6413     return 0;
6414
6415   /* Optimize ceil of constant value.  */
6416   arg = TREE_VALUE (arglist);
6417   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6418     {
6419       REAL_VALUE_TYPE x;
6420
6421       x = TREE_REAL_CST (arg);
6422       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6423         {
6424           tree type = TREE_TYPE (exp);
6425           REAL_VALUE_TYPE r;
6426
6427           real_ceil (&r, TYPE_MODE (type), &x);
6428           return build_real (type, r);
6429         }
6430     }
6431
6432   return fold_trunc_transparent_mathfn (exp);
6433 }
6434
6435 /* Fold function call to builtin round, roundf or roundl.  Return
6436    NULL_TREE if no simplification can be made.  */
6437
6438 static tree
6439 fold_builtin_round (tree exp)
6440 {
6441   tree arglist = TREE_OPERAND (exp, 1);
6442   tree arg;
6443
6444   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6445     return 0;
6446
6447   /* Optimize round of constant value.  */
6448   arg = TREE_VALUE (arglist);
6449   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6450     {
6451       REAL_VALUE_TYPE x;
6452
6453       x = TREE_REAL_CST (arg);
6454       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
6455         {
6456           tree type = TREE_TYPE (exp);
6457           REAL_VALUE_TYPE r;
6458
6459           real_round (&r, TYPE_MODE (type), &x);
6460           return build_real (type, r);
6461         }
6462     }
6463
6464   return fold_trunc_transparent_mathfn (exp);
6465 }
6466
6467 /* Fold function call to builtin lround, lroundf or lroundl (or the
6468    corresponding long long versions).  Return NULL_TREE if no
6469    simplification can be made.  */
6470
6471 static tree
6472 fold_builtin_lround (tree exp)
6473 {
6474   tree arglist = TREE_OPERAND (exp, 1);
6475   tree arg;
6476
6477   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6478     return 0;
6479
6480   /* Optimize lround of constant value.  */
6481   arg = TREE_VALUE (arglist);
6482   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6483     {
6484       const REAL_VALUE_TYPE x = TREE_REAL_CST (arg);
6485
6486       if (! REAL_VALUE_ISNAN (x) && ! REAL_VALUE_ISINF (x))
6487         {
6488           tree itype = TREE_TYPE (exp), ftype = TREE_TYPE (arg), result;
6489           HOST_WIDE_INT hi, lo;
6490           REAL_VALUE_TYPE r;
6491
6492           real_round (&r, TYPE_MODE (ftype), &x);
6493           REAL_VALUE_TO_INT (&lo, &hi, r);
6494           result = build_int_cst_wide (NULL_TREE, lo, hi);
6495           if (int_fits_type_p (result, itype))
6496             return fold_convert (itype, result);
6497         }
6498     }
6499
6500   return fold_fixed_mathfn (exp);
6501 }
6502
6503 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
6504    and their long and long long variants (i.e. ffsl and ffsll).
6505    Return NULL_TREE if no simplification can be made.  */
6506
6507 static tree
6508 fold_builtin_bitop (tree exp)
6509 {
6510   tree fndecl = get_callee_fndecl (exp);
6511   tree arglist = TREE_OPERAND (exp, 1);
6512   tree arg;
6513
6514   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
6515     return NULL_TREE;
6516
6517   /* Optimize for constant argument.  */
6518   arg = TREE_VALUE (arglist);
6519   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
6520     {
6521       HOST_WIDE_INT hi, width, result;
6522       unsigned HOST_WIDE_INT lo;
6523       tree type;
6524
6525       type = TREE_TYPE (arg);
6526       width = TYPE_PRECISION (type);
6527       lo = TREE_INT_CST_LOW (arg);
6528
6529       /* Clear all the bits that are beyond the type's precision.  */
6530       if (width > HOST_BITS_PER_WIDE_INT)
6531         {
6532           hi = TREE_INT_CST_HIGH (arg);
6533           if (width < 2 * HOST_BITS_PER_WIDE_INT)
6534             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
6535         }
6536       else
6537         {
6538           hi = 0;
6539           if (width < HOST_BITS_PER_WIDE_INT)
6540             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
6541         }
6542
6543       switch (DECL_FUNCTION_CODE (fndecl))
6544         {
6545         case BUILT_IN_FFS:
6546         case BUILT_IN_FFSL:
6547         case BUILT_IN_FFSLL:
6548           if (lo != 0)
6549             result = exact_log2 (lo & -lo) + 1;
6550           else if (hi != 0)
6551             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
6552           else
6553             result = 0;
6554           break;
6555
6556         case BUILT_IN_CLZ:
6557         case BUILT_IN_CLZL:
6558         case BUILT_IN_CLZLL:
6559           if (hi != 0)
6560             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
6561           else if (lo != 0)
6562             result = width - floor_log2 (lo) - 1;
6563           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6564             result = width;
6565           break;
6566
6567         case BUILT_IN_CTZ:
6568         case BUILT_IN_CTZL:
6569         case BUILT_IN_CTZLL:
6570           if (lo != 0)
6571             result = exact_log2 (lo & -lo);
6572           else if (hi != 0)
6573             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
6574           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
6575             result = width;
6576           break;
6577
6578         case BUILT_IN_POPCOUNT:
6579         case BUILT_IN_POPCOUNTL:
6580         case BUILT_IN_POPCOUNTLL:
6581           result = 0;
6582           while (lo)
6583             result++, lo &= lo - 1;
6584           while (hi)
6585             result++, hi &= hi - 1;
6586           break;
6587
6588         case BUILT_IN_PARITY:
6589         case BUILT_IN_PARITYL:
6590         case BUILT_IN_PARITYLL:
6591           result = 0;
6592           while (lo)
6593             result++, lo &= lo - 1;
6594           while (hi)
6595             result++, hi &= hi - 1;
6596           result &= 1;
6597           break;
6598
6599         default:
6600           gcc_unreachable ();
6601         }
6602
6603       return build_int_cst (TREE_TYPE (exp), result);
6604     }
6605
6606   return NULL_TREE;
6607 }
6608
6609 /* Return true if EXPR is the real constant contained in VALUE.  */
6610
6611 static bool
6612 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6613 {
6614   STRIP_NOPS (expr);
6615
6616   return ((TREE_CODE (expr) == REAL_CST
6617            && ! TREE_CONSTANT_OVERFLOW (expr)
6618            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6619           || (TREE_CODE (expr) == COMPLEX_CST
6620               && real_dconstp (TREE_REALPART (expr), value)
6621               && real_zerop (TREE_IMAGPART (expr))));
6622 }
6623
6624 /* A subroutine of fold_builtin to fold the various logarithmic
6625    functions.  EXP is the CALL_EXPR of a call to a builtin logN
6626    function.  VALUE is the base of the logN function.  */
6627
6628 static tree
6629 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6630 {
6631   tree arglist = TREE_OPERAND (exp, 1);
6632
6633   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6634     {
6635       tree fndecl = get_callee_fndecl (exp);
6636       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6637       tree arg = TREE_VALUE (arglist);
6638       const enum built_in_function fcode = builtin_mathfn_code (arg);
6639
6640       /* Optimize logN(1.0) = 0.0.  */
6641       if (real_onep (arg))
6642         return build_real (type, dconst0);
6643
6644       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6645          exactly, then only do this if flag_unsafe_math_optimizations.  */
6646       if (exact_real_truncate (TYPE_MODE (type), value)
6647           || flag_unsafe_math_optimizations)
6648         {
6649           const REAL_VALUE_TYPE value_truncate =
6650             real_value_truncate (TYPE_MODE (type), *value);
6651           if (real_dconstp (arg, &value_truncate))
6652             return build_real (type, dconst1);
6653         }
6654
6655       /* Special case, optimize logN(expN(x)) = x.  */
6656       if (flag_unsafe_math_optimizations
6657           && ((value == &dconste
6658                && (fcode == BUILT_IN_EXP
6659                    || fcode == BUILT_IN_EXPF
6660                    || fcode == BUILT_IN_EXPL))
6661               || (value == &dconst2
6662                   && (fcode == BUILT_IN_EXP2
6663                       || fcode == BUILT_IN_EXP2F
6664                       || fcode == BUILT_IN_EXP2L))
6665               || (value == &dconst10 && (BUILTIN_EXP10_P (fcode)))))
6666         return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6667
6668       /* Optimize logN(func()) for various exponential functions.  We
6669          want to determine the value "x" and the power "exponent" in
6670          order to transform logN(x**exponent) into exponent*logN(x).  */
6671       if (flag_unsafe_math_optimizations)
6672         {
6673           tree exponent = 0, x = 0;
6674
6675           switch (fcode)
6676           {
6677           case BUILT_IN_EXP:
6678           case BUILT_IN_EXPF:
6679           case BUILT_IN_EXPL:
6680             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6681             x = build_real (type,
6682                             real_value_truncate (TYPE_MODE (type), dconste));
6683             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6684             break;
6685           case BUILT_IN_EXP2:
6686           case BUILT_IN_EXP2F:
6687           case BUILT_IN_EXP2L:
6688             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6689             x = build_real (type, dconst2);
6690             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6691             break;
6692           case BUILT_IN_EXP10:
6693           case BUILT_IN_EXP10F:
6694           case BUILT_IN_EXP10L:
6695           case BUILT_IN_POW10:
6696           case BUILT_IN_POW10F:
6697           case BUILT_IN_POW10L:
6698             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6699             x = build_real (type, dconst10);
6700             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6701             break;
6702           case BUILT_IN_SQRT:
6703           case BUILT_IN_SQRTF:
6704           case BUILT_IN_SQRTL:
6705             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6706             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6707             exponent = build_real (type, dconsthalf);
6708             break;
6709           case BUILT_IN_CBRT:
6710           case BUILT_IN_CBRTF:
6711           case BUILT_IN_CBRTL:
6712             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6713             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6714             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6715                                                               dconstthird));
6716             break;
6717           case BUILT_IN_POW:
6718           case BUILT_IN_POWF:
6719           case BUILT_IN_POWL:
6720             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6721             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6722             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6723             break;
6724           default:
6725             break;
6726           }
6727
6728           /* Now perform the optimization.  */
6729           if (x && exponent)
6730             {
6731               tree logfn;
6732               arglist = build_tree_list (NULL_TREE, x);
6733               logfn = build_function_call_expr (fndecl, arglist);
6734               return fold (build2 (MULT_EXPR, type, exponent, logfn));
6735             }
6736         }
6737     }
6738
6739   return 0;
6740 }
6741
6742 /* Fold a builtin function call to pow, powf, or powl.  Return
6743    NULL_TREE if no simplification can be made.  */
6744 static tree
6745 fold_builtin_pow (tree fndecl, tree arglist, tree type)
6746 {
6747   enum built_in_function fcode;
6748   tree arg0 = TREE_VALUE (arglist);
6749   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6750
6751   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6752     return NULL_TREE;
6753
6754   /* Optimize pow(1.0,y) = 1.0.  */
6755   if (real_onep (arg0))
6756     return omit_one_operand (type, build_real (type, dconst1), arg1);
6757
6758   if (TREE_CODE (arg1) == REAL_CST
6759       && ! TREE_CONSTANT_OVERFLOW (arg1))
6760     {
6761       REAL_VALUE_TYPE c;
6762       c = TREE_REAL_CST (arg1);
6763
6764       /* Optimize pow(x,0.0) = 1.0.  */
6765       if (REAL_VALUES_EQUAL (c, dconst0))
6766         return omit_one_operand (type, build_real (type, dconst1),
6767                                  arg0);
6768
6769       /* Optimize pow(x,1.0) = x.  */
6770       if (REAL_VALUES_EQUAL (c, dconst1))
6771         return arg0;
6772
6773       /* Optimize pow(x,-1.0) = 1.0/x.  */
6774       if (REAL_VALUES_EQUAL (c, dconstm1))
6775         return fold (build2 (RDIV_EXPR, type,
6776                              build_real (type, dconst1), arg0));
6777
6778       /* Optimize pow(x,0.5) = sqrt(x).  */
6779       if (flag_unsafe_math_optimizations
6780           && REAL_VALUES_EQUAL (c, dconsthalf))
6781         {
6782           tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
6783
6784           if (sqrtfn != NULL_TREE)
6785             {
6786               tree arglist = build_tree_list (NULL_TREE, arg0);
6787               return build_function_call_expr (sqrtfn, arglist);
6788             }
6789         }
6790
6791       /* Attempt to evaluate pow at compile-time.  */
6792       if (TREE_CODE (arg0) == REAL_CST
6793           && ! TREE_CONSTANT_OVERFLOW (arg0))
6794         {
6795           REAL_VALUE_TYPE cint;
6796           HOST_WIDE_INT n;
6797
6798           n = real_to_integer (&c);
6799           real_from_integer (&cint, VOIDmode, n,
6800                              n < 0 ? -1 : 0, 0);
6801           if (real_identical (&c, &cint))
6802             {
6803               REAL_VALUE_TYPE x;
6804               bool inexact;
6805
6806               x = TREE_REAL_CST (arg0);
6807               inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6808               if (flag_unsafe_math_optimizations || !inexact)
6809                 return build_real (type, x);
6810             }
6811         }
6812     }
6813
6814   /* Optimize pow(expN(x),y) = expN(x*y).  */
6815   fcode = builtin_mathfn_code (arg0);
6816   if (flag_unsafe_math_optimizations && BUILTIN_EXPONENT_P (fcode))
6817     {
6818       tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6819       tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6820       arg = fold (build2 (MULT_EXPR, type, arg, arg1));
6821       arglist = build_tree_list (NULL_TREE, arg);
6822       return build_function_call_expr (expfn, arglist);
6823     }
6824
6825   /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6826   if (flag_unsafe_math_optimizations && BUILTIN_SQRT_P (fcode))
6827     {
6828       tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6829       tree narg1 = fold (build2 (MULT_EXPR, type, arg1,
6830                                  build_real (type, dconsthalf)));
6831
6832       arglist = tree_cons (NULL_TREE, narg0,
6833                            build_tree_list (NULL_TREE, narg1));
6834       return build_function_call_expr (fndecl, arglist);
6835     }
6836
6837   /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6838   if (flag_unsafe_math_optimizations
6839       && (fcode == BUILT_IN_POW
6840           || fcode == BUILT_IN_POWF
6841           || fcode == BUILT_IN_POWL))
6842     {
6843       tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6844       tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6845       tree narg1 = fold (build2 (MULT_EXPR, type, arg01, arg1));
6846       arglist = tree_cons (NULL_TREE, arg00,
6847                            build_tree_list (NULL_TREE, narg1));
6848       return build_function_call_expr (fndecl, arglist);
6849     }
6850   return NULL_TREE;
6851 }
6852
6853 /* A subroutine of fold_builtin to fold the various exponent
6854    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6855    VALUE is the value which will be raised to a power.  */
6856
6857 static tree
6858 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6859 {
6860   tree arglist = TREE_OPERAND (exp, 1);
6861
6862   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6863     {
6864       tree fndecl = get_callee_fndecl (exp);
6865       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6866       tree arg = TREE_VALUE (arglist);
6867
6868       /* Optimize exp*(0.0) = 1.0.  */
6869       if (real_zerop (arg))
6870         return build_real (type, dconst1);
6871
6872       /* Optimize expN(1.0) = N.  */
6873       if (real_onep (arg))
6874         {
6875           REAL_VALUE_TYPE cst;
6876
6877           real_convert (&cst, TYPE_MODE (type), value);
6878           return build_real (type, cst);
6879         }
6880
6881       /* Attempt to evaluate expN(integer) at compile-time.  */
6882       if (flag_unsafe_math_optimizations
6883           && TREE_CODE (arg) == REAL_CST
6884           && ! TREE_CONSTANT_OVERFLOW (arg))
6885         {
6886           REAL_VALUE_TYPE cint;
6887           REAL_VALUE_TYPE c;
6888           HOST_WIDE_INT n;
6889
6890           c = TREE_REAL_CST (arg);
6891           n = real_to_integer (&c);
6892           real_from_integer (&cint, VOIDmode, n,
6893                              n < 0 ? -1 : 0, 0);
6894           if (real_identical (&c, &cint))
6895             {
6896               REAL_VALUE_TYPE x;
6897
6898               real_powi (&x, TYPE_MODE (type), value, n);
6899               return build_real (type, x);
6900             }
6901         }
6902
6903       /* Optimize expN(logN(x)) = x.  */
6904       if (flag_unsafe_math_optimizations)
6905         {
6906           const enum built_in_function fcode = builtin_mathfn_code (arg);
6907
6908           if ((value == &dconste
6909                && (fcode == BUILT_IN_LOG
6910                    || fcode == BUILT_IN_LOGF
6911                    || fcode == BUILT_IN_LOGL))
6912               || (value == &dconst2
6913                   && (fcode == BUILT_IN_LOG2
6914                       || fcode == BUILT_IN_LOG2F
6915                       || fcode == BUILT_IN_LOG2L))
6916               || (value == &dconst10
6917                   && (fcode == BUILT_IN_LOG10
6918                       || fcode == BUILT_IN_LOG10F
6919                       || fcode == BUILT_IN_LOG10L)))
6920             return fold_convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6921         }
6922     }
6923
6924   return 0;
6925 }
6926
6927 /* Fold function call to builtin memcpy.  Return
6928    NULL_TREE if no simplification can be made.  */
6929
6930 static tree
6931 fold_builtin_memcpy (tree exp)
6932 {
6933   tree arglist = TREE_OPERAND (exp, 1);
6934   tree dest, src, len;
6935
6936   if (!validate_arglist (arglist,
6937                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6938     return 0;
6939
6940   dest = TREE_VALUE (arglist);
6941   src = TREE_VALUE (TREE_CHAIN (arglist));
6942   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6943
6944   /* If the LEN parameter is zero, return DEST.  */
6945   if (integer_zerop (len))
6946     return omit_one_operand (TREE_TYPE (exp), dest, src);
6947
6948   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6949   if (operand_equal_p (src, dest, 0))
6950     return omit_one_operand (TREE_TYPE (exp), dest, len);
6951
6952   return 0;
6953 }
6954
6955 /* Fold function call to builtin mempcpy.  Return
6956    NULL_TREE if no simplification can be made.  */
6957
6958 static tree
6959 fold_builtin_mempcpy (tree arglist, tree type, int endp)
6960 {
6961   if (validate_arglist (arglist,
6962                         POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6963     {
6964       tree dest = TREE_VALUE (arglist);
6965       tree src = TREE_VALUE (TREE_CHAIN (arglist));
6966       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6967
6968       /* If the LEN parameter is zero, return DEST.  */
6969       if (integer_zerop (len))
6970         return omit_one_operand (type, dest, src);
6971
6972       /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6973       if (operand_equal_p (src, dest, 0))
6974         {
6975           if (endp == 0)
6976             return omit_one_operand (type, dest, len);
6977
6978           if (endp == 2)
6979             len = fold (build2 (MINUS_EXPR, TREE_TYPE (len), len,
6980                                 ssize_int (1)));
6981       
6982           len = fold_convert (TREE_TYPE (dest), len);
6983           len = fold (build2 (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6984           return fold_convert (type, len);
6985         }
6986     }
6987   return 0;
6988 }
6989
6990 /* Fold function call to builtin memmove.  Return
6991    NULL_TREE if no simplification can be made.  */
6992
6993 static tree
6994 fold_builtin_memmove (tree arglist, tree type)
6995 {
6996   tree dest, src, len;
6997
6998   if (!validate_arglist (arglist,
6999                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7000     return 0;
7001
7002   dest = TREE_VALUE (arglist);
7003   src = TREE_VALUE (TREE_CHAIN (arglist));
7004   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7005
7006   /* If the LEN parameter is zero, return DEST.  */
7007   if (integer_zerop (len))
7008     return omit_one_operand (type, dest, src);
7009
7010   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7011   if (operand_equal_p (src, dest, 0))
7012     return omit_one_operand (type, dest, len);
7013
7014   return 0;
7015 }
7016
7017 /* Fold function call to builtin strcpy.  If LEN is not NULL, it represents
7018    the length of the string to be copied.  Return NULL_TREE if no
7019    simplification can be made.  */
7020
7021 tree
7022 fold_builtin_strcpy (tree exp, tree len)
7023 {
7024   tree arglist = TREE_OPERAND (exp, 1);
7025   tree dest, src, fn;
7026
7027   if (!validate_arglist (arglist,
7028                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7029     return 0;
7030
7031   dest = TREE_VALUE (arglist);
7032   src = TREE_VALUE (TREE_CHAIN (arglist));
7033
7034   /* If SRC and DEST are the same (and not volatile), return DEST.  */
7035   if (operand_equal_p (src, dest, 0))
7036     return fold_convert (TREE_TYPE (exp), dest);
7037
7038   if (optimize_size)
7039     return 0;
7040
7041   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7042   if (!fn)
7043     return 0;
7044
7045   if (!len)
7046     {
7047       len = c_strlen (src, 1);
7048       if (! len || TREE_SIDE_EFFECTS (len))
7049         return 0;
7050     }
7051
7052   len = size_binop (PLUS_EXPR, len, ssize_int (1));
7053   arglist = build_tree_list (NULL_TREE, len);
7054   arglist = tree_cons (NULL_TREE, src, arglist);
7055   arglist = tree_cons (NULL_TREE, dest, arglist);
7056   return fold_convert (TREE_TYPE (exp),
7057                        build_function_call_expr (fn, arglist));
7058 }
7059
7060 /* Fold function call to builtin strncpy.  If SLEN is not NULL, it represents
7061    the length of the source string.  Return NULL_TREE if no simplification
7062    can be made.  */
7063
7064 tree
7065 fold_builtin_strncpy (tree exp, tree slen)
7066 {
7067   tree arglist = TREE_OPERAND (exp, 1);
7068   tree dest, src, len, fn;
7069
7070   if (!validate_arglist (arglist,
7071                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7072     return 0;
7073
7074   dest = TREE_VALUE (arglist);
7075   src = TREE_VALUE (TREE_CHAIN (arglist));
7076   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7077
7078   /* If the LEN parameter is zero, return DEST.  */
7079   if (integer_zerop (len))
7080     return omit_one_operand (TREE_TYPE (exp), dest, src);
7081
7082   /* We can't compare slen with len as constants below if len is not a
7083      constant.  */
7084   if (len == 0 || TREE_CODE (len) != INTEGER_CST)
7085     return 0;
7086
7087   if (!slen)
7088     slen = c_strlen (src, 1);
7089
7090   /* Now, we must be passed a constant src ptr parameter.  */
7091   if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
7092     return 0;
7093
7094   slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
7095
7096   /* We do not support simplification of this case, though we do
7097      support it when expanding trees into RTL.  */
7098   /* FIXME: generate a call to __builtin_memset.  */
7099   if (tree_int_cst_lt (slen, len))
7100     return 0;
7101
7102   /* OK transform into builtin memcpy.  */
7103   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
7104   if (!fn)
7105     return 0;
7106   return fold_convert (TREE_TYPE (exp),
7107                        build_function_call_expr (fn, arglist));
7108 }
7109
7110 /* Fold function call to builtin memcmp.  Return
7111    NULL_TREE if no simplification can be made.  */
7112
7113 static tree
7114 fold_builtin_memcmp (tree arglist)
7115 {
7116   tree arg1, arg2, len;
7117   const char *p1, *p2;
7118
7119   if (!validate_arglist (arglist,
7120                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7121     return 0;
7122
7123   arg1 = TREE_VALUE (arglist);
7124   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7125   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7126
7127   /* If the LEN parameter is zero, return zero.  */
7128   if (integer_zerop (len))
7129     return omit_two_operands (integer_type_node, integer_zero_node,
7130                               arg1, arg2);
7131
7132   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7133   if (operand_equal_p (arg1, arg2, 0))
7134     return omit_one_operand (integer_type_node, integer_zero_node, len);
7135
7136   p1 = c_getstr (arg1);
7137   p2 = c_getstr (arg2);
7138
7139   /* If all arguments are constant, and the value of len is not greater
7140      than the lengths of arg1 and arg2, evaluate at compile-time.  */
7141   if (host_integerp (len, 1) && p1 && p2
7142       && compare_tree_int (len, strlen (p1) + 1) <= 0
7143       && compare_tree_int (len, strlen (p2) + 1) <= 0)
7144     {
7145       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
7146
7147       if (r > 0)
7148         return integer_one_node;
7149       else if (r < 0)
7150         return integer_minus_one_node;
7151       else
7152         return integer_zero_node;
7153     }
7154
7155   /* If len parameter is one, return an expression corresponding to
7156      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7157   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7158     {
7159       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7160       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7161       tree ind1 = fold_convert (integer_type_node,
7162                                 build1 (INDIRECT_REF, cst_uchar_node,
7163                                         fold_convert (cst_uchar_ptr_node,
7164                                                       arg1)));
7165       tree ind2 = fold_convert (integer_type_node,
7166                                 build1 (INDIRECT_REF, cst_uchar_node,
7167                                         fold_convert (cst_uchar_ptr_node,
7168                                                       arg2)));
7169       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7170     }
7171
7172   return 0;
7173 }
7174
7175 /* Fold function call to builtin strcmp.  Return
7176    NULL_TREE if no simplification can be made.  */
7177
7178 static tree
7179 fold_builtin_strcmp (tree arglist)
7180 {
7181   tree arg1, arg2;
7182   const char *p1, *p2;
7183
7184   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
7185     return 0;
7186
7187   arg1 = TREE_VALUE (arglist);
7188   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7189
7190   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7191   if (operand_equal_p (arg1, arg2, 0))
7192     return integer_zero_node;
7193
7194   p1 = c_getstr (arg1);
7195   p2 = c_getstr (arg2);
7196
7197   if (p1 && p2)
7198     {
7199       const int i = strcmp (p1, p2);
7200       if (i < 0)
7201         return integer_minus_one_node;
7202       else if (i > 0)
7203         return integer_one_node;
7204       else
7205         return integer_zero_node;
7206     }
7207
7208   /* If the second arg is "", return *(const unsigned char*)arg1.  */
7209   if (p2 && *p2 == '\0')
7210     {
7211       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7212       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7213       return fold_convert (integer_type_node,
7214                            build1 (INDIRECT_REF, cst_uchar_node,
7215                                    fold_convert (cst_uchar_ptr_node,
7216                                                  arg1)));
7217     }
7218
7219   /* If the first arg is "", return -*(const unsigned char*)arg2.  */
7220   if (p1 && *p1 == '\0')
7221     {
7222       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7223       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7224       tree temp = fold_convert (integer_type_node,
7225                                 build1 (INDIRECT_REF, cst_uchar_node,
7226                                         fold_convert (cst_uchar_ptr_node,
7227                                                       arg2)));
7228       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7229     }
7230
7231   return 0;
7232 }
7233
7234 /* Fold function call to builtin strncmp.  Return
7235    NULL_TREE if no simplification can be made.  */
7236
7237 static tree
7238 fold_builtin_strncmp (tree arglist)
7239 {
7240   tree arg1, arg2, len;
7241   const char *p1, *p2;
7242
7243   if (!validate_arglist (arglist,
7244                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
7245     return 0;
7246
7247   arg1 = TREE_VALUE (arglist);
7248   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7249   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7250
7251   /* If the LEN parameter is zero, return zero.  */
7252   if (integer_zerop (len))
7253     return omit_two_operands (integer_type_node, integer_zero_node,
7254                               arg1, arg2);
7255
7256   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
7257   if (operand_equal_p (arg1, arg2, 0))
7258     return omit_one_operand (integer_type_node, integer_zero_node, len);
7259
7260   p1 = c_getstr (arg1);
7261   p2 = c_getstr (arg2);
7262
7263   if (host_integerp (len, 1) && p1 && p2)
7264     {
7265       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
7266       if (i > 0)
7267         return integer_one_node;
7268       else if (i < 0)
7269         return integer_minus_one_node;
7270       else
7271         return integer_zero_node;
7272     }
7273
7274   /* If the second arg is "", and the length is greater than zero,
7275      return *(const unsigned char*)arg1.  */
7276   if (p2 && *p2 == '\0'
7277       && TREE_CODE (len) == INTEGER_CST
7278       && tree_int_cst_sgn (len) == 1)
7279     {
7280       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7281       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7282       return fold_convert (integer_type_node,
7283                            build1 (INDIRECT_REF, cst_uchar_node,
7284                                    fold_convert (cst_uchar_ptr_node,
7285                                                  arg1)));
7286     }
7287
7288   /* If the first arg is "", and the length is greater than zero,
7289      return -*(const unsigned char*)arg2.  */
7290   if (p1 && *p1 == '\0'
7291       && TREE_CODE (len) == INTEGER_CST
7292       && tree_int_cst_sgn (len) == 1)
7293     {
7294       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7295       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7296       tree temp = fold_convert (integer_type_node,
7297                                 build1 (INDIRECT_REF, cst_uchar_node,
7298                                         fold_convert (cst_uchar_ptr_node,
7299                                                       arg2)));
7300       return fold (build1 (NEGATE_EXPR, integer_type_node, temp));
7301     }
7302
7303   /* If len parameter is one, return an expression corresponding to
7304      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
7305   if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
7306     {
7307       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
7308       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
7309       tree ind1 = fold_convert (integer_type_node,
7310                                 build1 (INDIRECT_REF, cst_uchar_node,
7311                                         fold_convert (cst_uchar_ptr_node,
7312                                                       arg1)));
7313       tree ind2 = fold_convert (integer_type_node,
7314                                 build1 (INDIRECT_REF, cst_uchar_node,
7315                                         fold_convert (cst_uchar_ptr_node,
7316                                                       arg2)));
7317       return fold (build2 (MINUS_EXPR, integer_type_node, ind1, ind2));
7318     }
7319
7320   return 0;
7321 }
7322
7323 /* Fold function call to builtin signbit, signbitf or signbitl.  Return
7324    NULL_TREE if no simplification can be made.  */
7325
7326 static tree
7327 fold_builtin_signbit (tree exp)
7328 {
7329   tree arglist = TREE_OPERAND (exp, 1);
7330   tree arg, temp;
7331
7332   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7333     return NULL_TREE;
7334
7335   arg = TREE_VALUE (arglist);
7336
7337   /* If ARG is a compile-time constant, determine the result.  */
7338   if (TREE_CODE (arg) == REAL_CST
7339       && !TREE_CONSTANT_OVERFLOW (arg))
7340     {
7341       REAL_VALUE_TYPE c;
7342
7343       c = TREE_REAL_CST (arg);
7344       temp = REAL_VALUE_NEGATIVE (c) ? integer_one_node : integer_zero_node;
7345       return fold_convert (TREE_TYPE (exp), temp);
7346     }
7347
7348   /* If ARG is non-negative, the result is always zero.  */
7349   if (tree_expr_nonnegative_p (arg))
7350     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg);
7351
7352   /* If ARG's format doesn't have signed zeros, return "arg < 0.0".  */
7353   if (!HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg))))
7354     return fold (build2 (LT_EXPR, TREE_TYPE (exp), arg,
7355                          build_real (TREE_TYPE (arg), dconst0)));
7356
7357   return NULL_TREE;
7358 }
7359
7360 /* Fold function call to builtin copysign, copysignf or copysignl.
7361    Return NULL_TREE if no simplification can be made.  */
7362
7363 static tree
7364 fold_builtin_copysign (tree arglist, tree type)
7365 {
7366   tree arg1, arg2;
7367
7368   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7369     return NULL_TREE;
7370
7371   arg1 = TREE_VALUE (arglist);
7372   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
7373
7374   /* copysign(X,X) is X.  */
7375   if (operand_equal_p (arg1, arg2, 0))
7376     return fold_convert (type, arg1);
7377
7378   /* If ARG1 and ARG2 are compile-time constants, determine the result.  */
7379   if (TREE_CODE (arg1) == REAL_CST
7380       && TREE_CODE (arg2) == REAL_CST
7381       && !TREE_CONSTANT_OVERFLOW (arg1)
7382       && !TREE_CONSTANT_OVERFLOW (arg2))
7383     {
7384       REAL_VALUE_TYPE c1, c2;
7385
7386       c1 = TREE_REAL_CST (arg1);
7387       c2 = TREE_REAL_CST (arg2);
7388       real_copysign (&c1, &c2);
7389       return build_real (type, c1);
7390       c1.sign = c2.sign;
7391     }
7392
7393   /* copysign(X, Y) is fabs(X) when Y is always non-negative.
7394      Remember to evaluate Y for side-effects.  */
7395   if (tree_expr_nonnegative_p (arg2))
7396     return omit_one_operand (type,
7397                              fold (build1 (ABS_EXPR, type, arg1)),
7398                              arg2);
7399
7400   return NULL_TREE;
7401 }
7402
7403 /* Fold a call to builtin isascii.  */
7404
7405 static tree
7406 fold_builtin_isascii (tree arglist)
7407 {
7408   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7409     return 0;
7410   else
7411     {
7412       /* Transform isascii(c) -> ((c & ~0x7f) == 0).  */
7413       tree arg = TREE_VALUE (arglist);
7414
7415       arg = build2 (BIT_AND_EXPR, integer_type_node, arg,
7416                     build_int_cst (NULL_TREE,
7417                                    ~ (unsigned HOST_WIDE_INT) 0x7f));
7418       arg = fold (build2 (EQ_EXPR, integer_type_node,
7419                           arg, integer_zero_node));
7420
7421       if (in_gimple_form && !TREE_CONSTANT (arg))
7422         return NULL_TREE;
7423       else
7424         return arg;
7425     }
7426 }
7427
7428 /* Fold a call to builtin toascii.  */
7429
7430 static tree
7431 fold_builtin_toascii (tree arglist)
7432 {
7433   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7434     return 0;
7435   else
7436     {
7437       /* Transform toascii(c) -> (c & 0x7f).  */
7438       tree arg = TREE_VALUE (arglist);
7439
7440       return fold (build2 (BIT_AND_EXPR, integer_type_node, arg,
7441                            build_int_cst (NULL_TREE, 0x7f)));
7442     }
7443 }
7444
7445 /* Fold a call to builtin isdigit.  */
7446
7447 static tree
7448 fold_builtin_isdigit (tree arglist)
7449 {
7450   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7451     return 0;
7452   else
7453     {
7454       /* Transform isdigit(c) -> (unsigned)(c) - '0' <= 9.  */
7455       /* According to the C standard, isdigit is unaffected by locale.  */
7456       tree arg = TREE_VALUE (arglist);
7457       arg = fold_convert (unsigned_type_node, arg);
7458       arg = build2 (MINUS_EXPR, unsigned_type_node, arg,
7459                     build_int_cst (unsigned_type_node, TARGET_DIGIT0));
7460       arg = build2 (LE_EXPR, integer_type_node, arg,
7461                     build_int_cst (unsigned_type_node, 9));
7462       arg = fold (arg);
7463       if (in_gimple_form && !TREE_CONSTANT (arg))
7464         return NULL_TREE;
7465       else
7466         return arg;
7467     }
7468 }
7469
7470 /* Fold a call to fabs, fabsf or fabsl.  */
7471
7472 static tree
7473 fold_builtin_fabs (tree arglist, tree type)
7474 {
7475   tree arg;
7476
7477   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7478     return 0;
7479
7480   arg = TREE_VALUE (arglist);
7481   if (TREE_CODE (arg) == REAL_CST)
7482     return fold_abs_const (arg, type);
7483   return fold (build1 (ABS_EXPR, type, arg));
7484 }
7485
7486 /* Fold a call to abs, labs, llabs or imaxabs.  */
7487
7488 static tree
7489 fold_builtin_abs (tree arglist, tree type)
7490 {
7491   tree arg;
7492
7493   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
7494     return 0;
7495
7496   arg = TREE_VALUE (arglist);
7497   if (TREE_CODE (arg) == INTEGER_CST)
7498     return fold_abs_const (arg, type);
7499   return fold (build1 (ABS_EXPR, type, arg));
7500 }
7501
7502 /* Fold a call to __builtin_isnan(), __builtin_isinf, __builtin_finite.
7503    EXP is the CALL_EXPR for the call.  */
7504
7505 static tree
7506 fold_builtin_classify (tree exp, int builtin_index)
7507 {
7508   tree fndecl = get_callee_fndecl (exp);
7509   tree arglist = TREE_OPERAND (exp, 1);
7510   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7511   tree arg;
7512   REAL_VALUE_TYPE r;
7513
7514   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
7515     {
7516       /* Check that we have exactly one argument.  */
7517       if (arglist == 0)
7518         {
7519           error ("too few arguments to function %qs",
7520                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7521           return error_mark_node;
7522         }
7523       else if (TREE_CHAIN (arglist) != 0)
7524         {
7525           error ("too many arguments to function %qs",
7526                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7527           return error_mark_node;
7528         }
7529       else
7530         {
7531           error ("non-floating-point argument to function %qs",
7532                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7533           return error_mark_node;
7534         }
7535     }
7536
7537   arg = TREE_VALUE (arglist);
7538   switch (builtin_index)
7539     {
7540     case BUILT_IN_ISINF:
7541       if (!MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7542         return omit_one_operand (type, integer_zero_node, arg);
7543
7544       if (TREE_CODE (arg) == REAL_CST)
7545         {
7546           r = TREE_REAL_CST (arg);
7547           if (real_isinf (&r))
7548             return real_compare (GT_EXPR, &r, &dconst0)
7549                    ? integer_one_node : integer_minus_one_node;
7550           else
7551             return integer_zero_node;
7552         }
7553
7554       return NULL_TREE;
7555
7556     case BUILT_IN_FINITE:
7557       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg)))
7558           && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (arg))))
7559         return omit_one_operand (type, integer_zero_node, arg);
7560
7561       if (TREE_CODE (arg) == REAL_CST)
7562         {
7563           r = TREE_REAL_CST (arg);
7564           return real_isinf (&r) || real_isnan (&r)
7565                  ? integer_zero_node : integer_one_node;
7566         }
7567
7568       return NULL_TREE;
7569
7570     case BUILT_IN_ISNAN:
7571       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg))))
7572         return omit_one_operand (type, integer_zero_node, arg);
7573
7574       if (TREE_CODE (arg) == REAL_CST)
7575         {
7576           r = TREE_REAL_CST (arg);
7577           return real_isnan (&r) ? integer_one_node : integer_zero_node;
7578         }
7579
7580       arg = builtin_save_expr (arg);
7581       return fold (build2 (UNORDERED_EXPR, type, arg, arg));
7582
7583     default:
7584       gcc_unreachable ();
7585     }
7586 }
7587
7588 /* Fold a call to an unordered comparison function such as
7589    __builtin_isgreater().  EXP is the CALL_EXPR for the call.
7590    UNORDERED_CODE and ORDERED_CODE are comparison codes that give
7591    the opposite of the desired result.  UNORDERED_CODE is used
7592    for modes that can hold NaNs and ORDERED_CODE is used for
7593    the rest.  */
7594
7595 static tree
7596 fold_builtin_unordered_cmp (tree exp,
7597                             enum tree_code unordered_code,
7598                             enum tree_code ordered_code)
7599 {
7600   tree fndecl = get_callee_fndecl (exp);
7601   tree arglist = TREE_OPERAND (exp, 1);
7602   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7603   enum tree_code code;
7604   tree arg0, arg1;
7605
7606   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
7607     {
7608       enum tree_code code0, code1;
7609       tree type0, type1;
7610       tree cmp_type = 0;
7611
7612       /* Check that we have exactly two arguments.  */
7613       if (arglist == 0 || TREE_CHAIN (arglist) == 0)
7614         {
7615           error ("too few arguments to function %qs",
7616                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7617           return error_mark_node;
7618         }
7619       else if (TREE_CHAIN (TREE_CHAIN (arglist)) != 0)
7620         {
7621           error ("too many arguments to function %qs",
7622                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7623           return error_mark_node;
7624         }
7625
7626       arg0 = TREE_VALUE (arglist);
7627       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7628
7629       type0 = TREE_TYPE (arg0);
7630       type1 = TREE_TYPE (arg1);
7631
7632       code0 = TREE_CODE (type0);
7633       code1 = TREE_CODE (type1);
7634
7635       if (code0 == REAL_TYPE && code1 == REAL_TYPE)
7636         /* Choose the wider of two real types.  */
7637         cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
7638                    ? type0 : type1;
7639       else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
7640         cmp_type = type0;
7641       else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
7642         cmp_type = type1;
7643       else
7644         {
7645           error ("non-floating-point argument to function %qs",
7646                  IDENTIFIER_POINTER (DECL_NAME (fndecl)));
7647           return error_mark_node;
7648         }
7649
7650       arg0 = fold_convert (cmp_type, arg0);
7651       arg1 = fold_convert (cmp_type, arg1);
7652     }
7653   else
7654     {
7655       arg0 = TREE_VALUE (arglist);
7656       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7657     }
7658
7659   if (unordered_code == UNORDERED_EXPR)
7660     {
7661       if (!MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))))
7662         return omit_two_operands (type, integer_zero_node, arg0, arg1);
7663       return fold (build2 (UNORDERED_EXPR, type, arg0, arg1));
7664     }
7665
7666   code = MODE_HAS_NANS (TYPE_MODE (TREE_TYPE (arg0))) ? unordered_code
7667                                                       : ordered_code;
7668   return fold (build1 (TRUTH_NOT_EXPR, type,
7669                        fold (build2 (code, type, arg0, arg1))));
7670 }
7671
7672 /* Used by constant folding to simplify calls to builtin functions.  EXP is
7673    the CALL_EXPR of a call to a builtin function.  IGNORE is true if the
7674    result of the function call is ignored.  This function returns NULL_TREE
7675    if no simplification was possible.  */
7676
7677 static tree
7678 fold_builtin_1 (tree exp, bool ignore)
7679 {
7680   tree fndecl = get_callee_fndecl (exp);
7681   tree arglist = TREE_OPERAND (exp, 1);
7682   tree type = TREE_TYPE (TREE_TYPE (fndecl));
7683
7684   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
7685     return targetm.fold_builtin (exp, ignore);
7686
7687   switch (DECL_FUNCTION_CODE (fndecl))
7688     {
7689     case BUILT_IN_FPUTS:
7690       return fold_builtin_fputs (arglist, ignore, false, NULL_TREE);
7691
7692     case BUILT_IN_FPUTS_UNLOCKED:
7693       return fold_builtin_fputs (arglist, ignore, true, NULL_TREE);
7694
7695     case BUILT_IN_STRSTR:
7696       return fold_builtin_strstr (arglist);
7697
7698     case BUILT_IN_STRCAT:
7699       return fold_builtin_strcat (arglist);
7700
7701     case BUILT_IN_STRNCAT:
7702       return fold_builtin_strncat (arglist);
7703
7704     case BUILT_IN_STRSPN:
7705       return fold_builtin_strspn (arglist);
7706
7707     case BUILT_IN_STRCSPN:
7708       return fold_builtin_strcspn (arglist);
7709
7710     case BUILT_IN_STRCHR:
7711     case BUILT_IN_INDEX:
7712       return fold_builtin_strchr (arglist);
7713
7714     case BUILT_IN_STRRCHR:
7715     case BUILT_IN_RINDEX:
7716       return fold_builtin_strrchr (arglist);
7717
7718     case BUILT_IN_STRCPY:
7719       return fold_builtin_strcpy (exp, NULL_TREE);
7720
7721     case BUILT_IN_STRNCPY:
7722       return fold_builtin_strncpy (exp, NULL_TREE);
7723
7724     case BUILT_IN_STRCMP:
7725       return fold_builtin_strcmp (arglist);
7726
7727     case BUILT_IN_STRNCMP:
7728       return fold_builtin_strncmp (arglist);
7729
7730     case BUILT_IN_STRPBRK:
7731       return fold_builtin_strpbrk (arglist);
7732
7733     case BUILT_IN_BCMP:
7734     case BUILT_IN_MEMCMP:
7735       return fold_builtin_memcmp (arglist);
7736
7737     case BUILT_IN_SPRINTF:
7738       return fold_builtin_sprintf (arglist, ignore);
7739
7740     case BUILT_IN_CONSTANT_P:
7741       {
7742         tree val;
7743
7744         val = fold_builtin_constant_p (arglist);
7745         /* Gimplification will pull the CALL_EXPR for the builtin out of
7746            an if condition.  When not optimizing, we'll not CSE it back.
7747            To avoid link error types of regressions, return false now.  */
7748         if (!val && !optimize)
7749           val = integer_zero_node;
7750
7751         return val;
7752       }
7753
7754     case BUILT_IN_EXPECT:
7755       return fold_builtin_expect (arglist);
7756
7757     case BUILT_IN_CLASSIFY_TYPE:
7758       return fold_builtin_classify_type (arglist);
7759
7760     case BUILT_IN_STRLEN:
7761       return fold_builtin_strlen (arglist);
7762
7763     case BUILT_IN_FABS:
7764     case BUILT_IN_FABSF:
7765     case BUILT_IN_FABSL:
7766       return fold_builtin_fabs (arglist, type);
7767
7768     case BUILT_IN_ABS:
7769     case BUILT_IN_LABS:
7770     case BUILT_IN_LLABS:
7771     case BUILT_IN_IMAXABS:
7772       return fold_builtin_abs (arglist, type);
7773
7774     case BUILT_IN_CONJ:
7775     case BUILT_IN_CONJF:
7776     case BUILT_IN_CONJL:
7777       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7778         return fold (build1 (CONJ_EXPR, type, TREE_VALUE (arglist)));
7779       break;
7780
7781     case BUILT_IN_CREAL:
7782     case BUILT_IN_CREALF:
7783     case BUILT_IN_CREALL:
7784       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7785         return non_lvalue (fold (build1 (REALPART_EXPR, type,
7786                                          TREE_VALUE (arglist))));
7787       break;
7788
7789     case BUILT_IN_CIMAG:
7790     case BUILT_IN_CIMAGF:
7791     case BUILT_IN_CIMAGL:
7792       if (validate_arglist (arglist, COMPLEX_TYPE, VOID_TYPE))
7793         return non_lvalue (fold (build1 (IMAGPART_EXPR, type,
7794                                          TREE_VALUE (arglist))));
7795       break;
7796
7797     case BUILT_IN_CABS:
7798     case BUILT_IN_CABSF:
7799     case BUILT_IN_CABSL:
7800       return fold_builtin_cabs (arglist, type);
7801
7802     case BUILT_IN_SQRT:
7803     case BUILT_IN_SQRTF:
7804     case BUILT_IN_SQRTL:
7805       return fold_builtin_sqrt (arglist, type);
7806
7807     case BUILT_IN_CBRT:
7808     case BUILT_IN_CBRTF:
7809     case BUILT_IN_CBRTL:
7810       return fold_builtin_cbrt (arglist, type);
7811
7812     case BUILT_IN_SIN:
7813     case BUILT_IN_SINF:
7814     case BUILT_IN_SINL:
7815       return fold_builtin_sin (arglist);
7816
7817     case BUILT_IN_COS:
7818     case BUILT_IN_COSF:
7819     case BUILT_IN_COSL:
7820       return fold_builtin_cos (arglist, type, fndecl);
7821
7822     case BUILT_IN_EXP:
7823     case BUILT_IN_EXPF:
7824     case BUILT_IN_EXPL:
7825       return fold_builtin_exponent (exp, &dconste);
7826
7827     case BUILT_IN_EXP2:
7828     case BUILT_IN_EXP2F:
7829     case BUILT_IN_EXP2L:
7830       return fold_builtin_exponent (exp, &dconst2);
7831
7832     case BUILT_IN_EXP10:
7833     case BUILT_IN_EXP10F:
7834     case BUILT_IN_EXP10L:
7835     case BUILT_IN_POW10:
7836     case BUILT_IN_POW10F:
7837     case BUILT_IN_POW10L:
7838       return fold_builtin_exponent (exp, &dconst10);
7839
7840     case BUILT_IN_LOG:
7841     case BUILT_IN_LOGF:
7842     case BUILT_IN_LOGL:
7843       return fold_builtin_logarithm (exp, &dconste);
7844
7845     case BUILT_IN_LOG2:
7846     case BUILT_IN_LOG2F:
7847     case BUILT_IN_LOG2L:
7848       return fold_builtin_logarithm (exp, &dconst2);
7849
7850     case BUILT_IN_LOG10:
7851     case BUILT_IN_LOG10F:
7852     case BUILT_IN_LOG10L:
7853       return fold_builtin_logarithm (exp, &dconst10);
7854
7855     case BUILT_IN_TAN:
7856     case BUILT_IN_TANF:
7857     case BUILT_IN_TANL:
7858       return fold_builtin_tan (arglist);
7859
7860     case BUILT_IN_ATAN:
7861     case BUILT_IN_ATANF:
7862     case BUILT_IN_ATANL:
7863       return fold_builtin_atan (arglist, type);
7864
7865     case BUILT_IN_POW:
7866     case BUILT_IN_POWF:
7867     case BUILT_IN_POWL:
7868       return fold_builtin_pow (fndecl, arglist, type);
7869
7870     case BUILT_IN_INF:
7871     case BUILT_IN_INFF:
7872     case BUILT_IN_INFL:
7873       return fold_builtin_inf (type, true);
7874
7875     case BUILT_IN_HUGE_VAL:
7876     case BUILT_IN_HUGE_VALF:
7877     case BUILT_IN_HUGE_VALL:
7878       return fold_builtin_inf (type, false);
7879
7880     case BUILT_IN_NAN:
7881     case BUILT_IN_NANF:
7882     case BUILT_IN_NANL:
7883       return fold_builtin_nan (arglist, type, true);
7884
7885     case BUILT_IN_NANS:
7886     case BUILT_IN_NANSF:
7887     case BUILT_IN_NANSL:
7888       return fold_builtin_nan (arglist, type, false);
7889
7890     case BUILT_IN_FLOOR:
7891     case BUILT_IN_FLOORF:
7892     case BUILT_IN_FLOORL:
7893       return fold_builtin_floor (exp);
7894
7895     case BUILT_IN_CEIL:
7896     case BUILT_IN_CEILF:
7897     case BUILT_IN_CEILL:
7898       return fold_builtin_ceil (exp);
7899
7900     case BUILT_IN_TRUNC:
7901     case BUILT_IN_TRUNCF:
7902     case BUILT_IN_TRUNCL:
7903       return fold_builtin_trunc (exp);
7904
7905     case BUILT_IN_ROUND:
7906     case BUILT_IN_ROUNDF:
7907     case BUILT_IN_ROUNDL:
7908       return fold_builtin_round (exp);
7909
7910     case BUILT_IN_NEARBYINT:
7911     case BUILT_IN_NEARBYINTF:
7912     case BUILT_IN_NEARBYINTL:
7913     case BUILT_IN_RINT:
7914     case BUILT_IN_RINTF:
7915     case BUILT_IN_RINTL:
7916       return fold_trunc_transparent_mathfn (exp);
7917
7918     case BUILT_IN_LROUND:
7919     case BUILT_IN_LROUNDF:
7920     case BUILT_IN_LROUNDL:
7921     case BUILT_IN_LLROUND:
7922     case BUILT_IN_LLROUNDF:
7923     case BUILT_IN_LLROUNDL:
7924       return fold_builtin_lround (exp);
7925
7926     case BUILT_IN_LRINT:
7927     case BUILT_IN_LRINTF:
7928     case BUILT_IN_LRINTL:
7929     case BUILT_IN_LLRINT:
7930     case BUILT_IN_LLRINTF:
7931     case BUILT_IN_LLRINTL:
7932       return fold_fixed_mathfn (exp);
7933
7934     case BUILT_IN_FFS:
7935     case BUILT_IN_FFSL:
7936     case BUILT_IN_FFSLL:
7937     case BUILT_IN_CLZ:
7938     case BUILT_IN_CLZL:
7939     case BUILT_IN_CLZLL:
7940     case BUILT_IN_CTZ:
7941     case BUILT_IN_CTZL:
7942     case BUILT_IN_CTZLL:
7943     case BUILT_IN_POPCOUNT:
7944     case BUILT_IN_POPCOUNTL:
7945     case BUILT_IN_POPCOUNTLL:
7946     case BUILT_IN_PARITY:
7947     case BUILT_IN_PARITYL:
7948     case BUILT_IN_PARITYLL:
7949       return fold_builtin_bitop (exp);
7950
7951     case BUILT_IN_MEMCPY:
7952       return fold_builtin_memcpy (exp);
7953
7954     case BUILT_IN_MEMPCPY:
7955       return fold_builtin_mempcpy (arglist, type, /*endp=*/1);
7956
7957     case BUILT_IN_MEMMOVE:
7958       return fold_builtin_memmove (arglist, type);
7959
7960     case BUILT_IN_SIGNBIT:
7961     case BUILT_IN_SIGNBITF:
7962     case BUILT_IN_SIGNBITL:
7963       return fold_builtin_signbit (exp);
7964
7965     case BUILT_IN_ISASCII:
7966       return fold_builtin_isascii (arglist);
7967
7968     case BUILT_IN_TOASCII:
7969       return fold_builtin_toascii (arglist);
7970
7971     case BUILT_IN_ISDIGIT:
7972       return fold_builtin_isdigit (arglist);
7973
7974     case BUILT_IN_COPYSIGN:
7975     case BUILT_IN_COPYSIGNF:
7976     case BUILT_IN_COPYSIGNL:
7977       return fold_builtin_copysign (arglist, type);
7978
7979     case BUILT_IN_FINITE:
7980     case BUILT_IN_FINITEF:
7981     case BUILT_IN_FINITEL:
7982       return fold_builtin_classify (exp, BUILT_IN_FINITE);
7983
7984     case BUILT_IN_ISINF:
7985     case BUILT_IN_ISINFF:
7986     case BUILT_IN_ISINFL:
7987       return fold_builtin_classify (exp, BUILT_IN_ISINF);
7988
7989     case BUILT_IN_ISNAN:
7990     case BUILT_IN_ISNANF:
7991     case BUILT_IN_ISNANL:
7992       return fold_builtin_classify (exp, BUILT_IN_ISNAN);
7993
7994     case BUILT_IN_ISGREATER:
7995       return fold_builtin_unordered_cmp (exp, UNLE_EXPR, LE_EXPR);
7996     case BUILT_IN_ISGREATEREQUAL:
7997       return fold_builtin_unordered_cmp (exp, UNLT_EXPR, LT_EXPR);
7998     case BUILT_IN_ISLESS:
7999       return fold_builtin_unordered_cmp (exp, UNGE_EXPR, GE_EXPR);
8000     case BUILT_IN_ISLESSEQUAL:
8001       return fold_builtin_unordered_cmp (exp, UNGT_EXPR, GT_EXPR);
8002     case BUILT_IN_ISLESSGREATER:
8003       return fold_builtin_unordered_cmp (exp, UNEQ_EXPR, EQ_EXPR);
8004     case BUILT_IN_ISUNORDERED:
8005       return fold_builtin_unordered_cmp (exp, UNORDERED_EXPR, NOP_EXPR);
8006
8007       /* We do the folding for va_start in the expander.  */
8008     case BUILT_IN_VA_START:
8009       break;
8010
8011     default:
8012       break;
8013     }
8014
8015   return 0;
8016 }
8017
8018 /* A wrapper function for builtin folding that prevents warnings for
8019    "statement without effect" and the like, caused by removing the
8020    call node earlier than the warning is generated.  */
8021
8022 tree
8023 fold_builtin (tree exp, bool ignore)
8024 {
8025   exp = fold_builtin_1 (exp, ignore);
8026   if (exp)
8027     {
8028       /* ??? Don't clobber shared nodes such as integer_zero_node.  */
8029       if (CONSTANT_CLASS_P (exp))
8030         exp = build1 (NOP_EXPR, TREE_TYPE (exp), exp);
8031       TREE_NO_WARNING (exp) = 1;
8032     }
8033
8034   return exp;
8035 }
8036
8037 /* Conveniently construct a function call expression.  */
8038
8039 tree
8040 build_function_call_expr (tree fn, tree arglist)
8041 {
8042   tree call_expr;
8043
8044   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
8045   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
8046                       call_expr, arglist, NULL_TREE);
8047   return fold (call_expr);
8048 }
8049
8050 /* This function validates the types of a function call argument list
8051    represented as a tree chain of parameters against a specified list
8052    of tree_codes.  If the last specifier is a 0, that represents an
8053    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
8054
8055 static int
8056 validate_arglist (tree arglist, ...)
8057 {
8058   enum tree_code code;
8059   int res = 0;
8060   va_list ap;
8061
8062   va_start (ap, arglist);
8063
8064   do
8065     {
8066       code = va_arg (ap, enum tree_code);
8067       switch (code)
8068         {
8069         case 0:
8070           /* This signifies an ellipses, any further arguments are all ok.  */
8071           res = 1;
8072           goto end;
8073         case VOID_TYPE:
8074           /* This signifies an endlink, if no arguments remain, return
8075              true, otherwise return false.  */
8076           res = arglist == 0;
8077           goto end;
8078         default:
8079           /* If no parameters remain or the parameter's code does not
8080              match the specified code, return false.  Otherwise continue
8081              checking any remaining arguments.  */
8082           if (arglist == 0
8083               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
8084             goto end;
8085           break;
8086         }
8087       arglist = TREE_CHAIN (arglist);
8088     }
8089   while (1);
8090
8091   /* We need gotos here since we can only have one VA_CLOSE in a
8092      function.  */
8093  end: ;
8094   va_end (ap);
8095
8096   return res;
8097 }
8098
8099 /* Default target-specific builtin expander that does nothing.  */
8100
8101 rtx
8102 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
8103                         rtx target ATTRIBUTE_UNUSED,
8104                         rtx subtarget ATTRIBUTE_UNUSED,
8105                         enum machine_mode mode ATTRIBUTE_UNUSED,
8106                         int ignore ATTRIBUTE_UNUSED)
8107 {
8108   return NULL_RTX;
8109 }
8110
8111 /* Returns true is EXP represents data that would potentially reside
8112    in a readonly section.  */
8113
8114 static bool
8115 readonly_data_expr (tree exp)
8116 {
8117   STRIP_NOPS (exp);
8118
8119   if (TREE_CODE (exp) != ADDR_EXPR)
8120     return false;
8121
8122   exp = get_base_address (TREE_OPERAND (exp, 0));
8123   if (!exp)
8124     return false;
8125
8126   /* Make sure we call decl_readonly_section only for trees it
8127      can handle (since it returns true for everything it doesn't
8128      understand).  */
8129   if (TREE_CODE (exp) == STRING_CST
8130       || TREE_CODE (exp) == CONSTRUCTOR
8131       || (TREE_CODE (exp) == VAR_DECL && TREE_STATIC (exp)))
8132     return decl_readonly_section (exp, 0);
8133   else
8134     return false;
8135 }
8136
8137 /* Simplify a call to the strstr builtin.
8138
8139    Return 0 if no simplification was possible, otherwise return the
8140    simplified form of the call as a tree.
8141
8142    The simplified form may be a constant or other expression which
8143    computes the same value, but in a more efficient manner (including
8144    calls to other builtin functions).
8145
8146    The call may contain arguments which need to be evaluated, but
8147    which are not useful to determine the result of the call.  In
8148    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8149    COMPOUND_EXPR will be an argument which must be evaluated.
8150    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8151    COMPOUND_EXPR in the chain will contain the tree for the simplified
8152    form of the builtin function call.  */
8153
8154 static tree
8155 fold_builtin_strstr (tree arglist)
8156 {
8157   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8158     return 0;
8159   else
8160     {
8161       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8162       tree fn;
8163       const char *p1, *p2;
8164
8165       p2 = c_getstr (s2);
8166       if (p2 == NULL)
8167         return 0;
8168
8169       p1 = c_getstr (s1);
8170       if (p1 != NULL)
8171         {
8172           const char *r = strstr (p1, p2);
8173
8174           if (r == NULL)
8175             return build_int_cst (TREE_TYPE (s1), 0);
8176
8177           /* Return an offset into the constant string argument.  */
8178           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8179                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8180         }
8181
8182       if (p2[0] == '\0')
8183         return s1;
8184
8185       if (p2[1] != '\0')
8186         return 0;
8187
8188       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8189       if (!fn)
8190         return 0;
8191
8192       /* New argument list transforming strstr(s1, s2) to
8193          strchr(s1, s2[0]).  */
8194       arglist = build_tree_list (NULL_TREE,
8195                                  build_int_cst (NULL_TREE, p2[0]));
8196       arglist = tree_cons (NULL_TREE, s1, arglist);
8197       return build_function_call_expr (fn, arglist);
8198     }
8199 }
8200
8201 /* Simplify a call to the strchr builtin.
8202
8203    Return 0 if no simplification was possible, otherwise return the
8204    simplified form of the call as a tree.
8205
8206    The simplified form may be a constant or other expression which
8207    computes the same value, but in a more efficient manner (including
8208    calls to other builtin functions).
8209
8210    The call may contain arguments which need to be evaluated, but
8211    which are not useful to determine the result of the call.  In
8212    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8213    COMPOUND_EXPR will be an argument which must be evaluated.
8214    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8215    COMPOUND_EXPR in the chain will contain the tree for the simplified
8216    form of the builtin function call.  */
8217
8218 static tree
8219 fold_builtin_strchr (tree arglist)
8220 {
8221   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8222     return 0;
8223   else
8224     {
8225       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8226       const char *p1;
8227
8228       if (TREE_CODE (s2) != INTEGER_CST)
8229         return 0;
8230
8231       p1 = c_getstr (s1);
8232       if (p1 != NULL)
8233         {
8234           char c;
8235           const char *r;
8236
8237           if (target_char_cast (s2, &c))
8238             return 0;
8239
8240           r = strchr (p1, c);
8241
8242           if (r == NULL)
8243             return build_int_cst (TREE_TYPE (s1), 0);
8244
8245           /* Return an offset into the constant string argument.  */
8246           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8247                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8248         }
8249       return 0;
8250     }
8251 }
8252
8253 /* Simplify a call to the strrchr builtin.
8254
8255    Return 0 if no simplification was possible, otherwise return the
8256    simplified form of the call as a tree.
8257
8258    The simplified form may be a constant or other expression which
8259    computes the same value, but in a more efficient manner (including
8260    calls to other builtin functions).
8261
8262    The call may contain arguments which need to be evaluated, but
8263    which are not useful to determine the result of the call.  In
8264    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8265    COMPOUND_EXPR will be an argument which must be evaluated.
8266    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8267    COMPOUND_EXPR in the chain will contain the tree for the simplified
8268    form of the builtin function call.  */
8269
8270 static tree
8271 fold_builtin_strrchr (tree arglist)
8272 {
8273   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8274     return 0;
8275   else
8276     {
8277       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8278       tree fn;
8279       const char *p1;
8280
8281       if (TREE_CODE (s2) != INTEGER_CST)
8282         return 0;
8283
8284       p1 = c_getstr (s1);
8285       if (p1 != NULL)
8286         {
8287           char c;
8288           const char *r;
8289
8290           if (target_char_cast (s2, &c))
8291             return 0;
8292
8293           r = strrchr (p1, c);
8294
8295           if (r == NULL)
8296             return build_int_cst (TREE_TYPE (s1), 0);
8297
8298           /* Return an offset into the constant string argument.  */
8299           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8300                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8301         }
8302
8303       if (! integer_zerop (s2))
8304         return 0;
8305
8306       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8307       if (!fn)
8308         return 0;
8309
8310       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
8311       return build_function_call_expr (fn, arglist);
8312     }
8313 }
8314
8315 /* Simplify a call to the strpbrk builtin.
8316
8317    Return 0 if no simplification was possible, otherwise return the
8318    simplified form of the call as a tree.
8319
8320    The simplified form may be a constant or other expression which
8321    computes the same value, but in a more efficient manner (including
8322    calls to other builtin functions).
8323
8324    The call may contain arguments which need to be evaluated, but
8325    which are not useful to determine the result of the call.  In
8326    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8327    COMPOUND_EXPR will be an argument which must be evaluated.
8328    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8329    COMPOUND_EXPR in the chain will contain the tree for the simplified
8330    form of the builtin function call.  */
8331
8332 static tree
8333 fold_builtin_strpbrk (tree arglist)
8334 {
8335   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8336     return 0;
8337   else
8338     {
8339       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8340       tree fn;
8341       const char *p1, *p2;
8342
8343       p2 = c_getstr (s2);
8344       if (p2 == NULL)
8345         return 0;
8346
8347       p1 = c_getstr (s1);
8348       if (p1 != NULL)
8349         {
8350           const char *r = strpbrk (p1, p2);
8351
8352           if (r == NULL)
8353             return build_int_cst (TREE_TYPE (s1), 0);
8354
8355           /* Return an offset into the constant string argument.  */
8356           return fold (build2 (PLUS_EXPR, TREE_TYPE (s1),
8357                                s1, build_int_cst (TREE_TYPE (s1), r - p1)));
8358         }
8359
8360       if (p2[0] == '\0')
8361         /* strpbrk(x, "") == NULL.
8362            Evaluate and ignore s1 in case it had side-effects.  */
8363         return omit_one_operand (TREE_TYPE (s1), integer_zero_node, s1);
8364
8365       if (p2[1] != '\0')
8366         return 0;  /* Really call strpbrk.  */
8367
8368       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
8369       if (!fn)
8370         return 0;
8371
8372       /* New argument list transforming strpbrk(s1, s2) to
8373          strchr(s1, s2[0]).  */
8374       arglist = build_tree_list (NULL_TREE,
8375                                  build_int_cst (NULL_TREE, p2[0]));
8376       arglist = tree_cons (NULL_TREE, s1, arglist);
8377       return build_function_call_expr (fn, arglist);
8378     }
8379 }
8380
8381 /* Simplify a call to the strcat builtin.
8382
8383    Return 0 if no simplification was possible, otherwise return the
8384    simplified form of the call as a tree.
8385
8386    The simplified form may be a constant or other expression which
8387    computes the same value, but in a more efficient manner (including
8388    calls to other builtin functions).
8389
8390    The call may contain arguments which need to be evaluated, but
8391    which are not useful to determine the result of the call.  In
8392    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8393    COMPOUND_EXPR will be an argument which must be evaluated.
8394    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8395    COMPOUND_EXPR in the chain will contain the tree for the simplified
8396    form of the builtin function call.  */
8397
8398 static tree
8399 fold_builtin_strcat (tree arglist)
8400 {
8401   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8402     return 0;
8403   else
8404     {
8405       tree dst = TREE_VALUE (arglist),
8406         src = TREE_VALUE (TREE_CHAIN (arglist));
8407       const char *p = c_getstr (src);
8408
8409       /* If the string length is zero, return the dst parameter.  */
8410       if (p && *p == '\0')
8411         return dst;
8412
8413       return 0;
8414     }
8415 }
8416
8417 /* Simplify a call to the strncat builtin.
8418
8419    Return 0 if no simplification was possible, otherwise return the
8420    simplified form of the call as a tree.
8421
8422    The simplified form may be a constant or other expression which
8423    computes the same value, but in a more efficient manner (including
8424    calls to other builtin functions).
8425
8426    The call may contain arguments which need to be evaluated, but
8427    which are not useful to determine the result of the call.  In
8428    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8429    COMPOUND_EXPR will be an argument which must be evaluated.
8430    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8431    COMPOUND_EXPR in the chain will contain the tree for the simplified
8432    form of the builtin function call.  */
8433
8434 static tree
8435 fold_builtin_strncat (tree arglist)
8436 {
8437   if (!validate_arglist (arglist,
8438                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
8439     return 0;
8440   else
8441     {
8442       tree dst = TREE_VALUE (arglist);
8443       tree src = TREE_VALUE (TREE_CHAIN (arglist));
8444       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8445       const char *p = c_getstr (src);
8446
8447       /* If the requested length is zero, or the src parameter string
8448           length is zero, return the dst parameter.  */
8449       if (integer_zerop (len) || (p && *p == '\0'))
8450         return omit_two_operands (TREE_TYPE (dst), dst, src, len);
8451
8452       /* If the requested len is greater than or equal to the string
8453          length, call strcat.  */
8454       if (TREE_CODE (len) == INTEGER_CST && p
8455           && compare_tree_int (len, strlen (p)) >= 0)
8456         {
8457           tree newarglist
8458             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
8459           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
8460
8461           /* If the replacement _DECL isn't initialized, don't do the
8462              transformation.  */
8463           if (!fn)
8464             return 0;
8465
8466           return build_function_call_expr (fn, newarglist);
8467         }
8468       return 0;
8469     }
8470 }
8471
8472 /* Simplify a call to the strspn builtin.
8473
8474    Return 0 if no simplification was possible, otherwise return the
8475    simplified form of the call as a tree.
8476
8477    The simplified form may be a constant or other expression which
8478    computes the same value, but in a more efficient manner (including
8479    calls to other builtin functions).
8480
8481    The call may contain arguments which need to be evaluated, but
8482    which are not useful to determine the result of the call.  In
8483    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8484    COMPOUND_EXPR will be an argument which must be evaluated.
8485    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8486    COMPOUND_EXPR in the chain will contain the tree for the simplified
8487    form of the builtin function call.  */
8488
8489 static tree
8490 fold_builtin_strspn (tree arglist)
8491 {
8492   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8493     return 0;
8494   else
8495     {
8496       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8497       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8498
8499       /* If both arguments are constants, evaluate at compile-time.  */
8500       if (p1 && p2)
8501         {
8502           const size_t r = strspn (p1, p2);
8503           return size_int (r);
8504         }
8505
8506       /* If either argument is "", return 0.  */
8507       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
8508         /* Evaluate and ignore both arguments in case either one has
8509            side-effects.  */
8510         return omit_two_operands (integer_type_node, integer_zero_node,
8511                                   s1, s2);
8512       return 0;
8513     }
8514 }
8515
8516 /* Simplify a call to the strcspn builtin.
8517
8518    Return 0 if no simplification was possible, otherwise return the
8519    simplified form of the call as a tree.
8520
8521    The simplified form may be a constant or other expression which
8522    computes the same value, but in a more efficient manner (including
8523    calls to other builtin functions).
8524
8525    The call may contain arguments which need to be evaluated, but
8526    which are not useful to determine the result of the call.  In
8527    this case we return a chain of COMPOUND_EXPRs.  The LHS of each
8528    COMPOUND_EXPR will be an argument which must be evaluated.
8529    COMPOUND_EXPRs are chained through their RHS.  The RHS of the last
8530    COMPOUND_EXPR in the chain will contain the tree for the simplified
8531    form of the builtin function call.  */
8532
8533 static tree
8534 fold_builtin_strcspn (tree arglist)
8535 {
8536   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8537     return 0;
8538   else
8539     {
8540       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
8541       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
8542
8543       /* If both arguments are constants, evaluate at compile-time.  */
8544       if (p1 && p2)
8545         {
8546           const size_t r = strcspn (p1, p2);
8547           return size_int (r);
8548         }
8549
8550       /* If the first argument is "", return 0.  */
8551       if (p1 && *p1 == '\0')
8552         {
8553           /* Evaluate and ignore argument s2 in case it has
8554              side-effects.  */
8555           return omit_one_operand (integer_type_node,
8556                                    integer_zero_node, s2);
8557         }
8558
8559       /* If the second argument is "", return __builtin_strlen(s1).  */
8560       if (p2 && *p2 == '\0')
8561         {
8562           tree newarglist = build_tree_list (NULL_TREE, s1),
8563             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
8564
8565           /* If the replacement _DECL isn't initialized, don't do the
8566              transformation.  */
8567           if (!fn)
8568             return 0;
8569
8570           return build_function_call_expr (fn, newarglist);
8571         }
8572       return 0;
8573     }
8574 }
8575
8576 /* Fold a call to the fputs builtin.  IGNORE is true if the value returned
8577    by the builtin will be ignored.  UNLOCKED is true is true if this
8578    actually a call to fputs_unlocked.  If LEN in non-NULL, it represents
8579    the known length of the string.  Return NULL_TREE if no simplification
8580    was possible.  */
8581
8582 tree
8583 fold_builtin_fputs (tree arglist, bool ignore, bool unlocked, tree len)
8584 {
8585   tree fn;
8586   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
8587     : implicit_built_in_decls[BUILT_IN_FPUTC];
8588   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
8589     : implicit_built_in_decls[BUILT_IN_FWRITE];
8590
8591   /* If the return value is used, or the replacement _DECL isn't
8592      initialized, don't do the transformation.  */
8593   if (!ignore || !fn_fputc || !fn_fwrite)
8594     return 0;
8595
8596   /* Verify the arguments in the original call.  */
8597   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
8598     return 0;
8599
8600   if (! len)
8601     len = c_strlen (TREE_VALUE (arglist), 0);
8602
8603   /* Get the length of the string passed to fputs.  If the length
8604      can't be determined, punt.  */
8605   if (!len
8606       || TREE_CODE (len) != INTEGER_CST)
8607     return 0;
8608
8609   switch (compare_tree_int (len, 1))
8610     {
8611     case -1: /* length is 0, delete the call entirely .  */
8612       return omit_one_operand (integer_type_node, integer_zero_node,
8613                                TREE_VALUE (TREE_CHAIN (arglist)));
8614
8615     case 0: /* length is 1, call fputc.  */
8616       {
8617         const char *p = c_getstr (TREE_VALUE (arglist));
8618
8619         if (p != NULL)
8620           {
8621             /* New argument list transforming fputs(string, stream) to
8622                fputc(string[0], stream).  */
8623             arglist = build_tree_list (NULL_TREE,
8624                                        TREE_VALUE (TREE_CHAIN (arglist)));
8625             arglist = tree_cons (NULL_TREE,
8626                                  build_int_cst (NULL_TREE, p[0]),
8627                                  arglist);
8628             fn = fn_fputc;
8629             break;
8630           }
8631       }
8632       /* FALLTHROUGH */
8633     case 1: /* length is greater than 1, call fwrite.  */
8634       {
8635         tree string_arg;
8636
8637         /* If optimizing for size keep fputs.  */
8638         if (optimize_size)
8639           return 0;
8640         string_arg = TREE_VALUE (arglist);
8641         /* New argument list transforming fputs(string, stream) to
8642            fwrite(string, 1, len, stream).  */
8643         arglist = build_tree_list (NULL_TREE,
8644                                    TREE_VALUE (TREE_CHAIN (arglist)));
8645         arglist = tree_cons (NULL_TREE, len, arglist);
8646         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
8647         arglist = tree_cons (NULL_TREE, string_arg, arglist);
8648         fn = fn_fwrite;
8649         break;
8650       }
8651     default:
8652       gcc_unreachable ();
8653     }
8654
8655   /* These optimizations are only performed when the result is ignored,
8656      hence there's no need to cast the result to integer_type_node.  */
8657   return build_function_call_expr (fn, arglist);
8658 }
8659
8660 static void
8661 fold_builtin_next_arg (tree arglist)
8662 {
8663   tree fntype = TREE_TYPE (current_function_decl);
8664
8665   if (TYPE_ARG_TYPES (fntype) == 0
8666       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
8667           == void_type_node))
8668     error ("%<va_start%> used in function with fixed args");
8669   else if (arglist)
8670     {
8671       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
8672       tree arg = TREE_VALUE (arglist);
8673
8674       /* Strip off all nops for the sake of the comparison.  This
8675          is not quite the same as STRIP_NOPS.  It does more.
8676          We must also strip off INDIRECT_EXPR for C++ reference
8677          parameters.  */
8678       while (TREE_CODE (arg) == NOP_EXPR
8679              || TREE_CODE (arg) == CONVERT_EXPR
8680              || TREE_CODE (arg) == NON_LVALUE_EXPR
8681              || TREE_CODE (arg) == INDIRECT_REF)
8682         arg = TREE_OPERAND (arg, 0);
8683       if (arg != last_parm)
8684         warning ("second parameter of %<va_start%> not last named argument");
8685       TREE_VALUE (arglist) = arg;
8686     }
8687   else
8688     /* Evidently an out of date version of <stdarg.h>; can't validate
8689        va_start's second argument, but can still work as intended.  */
8690     warning ("%<__builtin_next_arg%> called without an argument");
8691 }
8692
8693
8694 /* Simplify a call to the sprintf builtin.
8695
8696    Return 0 if no simplification was possible, otherwise return the
8697    simplified form of the call as a tree.  If IGNORED is true, it means that
8698    the caller does not use the returned value of the function.  */
8699
8700 static tree
8701 fold_builtin_sprintf (tree arglist, int ignored)
8702 {
8703   tree call, retval, dest, fmt;
8704   const char *fmt_str = NULL;
8705
8706   /* Verify the required arguments in the original call.  We deal with two
8707      types of sprintf() calls: 'sprintf (str, fmt)' and
8708      'sprintf (dest, "%s", orig)'.  */
8709   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)
8710       && !validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, POINTER_TYPE,
8711                             VOID_TYPE))
8712     return NULL_TREE;
8713
8714   /* Get the destination string and the format specifier.  */
8715   dest = TREE_VALUE (arglist);
8716   fmt = TREE_VALUE (TREE_CHAIN (arglist));
8717
8718   /* Check whether the format is a literal string constant.  */
8719   fmt_str = c_getstr (fmt);
8720   if (fmt_str == NULL)
8721     return NULL_TREE;
8722
8723   call = NULL_TREE;
8724   retval = NULL_TREE;
8725
8726   /* If the format doesn't contain % args or %%, use strcpy.  */
8727   if (strchr (fmt_str, '%') == NULL)
8728     {
8729       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8730
8731       if (!fn)
8732         return NULL_TREE;
8733
8734       /* Convert sprintf (str, fmt) into strcpy (str, fmt) when
8735          'format' is known to contain no % formats.  */
8736       arglist = build_tree_list (NULL_TREE, fmt);
8737       arglist = tree_cons (NULL_TREE, dest, arglist);
8738       call = build_function_call_expr (fn, arglist);
8739       if (!ignored)
8740         retval = build_int_cst (NULL_TREE, strlen (fmt_str));
8741     }
8742
8743   /* If the format is "%s", use strcpy if the result isn't used.  */
8744   else if (fmt_str && strcmp (fmt_str, "%s") == 0)
8745     {
8746       tree fn, orig;
8747       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
8748
8749       if (!fn)
8750         return NULL_TREE;
8751
8752       /* Convert sprintf (str1, "%s", str2) into strcpy (str1, str2).  */
8753       orig = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
8754       arglist = build_tree_list (NULL_TREE, orig);
8755       arglist = tree_cons (NULL_TREE, dest, arglist);
8756       if (!ignored)
8757         {
8758           retval = c_strlen (orig, 1);
8759           if (!retval || TREE_CODE (retval) != INTEGER_CST)
8760             return NULL_TREE;
8761         }
8762       call = build_function_call_expr (fn, arglist);
8763     }
8764
8765   if (call && retval)
8766     {
8767       retval = convert
8768         (TREE_TYPE (TREE_TYPE (implicit_built_in_decls[BUILT_IN_SPRINTF])),
8769          retval);
8770       return build2 (COMPOUND_EXPR, TREE_TYPE (retval), call, retval);
8771     }
8772   else
8773     return call;
8774 }