OSDN Git Service

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