OSDN Git Service

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