OSDN Git Service

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