OSDN Git Service

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