OSDN Git Service

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