OSDN Git Service

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