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