OSDN Git Service

5c9971acdb7fd85caec9c2f1328b25405832a887
[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 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 "flags.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "except.h"
34 #include "function.h"
35 #include "insn-config.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "output.h"
41 #include "typeclass.h"
42 #include "toplev.h"
43 #include "predict.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "langhooks.h"
47
48 #define CALLED_AS_BUILT_IN(NODE) \
49    (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
50
51 /* Register mappings for target machines without register windows.  */
52 #ifndef INCOMING_REGNO
53 #define INCOMING_REGNO(OUT) (OUT)
54 #endif
55 #ifndef OUTGOING_REGNO
56 #define OUTGOING_REGNO(IN) (IN)
57 #endif
58
59 #ifndef PAD_VARARGS_DOWN
60 #define PAD_VARARGS_DOWN BYTES_BIG_ENDIAN
61 #endif
62
63 /* Define the names of the builtin function types and codes.  */
64 const char *const built_in_class_names[4]
65   = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
66
67 #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
68 const char *const built_in_names[(int) END_BUILTINS] =
69 {
70 #include "builtins.def"
71 };
72 #undef DEF_BUILTIN
73
74 /* Setup an array of _DECL trees, make sure each element is
75    initialized to NULL_TREE.  */
76 tree built_in_decls[(int) END_BUILTINS];
77 /* Declarations used when constructing the builtin implicitly in the compiler.
78    It may be NULL_TREE when this is invalid (for instance runtime is not
79    required to implement the function call in all cases.  */
80 tree implicit_built_in_decls[(int) END_BUILTINS];
81
82 static int get_pointer_alignment (tree, unsigned int);
83 static tree c_strlen (tree, int);
84 static const char *c_getstr (tree);
85 static rtx c_readstr (const char *, enum machine_mode);
86 static int target_char_cast (tree, char *);
87 static rtx get_memory_rtx (tree);
88 static tree build_string_literal (int, const char *);
89 static int apply_args_size (void);
90 static int apply_result_size (void);
91 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
92 static rtx result_vector (int, rtx);
93 #endif
94 static rtx expand_builtin_setjmp (tree, rtx);
95 static void expand_builtin_prefetch (tree);
96 static rtx expand_builtin_apply_args (void);
97 static rtx expand_builtin_apply_args_1 (void);
98 static rtx expand_builtin_apply (rtx, rtx, rtx);
99 static void expand_builtin_return (rtx);
100 static enum type_class type_to_class (tree);
101 static rtx expand_builtin_classify_type (tree);
102 static void expand_errno_check (tree, rtx);
103 static rtx expand_builtin_mathfn (tree, rtx, rtx);
104 static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
105 static rtx expand_builtin_constant_p (tree, enum machine_mode);
106 static rtx expand_builtin_args_info (tree);
107 static rtx expand_builtin_next_arg (tree);
108 static rtx expand_builtin_va_start (tree);
109 static rtx expand_builtin_va_end (tree);
110 static rtx expand_builtin_va_copy (tree);
111 static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
112 static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
113 static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
114 static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
115 static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
116 static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
117 static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
118 static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
119 static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
120 static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
121 static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
122 static rtx expand_builtin_bcopy (tree);
123 static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
124 static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
125 static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
126 static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
127 static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
128 static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
129 static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
130 static rtx expand_builtin_bzero (tree);
131 static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
132 static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
133 static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
134 static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
135 static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
136 static rtx expand_builtin_alloca (tree, rtx);
137 static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
138 static rtx expand_builtin_frame_address (tree, tree);
139 static rtx expand_builtin_fputs (tree, rtx, bool);
140 static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
141 static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
142 static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
143 static tree stabilize_va_list (tree, int);
144 static rtx expand_builtin_expect (tree, rtx);
145 static tree fold_builtin_constant_p (tree);
146 static tree fold_builtin_classify_type (tree);
147 static tree fold_builtin_inf (tree, int);
148 static tree fold_builtin_nan (tree, tree, int);
149 static int validate_arglist (tree, ...);
150 static bool integer_valued_real_p (tree);
151 static tree fold_trunc_transparent_mathfn (tree);
152 static bool readonly_data_expr (tree);
153 static rtx expand_builtin_fabs (tree, rtx, rtx);
154 static rtx expand_builtin_cabs (tree, rtx);
155 static tree fold_builtin_cabs (tree, tree, tree);
156 static tree fold_builtin_trunc (tree);
157 static tree fold_builtin_floor (tree);
158 static tree fold_builtin_ceil (tree);
159 static tree fold_builtin_bitop (tree);
160 static tree fold_builtin_memcpy (tree);
161 static tree fold_builtin_mempcpy (tree);
162 static tree fold_builtin_memmove (tree);
163 static tree fold_builtin_strcpy (tree);
164 static tree fold_builtin_strncpy (tree);
165 static tree fold_builtin_memcmp (tree);
166 static tree fold_builtin_strcmp (tree);
167 static tree fold_builtin_strncmp (tree);
168
169 /* Return the alignment in bits of EXP, a pointer valued expression.
170    But don't return more than MAX_ALIGN no matter what.
171    The alignment returned is, by default, the alignment of the thing that
172    EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
173
174    Otherwise, look at the expression to see if we can do better, i.e., if the
175    expression is actually pointing at an object whose alignment is tighter.  */
176
177 static int
178 get_pointer_alignment (tree exp, unsigned int max_align)
179 {
180   unsigned int align, inner;
181
182   if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
183     return 0;
184
185   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
186   align = MIN (align, max_align);
187
188   while (1)
189     {
190       switch (TREE_CODE (exp))
191         {
192         case NOP_EXPR:
193         case CONVERT_EXPR:
194         case NON_LVALUE_EXPR:
195           exp = TREE_OPERAND (exp, 0);
196           if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
197             return align;
198
199           inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
200           align = MIN (inner, max_align);
201           break;
202
203         case PLUS_EXPR:
204           /* If sum of pointer + int, restrict our maximum alignment to that
205              imposed by the integer.  If not, we can't do any better than
206              ALIGN.  */
207           if (! host_integerp (TREE_OPERAND (exp, 1), 1))
208             return align;
209
210           while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
211                   & (max_align / BITS_PER_UNIT - 1))
212                  != 0)
213             max_align >>= 1;
214
215           exp = TREE_OPERAND (exp, 0);
216           break;
217
218         case ADDR_EXPR:
219           /* See what we are pointing at and look at its alignment.  */
220           exp = TREE_OPERAND (exp, 0);
221           if (TREE_CODE (exp) == FUNCTION_DECL)
222             align = FUNCTION_BOUNDARY;
223           else if (DECL_P (exp))
224             align = DECL_ALIGN (exp);
225 #ifdef CONSTANT_ALIGNMENT
226           else if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'c')
227             align = CONSTANT_ALIGNMENT (exp, align);
228 #endif
229           return MIN (align, max_align);
230
231         default:
232           return align;
233         }
234     }
235 }
236
237 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
238    way, because it could contain a zero byte in the middle.
239    TREE_STRING_LENGTH is the size of the character array, not the string.
240
241    ONLY_VALUE should be nonzero if the result is not going to be emitted
242    into the instruction stream and zero if it is going to be expanded.
243    E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
244    is returned, otherwise NULL, since
245    len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
246    evaluate the side-effects.
247
248    The value returned is of type `ssizetype'.
249
250    Unfortunately, string_constant can't access the values of const char
251    arrays with initializers, so neither can we do so here.  */
252
253 static tree
254 c_strlen (tree src, int only_value)
255 {
256   tree offset_node;
257   HOST_WIDE_INT offset;
258   int max;
259   const char *ptr;
260
261   STRIP_NOPS (src);
262   if (TREE_CODE (src) == COND_EXPR
263       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
264     {
265       tree len1, len2;
266
267       len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
268       len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
269       if (tree_int_cst_equal (len1, len2))      
270         return len1;
271     }
272
273   if (TREE_CODE (src) == COMPOUND_EXPR
274       && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
275     return c_strlen (TREE_OPERAND (src, 1), only_value);
276
277   src = string_constant (src, &offset_node);
278   if (src == 0)
279     return 0;
280
281   max = TREE_STRING_LENGTH (src) - 1;
282   ptr = TREE_STRING_POINTER (src);
283
284   if (offset_node && TREE_CODE (offset_node) != INTEGER_CST)
285     {
286       /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't
287          compute the offset to the following null if we don't know where to
288          start searching for it.  */
289       int i;
290
291       for (i = 0; i < max; i++)
292         if (ptr[i] == 0)
293           return 0;
294
295       /* We don't know the starting offset, but we do know that the string
296          has no internal zero bytes.  We can assume that the offset falls
297          within the bounds of the string; otherwise, the programmer deserves
298          what he gets.  Subtract the offset from the length of the string,
299          and return that.  This would perhaps not be valid if we were dealing
300          with named arrays in addition to literal string constants.  */
301
302       return size_diffop (size_int (max), offset_node);
303     }
304
305   /* We have a known offset into the string.  Start searching there for
306      a null character if we can represent it as a single HOST_WIDE_INT.  */
307   if (offset_node == 0)
308     offset = 0;
309   else if (! host_integerp (offset_node, 0))
310     offset = -1;
311   else
312     offset = tree_low_cst (offset_node, 0);
313
314   /* If the offset is known to be out of bounds, warn, and call strlen at
315      runtime.  */
316   if (offset < 0 || offset > max)
317     {
318       warning ("offset outside bounds of constant string");
319       return 0;
320     }
321
322   /* Use strlen to search for the first zero byte.  Since any strings
323      constructed with build_string will have nulls appended, we win even
324      if we get handed something like (char[4])"abcd".
325
326      Since OFFSET is our starting index into the string, no further
327      calculation is needed.  */
328   return ssize_int (strlen (ptr + offset));
329 }
330
331 /* Return a char pointer for a C string if it is a string constant
332    or sum of string constant and integer constant.  */
333
334 static const char *
335 c_getstr (tree src)
336 {
337   tree offset_node;
338
339   src = string_constant (src, &offset_node);
340   if (src == 0)
341     return 0;
342
343   if (offset_node == 0)
344     return TREE_STRING_POINTER (src);
345   else if (!host_integerp (offset_node, 1)
346            || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0)
347     return 0;
348
349   return TREE_STRING_POINTER (src) + tree_low_cst (offset_node, 1);
350 }
351
352 /* Return a CONST_INT or CONST_DOUBLE corresponding to target reading
353    GET_MODE_BITSIZE (MODE) bits from string constant STR.  */
354
355 static rtx
356 c_readstr (const char *str, enum machine_mode mode)
357 {
358   HOST_WIDE_INT c[2];
359   HOST_WIDE_INT ch;
360   unsigned int i, j;
361
362   if (GET_MODE_CLASS (mode) != MODE_INT)
363     abort ();
364   c[0] = 0;
365   c[1] = 0;
366   ch = 1;
367   for (i = 0; i < GET_MODE_SIZE (mode); i++)
368     {
369       j = i;
370       if (WORDS_BIG_ENDIAN)
371         j = GET_MODE_SIZE (mode) - i - 1;
372       if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
373           && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
374         j = j + UNITS_PER_WORD - 2 * (j % UNITS_PER_WORD) - 1;
375       j *= BITS_PER_UNIT;
376       if (j > 2 * HOST_BITS_PER_WIDE_INT)
377         abort ();
378       if (ch)
379         ch = (unsigned char) str[i];
380       c[j / HOST_BITS_PER_WIDE_INT] |= ch << (j % HOST_BITS_PER_WIDE_INT);
381     }
382   return immed_double_const (c[0], c[1], mode);
383 }
384
385 /* Cast a target constant CST to target CHAR and if that value fits into
386    host char type, return zero and put that value into variable pointed by
387    P.  */
388
389 static int
390 target_char_cast (tree cst, char *p)
391 {
392   unsigned HOST_WIDE_INT val, hostval;
393
394   if (!host_integerp (cst, 1)
395       || CHAR_TYPE_SIZE > HOST_BITS_PER_WIDE_INT)
396     return 1;
397
398   val = tree_low_cst (cst, 1);
399   if (CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT)
400     val &= (((unsigned HOST_WIDE_INT) 1) << CHAR_TYPE_SIZE) - 1;
401
402   hostval = val;
403   if (HOST_BITS_PER_CHAR < HOST_BITS_PER_WIDE_INT)
404     hostval &= (((unsigned HOST_WIDE_INT) 1) << HOST_BITS_PER_CHAR) - 1;
405
406   if (val != hostval)
407     return 1;
408
409   *p = hostval;
410   return 0;
411 }
412
413 /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT
414    times to get the address of either a higher stack frame, or a return
415    address located within it (depending on FNDECL_CODE).  */
416
417 rtx
418 expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
419                             rtx tem)
420 {
421   int i;
422
423   /* Some machines need special handling before we can access
424      arbitrary frames.  For example, on the sparc, we must first flush
425      all register windows to the stack.  */
426 #ifdef SETUP_FRAME_ADDRESSES
427   if (count > 0)
428     SETUP_FRAME_ADDRESSES ();
429 #endif
430
431   /* On the sparc, the return address is not in the frame, it is in a
432      register.  There is no way to access it off of the current frame
433      pointer, but it can be accessed off the previous frame pointer by
434      reading the value from the register window save area.  */
435 #ifdef RETURN_ADDR_IN_PREVIOUS_FRAME
436   if (fndecl_code == BUILT_IN_RETURN_ADDRESS)
437     count--;
438 #endif
439
440   /* Scan back COUNT frames to the specified frame.  */
441   for (i = 0; i < count; i++)
442     {
443       /* Assume the dynamic chain pointer is in the word that the
444          frame address points to, unless otherwise specified.  */
445 #ifdef DYNAMIC_CHAIN_ADDRESS
446       tem = DYNAMIC_CHAIN_ADDRESS (tem);
447 #endif
448       tem = memory_address (Pmode, tem);
449       tem = gen_rtx_MEM (Pmode, tem);
450       set_mem_alias_set (tem, get_frame_alias_set ());
451       tem = copy_to_reg (tem);
452     }
453
454   /* For __builtin_frame_address, return what we've got.  */
455   if (fndecl_code == BUILT_IN_FRAME_ADDRESS)
456     return tem;
457
458   /* For __builtin_return_address, Get the return address from that
459      frame.  */
460 #ifdef RETURN_ADDR_RTX
461   tem = RETURN_ADDR_RTX (count, tem);
462 #else
463   tem = memory_address (Pmode,
464                         plus_constant (tem, GET_MODE_SIZE (Pmode)));
465   tem = gen_rtx_MEM (Pmode, tem);
466   set_mem_alias_set (tem, get_frame_alias_set ());
467 #endif
468   return tem;
469 }
470
471 /* Alias set used for setjmp buffer.  */
472 static HOST_WIDE_INT setjmp_alias_set = -1;
473
474 /* Construct the leading half of a __builtin_setjmp call.  Control will
475    return to RECEIVER_LABEL.  This is used directly by sjlj exception
476    handling code.  */
477
478 void
479 expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
480 {
481   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
482   rtx stack_save;
483   rtx mem;
484
485   if (setjmp_alias_set == -1)
486     setjmp_alias_set = new_alias_set ();
487
488   buf_addr = convert_memory_address (Pmode, buf_addr);
489
490   buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
491
492   emit_queue ();
493
494   /* We store the frame pointer and the address of receiver_label in
495      the buffer and use the rest of it for the stack save area, which
496      is machine-dependent.  */
497
498 #ifndef BUILTIN_SETJMP_FRAME_VALUE
499 #define BUILTIN_SETJMP_FRAME_VALUE virtual_stack_vars_rtx
500 #endif
501
502   mem = gen_rtx_MEM (Pmode, buf_addr);
503   set_mem_alias_set (mem, setjmp_alias_set);
504   emit_move_insn (mem, BUILTIN_SETJMP_FRAME_VALUE);
505
506   mem = gen_rtx_MEM (Pmode, plus_constant (buf_addr, GET_MODE_SIZE (Pmode))),
507   set_mem_alias_set (mem, setjmp_alias_set);
508
509   emit_move_insn (validize_mem (mem),
510                   force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, receiver_label)));
511
512   stack_save = gen_rtx_MEM (sa_mode,
513                             plus_constant (buf_addr,
514                                            2 * GET_MODE_SIZE (Pmode)));
515   set_mem_alias_set (stack_save, setjmp_alias_set);
516   emit_stack_save (SAVE_NONLOCAL, &stack_save, NULL_RTX);
517
518   /* If there is further processing to do, do it.  */
519 #ifdef HAVE_builtin_setjmp_setup
520   if (HAVE_builtin_setjmp_setup)
521     emit_insn (gen_builtin_setjmp_setup (buf_addr));
522 #endif
523
524   /* Tell optimize_save_area_alloca that extra work is going to
525      need to go on during alloca.  */
526   current_function_calls_setjmp = 1;
527
528   /* Set this so all the registers get saved in our frame; we need to be
529      able to copy the saved values for any registers from frames we unwind.  */
530   current_function_has_nonlocal_label = 1;
531 }
532
533 /* Construct the trailing part of a __builtin_setjmp call.
534    This is used directly by sjlj exception handling code.  */
535
536 void
537 expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
538 {
539   /* Clobber the FP when we get here, so we have to make sure it's
540      marked as used by this function.  */
541   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
542
543   /* Mark the static chain as clobbered here so life information
544      doesn't get messed up for it.  */
545   emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
546
547   /* Now put in the code to restore the frame pointer, and argument
548      pointer, if needed.  The code below is from expand_end_bindings
549      in stmt.c; see detailed documentation there.  */
550 #ifdef HAVE_nonlocal_goto
551   if (! HAVE_nonlocal_goto)
552 #endif
553     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
554
555 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
556   if (fixed_regs[ARG_POINTER_REGNUM])
557     {
558 #ifdef ELIMINABLE_REGS
559       size_t i;
560       static const struct elims {const int from, to;} elim_regs[] = ELIMINABLE_REGS;
561
562       for (i = 0; i < ARRAY_SIZE (elim_regs); i++)
563         if (elim_regs[i].from == ARG_POINTER_REGNUM
564             && elim_regs[i].to == HARD_FRAME_POINTER_REGNUM)
565           break;
566
567       if (i == ARRAY_SIZE (elim_regs))
568 #endif
569         {
570           /* Now restore our arg pointer from the address at which it
571              was saved in our stack frame.  */
572           emit_move_insn (virtual_incoming_args_rtx,
573                           copy_to_reg (get_arg_pointer_save_area (cfun)));
574         }
575     }
576 #endif
577
578 #ifdef HAVE_builtin_setjmp_receiver
579   if (HAVE_builtin_setjmp_receiver)
580     emit_insn (gen_builtin_setjmp_receiver (receiver_label));
581   else
582 #endif
583 #ifdef HAVE_nonlocal_goto_receiver
584     if (HAVE_nonlocal_goto_receiver)
585       emit_insn (gen_nonlocal_goto_receiver ());
586     else
587 #endif
588       { /* Nothing */ }
589
590   /* @@@ This is a kludge.  Not all machine descriptions define a blockage
591      insn, but we must not allow the code we just generated to be reordered
592      by scheduling.  Specifically, the update of the frame pointer must
593      happen immediately, not later.  So emit an ASM_INPUT to act as blockage
594      insn.  */
595   emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
596 }
597
598 /* __builtin_setjmp is passed a pointer to an array of five words (not
599    all will be used on all machines).  It operates similarly to the C
600    library function of the same name, but is more efficient.  Much of
601    the code below (and for longjmp) is copied from the handling of
602    non-local gotos.
603
604    NOTE: This is intended for use by GNAT and the exception handling
605    scheme in the compiler and will only work in the method used by
606    them.  */
607
608 static rtx
609 expand_builtin_setjmp (tree arglist, rtx target)
610 {
611   rtx buf_addr, next_lab, cont_lab;
612
613   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
614     return NULL_RTX;
615
616   if (target == 0 || GET_CODE (target) != REG
617       || REGNO (target) < FIRST_PSEUDO_REGISTER)
618     target = gen_reg_rtx (TYPE_MODE (integer_type_node));
619
620   buf_addr = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
621
622   next_lab = gen_label_rtx ();
623   cont_lab = gen_label_rtx ();
624
625   expand_builtin_setjmp_setup (buf_addr, next_lab);
626
627   /* Set TARGET to zero and branch to the continue label.  Use emit_jump to
628      ensure that pending stack adjustments are flushed.  */
629   emit_move_insn (target, const0_rtx);
630   emit_jump (cont_lab);
631
632   emit_label (next_lab);
633
634   expand_builtin_setjmp_receiver (next_lab);
635
636   /* Set TARGET to one.  */
637   emit_move_insn (target, const1_rtx);
638   emit_label (cont_lab);
639
640   /* Tell flow about the strange goings on.  Putting `next_lab' on
641      `nonlocal_goto_handler_labels' to indicates that function
642      calls may traverse the arc back to this label.  */
643
644   current_function_has_nonlocal_label = 1;
645   nonlocal_goto_handler_labels
646     = gen_rtx_EXPR_LIST (VOIDmode, next_lab, nonlocal_goto_handler_labels);
647
648   return target;
649 }
650
651 /* __builtin_longjmp is passed a pointer to an array of five words (not
652    all will be used on all machines).  It operates similarly to the C
653    library function of the same name, but is more efficient.  Much of
654    the code below is copied from the handling of non-local gotos.
655
656    NOTE: This is intended for use by GNAT and the exception handling
657    scheme in the compiler and will only work in the method used by
658    them.  */
659
660 void
661 expand_builtin_longjmp (rtx buf_addr, rtx value)
662 {
663   rtx fp, lab, stack, insn, last;
664   enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
665
666   if (setjmp_alias_set == -1)
667     setjmp_alias_set = new_alias_set ();
668
669   buf_addr = convert_memory_address (Pmode, buf_addr);
670
671   buf_addr = force_reg (Pmode, buf_addr);
672
673   /* We used to store value in static_chain_rtx, but that fails if pointers
674      are smaller than integers.  We instead require that the user must pass
675      a second argument of 1, because that is what builtin_setjmp will
676      return.  This also makes EH slightly more efficient, since we are no
677      longer copying around a value that we don't care about.  */
678   if (value != const1_rtx)
679     abort ();
680
681   current_function_calls_longjmp = 1;
682
683   last = get_last_insn ();
684 #ifdef HAVE_builtin_longjmp
685   if (HAVE_builtin_longjmp)
686     emit_insn (gen_builtin_longjmp (buf_addr));
687   else
688 #endif
689     {
690       fp = gen_rtx_MEM (Pmode, buf_addr);
691       lab = gen_rtx_MEM (Pmode, plus_constant (buf_addr,
692                                                GET_MODE_SIZE (Pmode)));
693
694       stack = gen_rtx_MEM (sa_mode, plus_constant (buf_addr,
695                                                    2 * GET_MODE_SIZE (Pmode)));
696       set_mem_alias_set (fp, setjmp_alias_set);
697       set_mem_alias_set (lab, setjmp_alias_set);
698       set_mem_alias_set (stack, setjmp_alias_set);
699
700       /* Pick up FP, label, and SP from the block and jump.  This code is
701          from expand_goto in stmt.c; see there for detailed comments.  */
702 #if HAVE_nonlocal_goto
703       if (HAVE_nonlocal_goto)
704         /* We have to pass a value to the nonlocal_goto pattern that will
705            get copied into the static_chain pointer, but it does not matter
706            what that value is, because builtin_setjmp does not use it.  */
707         emit_insn (gen_nonlocal_goto (value, lab, stack, fp));
708       else
709 #endif
710         {
711           lab = copy_to_reg (lab);
712
713           emit_insn (gen_rtx_CLOBBER (VOIDmode,
714                                       gen_rtx_MEM (BLKmode,
715                                                    gen_rtx_SCRATCH (VOIDmode))));
716           emit_insn (gen_rtx_CLOBBER (VOIDmode,
717                                       gen_rtx_MEM (BLKmode,
718                                                    hard_frame_pointer_rtx)));
719
720           emit_move_insn (hard_frame_pointer_rtx, fp);
721           emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
722
723           emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
724           emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
725           emit_indirect_jump (lab);
726         }
727     }
728
729   /* Search backwards and mark the jump insn as a non-local goto.
730      Note that this precludes the use of __builtin_longjmp to a
731      __builtin_setjmp target in the same function.  However, we've
732      already cautioned the user that these functions are for
733      internal exception handling use only.  */
734   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
735     {
736       if (insn == last)
737         abort ();
738       if (GET_CODE (insn) == JUMP_INSN)
739         {
740           REG_NOTES (insn) = alloc_EXPR_LIST (REG_NON_LOCAL_GOTO, const0_rtx,
741                                               REG_NOTES (insn));
742           break;
743         }
744       else if (GET_CODE (insn) == CALL_INSN)
745         break;
746     }
747 }
748
749 /* Expand a call to __builtin_prefetch.  For a target that does not support
750    data prefetch, evaluate the memory address argument in case it has side
751    effects.  */
752
753 static void
754 expand_builtin_prefetch (tree arglist)
755 {
756   tree arg0, arg1, arg2;
757   rtx op0, op1, op2;
758
759   if (!validate_arglist (arglist, POINTER_TYPE, 0))
760     return;
761
762   arg0 = TREE_VALUE (arglist);
763   /* Arguments 1 and 2 are optional; argument 1 (read/write) defaults to
764      zero (read) and argument 2 (locality) defaults to 3 (high degree of
765      locality).  */
766   if (TREE_CHAIN (arglist))
767     {
768       arg1 = TREE_VALUE (TREE_CHAIN (arglist));
769       if (TREE_CHAIN (TREE_CHAIN (arglist)))
770         arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
771       else
772         arg2 = build_int_2 (3, 0);
773     }
774   else
775     {
776       arg1 = integer_zero_node;
777       arg2 = build_int_2 (3, 0);
778     }
779
780   /* Argument 0 is an address.  */
781   op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL);
782
783   /* Argument 1 (read/write flag) must be a compile-time constant int.  */
784   if (TREE_CODE (arg1) != INTEGER_CST)
785     {
786       error ("second arg to `__builtin_prefetch' must be a constant");
787       arg1 = integer_zero_node;
788     }
789   op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
790   /* Argument 1 must be either zero or one.  */
791   if (INTVAL (op1) != 0 && INTVAL (op1) != 1)
792     {
793       warning ("invalid second arg to __builtin_prefetch; using zero");
794       op1 = const0_rtx;
795     }
796
797   /* Argument 2 (locality) must be a compile-time constant int.  */
798   if (TREE_CODE (arg2) != INTEGER_CST)
799     {
800       error ("third arg to `__builtin_prefetch' must be a constant");
801       arg2 = integer_zero_node;
802     }
803   op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
804   /* Argument 2 must be 0, 1, 2, or 3.  */
805   if (INTVAL (op2) < 0 || INTVAL (op2) > 3)
806     {
807       warning ("invalid third arg to __builtin_prefetch; using zero");
808       op2 = const0_rtx;
809     }
810
811 #ifdef HAVE_prefetch
812   if (HAVE_prefetch)
813     {
814       if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
815              (op0,
816               insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
817           || (GET_MODE (op0) != Pmode))
818         {
819           op0 = convert_memory_address (Pmode, op0);
820           op0 = force_reg (Pmode, op0);
821         }
822       emit_insn (gen_prefetch (op0, op1, op2));
823     }
824   else
825 #endif
826     op0 = protect_from_queue (op0, 0);
827   /* Don't do anything with direct references to volatile memory, but
828      generate code to handle other side effects.  */
829   if (GET_CODE (op0) != MEM && side_effects_p (op0))
830     emit_insn (op0);
831 }
832
833 /* Get a MEM rtx for expression EXP which is the address of an operand
834    to be used to be used in a string instruction (cmpstrsi, movstrsi, ..).  */
835
836 static rtx
837 get_memory_rtx (tree exp)
838 {
839   rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
840   rtx mem;
841
842   addr = convert_memory_address (Pmode, addr);
843
844   mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
845
846   /* Get an expression we can use to find the attributes to assign to MEM.
847      If it is an ADDR_EXPR, use the operand.  Otherwise, dereference it if
848      we can.  First remove any nops.  */
849   while ((TREE_CODE (exp) == NOP_EXPR || TREE_CODE (exp) == CONVERT_EXPR
850           || TREE_CODE (exp) == NON_LVALUE_EXPR)
851          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (exp, 0))))
852     exp = TREE_OPERAND (exp, 0);
853
854   if (TREE_CODE (exp) == ADDR_EXPR)
855     {
856       exp = TREE_OPERAND (exp, 0);
857       set_mem_attributes (mem, exp, 0);
858     }
859   else if (POINTER_TYPE_P (TREE_TYPE (exp)))
860     {
861       exp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (exp)), exp);
862       /* memcpy, memset and other builtin stringops can alias with anything.  */
863       set_mem_alias_set (mem, 0);
864     }
865
866   return mem;
867 }
868 \f
869 /* Built-in functions to perform an untyped call and return.  */
870
871 /* For each register that may be used for calling a function, this
872    gives a mode used to copy the register's value.  VOIDmode indicates
873    the register is not used for calling a function.  If the machine
874    has register windows, this gives only the outbound registers.
875    INCOMING_REGNO gives the corresponding inbound register.  */
876 static enum machine_mode apply_args_mode[FIRST_PSEUDO_REGISTER];
877
878 /* For each register that may be used for returning values, this gives
879    a mode used to copy the register's value.  VOIDmode indicates the
880    register is not used for returning values.  If the machine has
881    register windows, this gives only the outbound registers.
882    INCOMING_REGNO gives the corresponding inbound register.  */
883 static enum machine_mode apply_result_mode[FIRST_PSEUDO_REGISTER];
884
885 /* For each register that may be used for calling a function, this
886    gives the offset of that register into the block returned by
887    __builtin_apply_args.  0 indicates that the register is not
888    used for calling a function.  */
889 static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
890
891 /* Return the offset of register REGNO into the block returned by
892    __builtin_apply_args.  This is not declared static, since it is
893    needed in objc-act.c.  */
894
895 int
896 apply_args_register_offset (int regno)
897 {
898   apply_args_size ();
899
900   /* Arguments are always put in outgoing registers (in the argument
901      block) if such make sense.  */
902 #ifdef OUTGOING_REGNO
903   regno = OUTGOING_REGNO (regno);
904 #endif
905   return apply_args_reg_offset[regno];
906 }
907
908 /* Return the size required for the block returned by __builtin_apply_args,
909    and initialize apply_args_mode.  */
910
911 static int
912 apply_args_size (void)
913 {
914   static int size = -1;
915   int align;
916   unsigned int regno;
917   enum machine_mode mode;
918
919   /* The values computed by this function never change.  */
920   if (size < 0)
921     {
922       /* The first value is the incoming arg-pointer.  */
923       size = GET_MODE_SIZE (Pmode);
924
925       /* The second value is the structure value address unless this is
926          passed as an "invisible" first argument.  */
927       if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
928         size += GET_MODE_SIZE (Pmode);
929
930       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
931         if (FUNCTION_ARG_REGNO_P (regno))
932           {
933             /* Search for the proper mode for copying this register's
934                value.  I'm not sure this is right, but it works so far.  */
935             enum machine_mode best_mode = VOIDmode;
936
937             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
938                  mode != VOIDmode;
939                  mode = GET_MODE_WIDER_MODE (mode))
940               if (HARD_REGNO_MODE_OK (regno, mode)
941                   && HARD_REGNO_NREGS (regno, mode) == 1)
942                 best_mode = mode;
943
944             if (best_mode == VOIDmode)
945               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
946                    mode != VOIDmode;
947                    mode = GET_MODE_WIDER_MODE (mode))
948                 if (HARD_REGNO_MODE_OK (regno, mode)
949                     && have_insn_for (SET, mode))
950                   best_mode = mode;
951
952             if (best_mode == VOIDmode)
953               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
954                    mode != VOIDmode;
955                    mode = GET_MODE_WIDER_MODE (mode))
956                 if (HARD_REGNO_MODE_OK (regno, mode)
957                     && have_insn_for (SET, mode))
958                   best_mode = mode;
959
960             if (best_mode == VOIDmode)
961               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
962                    mode != VOIDmode;
963                    mode = GET_MODE_WIDER_MODE (mode))
964                 if (HARD_REGNO_MODE_OK (regno, mode)
965                     && have_insn_for (SET, mode))
966                   best_mode = mode;
967
968             mode = best_mode;
969             if (mode == VOIDmode)
970               abort ();
971
972             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
973             if (size % align != 0)
974               size = CEIL (size, align) * align;
975             apply_args_reg_offset[regno] = size;
976             size += GET_MODE_SIZE (mode);
977             apply_args_mode[regno] = mode;
978           }
979         else
980           {
981             apply_args_mode[regno] = VOIDmode;
982             apply_args_reg_offset[regno] = 0;
983           }
984     }
985   return size;
986 }
987
988 /* Return the size required for the block returned by __builtin_apply,
989    and initialize apply_result_mode.  */
990
991 static int
992 apply_result_size (void)
993 {
994   static int size = -1;
995   int align, regno;
996   enum machine_mode mode;
997
998   /* The values computed by this function never change.  */
999   if (size < 0)
1000     {
1001       size = 0;
1002
1003       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1004         if (FUNCTION_VALUE_REGNO_P (regno))
1005           {
1006             /* Search for the proper mode for copying this register's
1007                value.  I'm not sure this is right, but it works so far.  */
1008             enum machine_mode best_mode = VOIDmode;
1009
1010             for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
1011                  mode != TImode;
1012                  mode = GET_MODE_WIDER_MODE (mode))
1013               if (HARD_REGNO_MODE_OK (regno, mode))
1014                 best_mode = mode;
1015
1016             if (best_mode == VOIDmode)
1017               for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
1018                    mode != VOIDmode;
1019                    mode = GET_MODE_WIDER_MODE (mode))
1020                 if (HARD_REGNO_MODE_OK (regno, mode)
1021                     && have_insn_for (SET, mode))
1022                   best_mode = mode;
1023
1024             if (best_mode == VOIDmode)
1025               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
1026                    mode != VOIDmode;
1027                    mode = GET_MODE_WIDER_MODE (mode))
1028                 if (HARD_REGNO_MODE_OK (regno, mode)
1029                     && have_insn_for (SET, mode))
1030                   best_mode = mode;
1031
1032             if (best_mode == VOIDmode)
1033               for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
1034                    mode != VOIDmode;
1035                    mode = GET_MODE_WIDER_MODE (mode))
1036                 if (HARD_REGNO_MODE_OK (regno, mode)
1037                     && have_insn_for (SET, mode))
1038                   best_mode = mode;
1039
1040             mode = best_mode;
1041             if (mode == VOIDmode)
1042               abort ();
1043
1044             align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1045             if (size % align != 0)
1046               size = CEIL (size, align) * align;
1047             size += GET_MODE_SIZE (mode);
1048             apply_result_mode[regno] = mode;
1049           }
1050         else
1051           apply_result_mode[regno] = VOIDmode;
1052
1053       /* Allow targets that use untyped_call and untyped_return to override
1054          the size so that machine-specific information can be stored here.  */
1055 #ifdef APPLY_RESULT_SIZE
1056       size = APPLY_RESULT_SIZE;
1057 #endif
1058     }
1059   return size;
1060 }
1061
1062 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
1063 /* Create a vector describing the result block RESULT.  If SAVEP is true,
1064    the result block is used to save the values; otherwise it is used to
1065    restore the values.  */
1066
1067 static rtx
1068 result_vector (int savep, rtx result)
1069 {
1070   int regno, size, align, nelts;
1071   enum machine_mode mode;
1072   rtx reg, mem;
1073   rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
1074
1075   size = nelts = 0;
1076   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1077     if ((mode = apply_result_mode[regno]) != VOIDmode)
1078       {
1079         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1080         if (size % align != 0)
1081           size = CEIL (size, align) * align;
1082         reg = gen_rtx_REG (mode, savep ? regno : INCOMING_REGNO (regno));
1083         mem = adjust_address (result, mode, size);
1084         savevec[nelts++] = (savep
1085                             ? gen_rtx_SET (VOIDmode, mem, reg)
1086                             : gen_rtx_SET (VOIDmode, reg, mem));
1087         size += GET_MODE_SIZE (mode);
1088       }
1089   return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nelts, savevec));
1090 }
1091 #endif /* HAVE_untyped_call or HAVE_untyped_return */
1092
1093 /* Save the state required to perform an untyped call with the same
1094    arguments as were passed to the current function.  */
1095
1096 static rtx
1097 expand_builtin_apply_args_1 (void)
1098 {
1099   rtx registers;
1100   int size, align, regno;
1101   enum machine_mode mode;
1102   rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
1103
1104   /* Create a block where the arg-pointer, structure value address,
1105      and argument registers can be saved.  */
1106   registers = assign_stack_local (BLKmode, apply_args_size (), -1);
1107
1108   /* Walk past the arg-pointer and structure value address.  */
1109   size = GET_MODE_SIZE (Pmode);
1110   if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
1111     size += GET_MODE_SIZE (Pmode);
1112
1113   /* Save each register used in calling a function to the block.  */
1114   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1115     if ((mode = apply_args_mode[regno]) != VOIDmode)
1116       {
1117         rtx tem;
1118
1119         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1120         if (size % align != 0)
1121           size = CEIL (size, align) * align;
1122
1123         tem = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1124
1125         emit_move_insn (adjust_address (registers, mode, size), tem);
1126         size += GET_MODE_SIZE (mode);
1127       }
1128
1129   /* Save the arg pointer to the block.  */
1130   emit_move_insn (adjust_address (registers, Pmode, 0),
1131                   copy_to_reg (virtual_incoming_args_rtx));
1132   size = GET_MODE_SIZE (Pmode);
1133
1134   /* Save the structure value address unless this is passed as an
1135      "invisible" first argument.  */
1136   if (struct_incoming_value)
1137     {
1138       emit_move_insn (adjust_address (registers, Pmode, size),
1139                       copy_to_reg (struct_incoming_value));
1140       size += GET_MODE_SIZE (Pmode);
1141     }
1142
1143   /* Return the address of the block.  */
1144   return copy_addr_to_reg (XEXP (registers, 0));
1145 }
1146
1147 /* __builtin_apply_args returns block of memory allocated on
1148    the stack into which is stored the arg pointer, structure
1149    value address, static chain, and all the registers that might
1150    possibly be used in performing a function call.  The code is
1151    moved to the start of the function so the incoming values are
1152    saved.  */
1153
1154 static rtx
1155 expand_builtin_apply_args (void)
1156 {
1157   /* Don't do __builtin_apply_args more than once in a function.
1158      Save the result of the first call and reuse it.  */
1159   if (apply_args_value != 0)
1160     return apply_args_value;
1161   {
1162     /* When this function is called, it means that registers must be
1163        saved on entry to this function.  So we migrate the
1164        call to the first insn of this function.  */
1165     rtx temp;
1166     rtx seq;
1167
1168     start_sequence ();
1169     temp = expand_builtin_apply_args_1 ();
1170     seq = get_insns ();
1171     end_sequence ();
1172
1173     apply_args_value = temp;
1174
1175     /* Put the insns after the NOTE that starts the function.
1176        If this is inside a start_sequence, make the outer-level insn
1177        chain current, so the code is placed at the start of the
1178        function.  */
1179     push_topmost_sequence ();
1180     emit_insn_before (seq, NEXT_INSN (get_insns ()));
1181     pop_topmost_sequence ();
1182     return temp;
1183   }
1184 }
1185
1186 /* Perform an untyped call and save the state required to perform an
1187    untyped return of whatever value was returned by the given function.  */
1188
1189 static rtx
1190 expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
1191 {
1192   int size, align, regno;
1193   enum machine_mode mode;
1194   rtx incoming_args, result, reg, dest, src, call_insn;
1195   rtx old_stack_level = 0;
1196   rtx call_fusage = 0;
1197   rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
1198
1199   arguments = convert_memory_address (Pmode, arguments);
1200
1201   /* Create a block where the return registers can be saved.  */
1202   result = assign_stack_local (BLKmode, apply_result_size (), -1);
1203
1204   /* Fetch the arg pointer from the ARGUMENTS block.  */
1205   incoming_args = gen_reg_rtx (Pmode);
1206   emit_move_insn (incoming_args, gen_rtx_MEM (Pmode, arguments));
1207 #ifndef STACK_GROWS_DOWNWARD
1208   incoming_args = expand_simple_binop (Pmode, MINUS, incoming_args, argsize,
1209                                        incoming_args, 0, OPTAB_LIB_WIDEN);
1210 #endif
1211
1212   /* Perform postincrements before actually calling the function.  */
1213   emit_queue ();
1214
1215   /* Push a new argument block and copy the arguments.  Do not allow
1216      the (potential) memcpy call below to interfere with our stack
1217      manipulations.  */
1218   do_pending_stack_adjust ();
1219   NO_DEFER_POP;
1220
1221   /* Save the stack with nonlocal if available.  */
1222 #ifdef HAVE_save_stack_nonlocal
1223   if (HAVE_save_stack_nonlocal)
1224     emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
1225   else
1226 #endif
1227     emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
1228
1229   /* Allocate a block of memory onto the stack and copy the memory
1230      arguments to the outgoing arguments address.  */
1231   allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
1232   dest = virtual_outgoing_args_rtx;
1233 #ifndef STACK_GROWS_DOWNWARD
1234   if (GET_CODE (argsize) == CONST_INT)
1235     dest = plus_constant (dest, -INTVAL (argsize));
1236   else
1237     dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
1238 #endif
1239   dest = gen_rtx_MEM (BLKmode, dest);
1240   set_mem_align (dest, PARM_BOUNDARY);
1241   src = gen_rtx_MEM (BLKmode, incoming_args);
1242   set_mem_align (src, PARM_BOUNDARY);
1243   emit_block_move (dest, src, argsize, BLOCK_OP_NORMAL);
1244
1245   /* Refer to the argument block.  */
1246   apply_args_size ();
1247   arguments = gen_rtx_MEM (BLKmode, arguments);
1248   set_mem_align (arguments, PARM_BOUNDARY);
1249
1250   /* Walk past the arg-pointer and structure value address.  */
1251   size = GET_MODE_SIZE (Pmode);
1252   if (struct_value)
1253     size += GET_MODE_SIZE (Pmode);
1254
1255   /* Restore each of the registers previously saved.  Make USE insns
1256      for each of these registers for use in making the call.  */
1257   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1258     if ((mode = apply_args_mode[regno]) != VOIDmode)
1259       {
1260         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1261         if (size % align != 0)
1262           size = CEIL (size, align) * align;
1263         reg = gen_rtx_REG (mode, regno);
1264         emit_move_insn (reg, adjust_address (arguments, mode, size));
1265         use_reg (&call_fusage, reg);
1266         size += GET_MODE_SIZE (mode);
1267       }
1268
1269   /* Restore the structure value address unless this is passed as an
1270      "invisible" first argument.  */
1271   size = GET_MODE_SIZE (Pmode);
1272   if (struct_value)
1273     {
1274       rtx value = gen_reg_rtx (Pmode);
1275       emit_move_insn (value, adjust_address (arguments, Pmode, size));
1276       emit_move_insn (struct_value, value);
1277       if (GET_CODE (struct_value) == REG)
1278         use_reg (&call_fusage, struct_value);
1279       size += GET_MODE_SIZE (Pmode);
1280     }
1281
1282   /* All arguments and registers used for the call are set up by now!  */
1283   function = prepare_call_address (function, NULL_TREE, &call_fusage, 0, 0);
1284
1285   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
1286      and we don't want to load it into a register as an optimization,
1287      because prepare_call_address already did it if it should be done.  */
1288   if (GET_CODE (function) != SYMBOL_REF)
1289     function = memory_address (FUNCTION_MODE, function);
1290
1291   /* Generate the actual call instruction and save the return value.  */
1292 #ifdef HAVE_untyped_call
1293   if (HAVE_untyped_call)
1294     emit_call_insn (gen_untyped_call (gen_rtx_MEM (FUNCTION_MODE, function),
1295                                       result, result_vector (1, result)));
1296   else
1297 #endif
1298 #ifdef HAVE_call_value
1299   if (HAVE_call_value)
1300     {
1301       rtx valreg = 0;
1302
1303       /* Locate the unique return register.  It is not possible to
1304          express a call that sets more than one return register using
1305          call_value; use untyped_call for that.  In fact, untyped_call
1306          only needs to save the return registers in the given block.  */
1307       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1308         if ((mode = apply_result_mode[regno]) != VOIDmode)
1309           {
1310             if (valreg)
1311               abort (); /* HAVE_untyped_call required.  */
1312             valreg = gen_rtx_REG (mode, regno);
1313           }
1314
1315       emit_call_insn (GEN_CALL_VALUE (valreg,
1316                                       gen_rtx_MEM (FUNCTION_MODE, function),
1317                                       const0_rtx, NULL_RTX, const0_rtx));
1318
1319       emit_move_insn (adjust_address (result, GET_MODE (valreg), 0), valreg);
1320     }
1321   else
1322 #endif
1323     abort ();
1324
1325   /* Find the CALL insn we just emitted, and attach the register usage
1326      information.  */
1327   call_insn = last_call_insn ();
1328   add_function_usage_to (call_insn, call_fusage);
1329
1330   /* Restore the stack.  */
1331 #ifdef HAVE_save_stack_nonlocal
1332   if (HAVE_save_stack_nonlocal)
1333     emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX);
1334   else
1335 #endif
1336     emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
1337
1338   OK_DEFER_POP;
1339
1340   /* Return the address of the result block.  */
1341   result = copy_addr_to_reg (XEXP (result, 0));
1342   return convert_memory_address (ptr_mode, result);
1343 }
1344
1345 /* Perform an untyped return.  */
1346
1347 static void
1348 expand_builtin_return (rtx result)
1349 {
1350   int size, align, regno;
1351   enum machine_mode mode;
1352   rtx reg;
1353   rtx call_fusage = 0;
1354
1355   result = convert_memory_address (Pmode, result);
1356
1357   apply_result_size ();
1358   result = gen_rtx_MEM (BLKmode, result);
1359
1360 #ifdef HAVE_untyped_return
1361   if (HAVE_untyped_return)
1362     {
1363       emit_jump_insn (gen_untyped_return (result, result_vector (0, result)));
1364       emit_barrier ();
1365       return;
1366     }
1367 #endif
1368
1369   /* Restore the return value and note that each value is used.  */
1370   size = 0;
1371   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1372     if ((mode = apply_result_mode[regno]) != VOIDmode)
1373       {
1374         align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
1375         if (size % align != 0)
1376           size = CEIL (size, align) * align;
1377         reg = gen_rtx_REG (mode, INCOMING_REGNO (regno));
1378         emit_move_insn (reg, adjust_address (result, mode, size));
1379
1380         push_to_sequence (call_fusage);
1381         emit_insn (gen_rtx_USE (VOIDmode, reg));
1382         call_fusage = get_insns ();
1383         end_sequence ();
1384         size += GET_MODE_SIZE (mode);
1385       }
1386
1387   /* Put the USE insns before the return.  */
1388   emit_insn (call_fusage);
1389
1390   /* Return whatever values was restored by jumping directly to the end
1391      of the function.  */
1392   expand_null_return ();
1393 }
1394
1395 /* Used by expand_builtin_classify_type and fold_builtin_classify_type.  */
1396
1397 static enum type_class
1398 type_to_class (tree type)
1399 {
1400   switch (TREE_CODE (type))
1401     {
1402     case VOID_TYPE:        return void_type_class;
1403     case INTEGER_TYPE:     return integer_type_class;
1404     case CHAR_TYPE:        return char_type_class;
1405     case ENUMERAL_TYPE:    return enumeral_type_class;
1406     case BOOLEAN_TYPE:     return boolean_type_class;
1407     case POINTER_TYPE:     return pointer_type_class;
1408     case REFERENCE_TYPE:   return reference_type_class;
1409     case OFFSET_TYPE:      return offset_type_class;
1410     case REAL_TYPE:        return real_type_class;
1411     case COMPLEX_TYPE:     return complex_type_class;
1412     case FUNCTION_TYPE:    return function_type_class;
1413     case METHOD_TYPE:      return method_type_class;
1414     case RECORD_TYPE:      return record_type_class;
1415     case UNION_TYPE:
1416     case QUAL_UNION_TYPE:  return union_type_class;
1417     case ARRAY_TYPE:       return (TYPE_STRING_FLAG (type)
1418                                    ? string_type_class : array_type_class);
1419     case SET_TYPE:         return set_type_class;
1420     case FILE_TYPE:        return file_type_class;
1421     case LANG_TYPE:        return lang_type_class;
1422     default:               return no_type_class;
1423     }
1424 }
1425
1426 /* Expand a call to __builtin_classify_type with arguments found in
1427    ARGLIST.  */
1428
1429 static rtx
1430 expand_builtin_classify_type (tree arglist)
1431 {
1432   if (arglist != 0)
1433     return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
1434   return GEN_INT (no_type_class);
1435 }
1436
1437 /* Expand expression EXP, which is a call to __builtin_constant_p.  */
1438
1439 static rtx
1440 expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
1441 {
1442   rtx tmp;
1443
1444   if (arglist == 0)
1445     return const0_rtx;
1446   arglist = TREE_VALUE (arglist);
1447
1448   /* We have taken care of the easy cases during constant folding.  This
1449      case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
1450      get a chance to see if it can deduce whether ARGLIST is constant.
1451      If CSE isn't going to run, of course, don't bother waiting.  */
1452
1453   if (cse_not_expected)
1454     return const0_rtx;
1455
1456   current_function_calls_constant_p = 1;
1457
1458   tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
1459   tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
1460   return tmp;
1461 }
1462
1463 /* This helper macro, meant to be used in mathfn_built_in below,
1464    determines which among a set of three builtin math functions is
1465    appropriate for a given type mode.  The `F' and `L' cases are
1466    automatically generated from the `double' case.  */
1467 #define CASE_MATHFN(BUILT_IN_MATHFN) \
1468   case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
1469   fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
1470   fcodel = BUILT_IN_MATHFN##L ; break;
1471
1472 /* Return mathematic function equivalent to FN but operating directly
1473    on TYPE, if available.  If we can't do the conversion, return zero.  */
1474 tree
1475 mathfn_built_in (tree type, enum built_in_function fn)
1476 {
1477   const enum machine_mode type_mode = TYPE_MODE (type);
1478   enum built_in_function fcode, fcodef, fcodel;
1479
1480   switch (fn)
1481     {
1482       CASE_MATHFN (BUILT_IN_ACOS)
1483       CASE_MATHFN (BUILT_IN_ACOSH)
1484       CASE_MATHFN (BUILT_IN_ASIN)
1485       CASE_MATHFN (BUILT_IN_ASINH)
1486       CASE_MATHFN (BUILT_IN_ATAN)
1487       CASE_MATHFN (BUILT_IN_ATAN2)
1488       CASE_MATHFN (BUILT_IN_ATANH)
1489       CASE_MATHFN (BUILT_IN_CBRT)
1490       CASE_MATHFN (BUILT_IN_CEIL)
1491       CASE_MATHFN (BUILT_IN_COPYSIGN)
1492       CASE_MATHFN (BUILT_IN_COS)
1493       CASE_MATHFN (BUILT_IN_COSH)
1494       CASE_MATHFN (BUILT_IN_DREM)
1495       CASE_MATHFN (BUILT_IN_ERF)
1496       CASE_MATHFN (BUILT_IN_ERFC)
1497       CASE_MATHFN (BUILT_IN_EXP)
1498       CASE_MATHFN (BUILT_IN_EXP10)
1499       CASE_MATHFN (BUILT_IN_EXP2)
1500       CASE_MATHFN (BUILT_IN_EXPM1)
1501       CASE_MATHFN (BUILT_IN_FABS)
1502       CASE_MATHFN (BUILT_IN_FDIM)
1503       CASE_MATHFN (BUILT_IN_FLOOR)
1504       CASE_MATHFN (BUILT_IN_FMA)
1505       CASE_MATHFN (BUILT_IN_FMAX)
1506       CASE_MATHFN (BUILT_IN_FMIN)
1507       CASE_MATHFN (BUILT_IN_FMOD)
1508       CASE_MATHFN (BUILT_IN_FREXP)
1509       CASE_MATHFN (BUILT_IN_GAMMA)
1510       CASE_MATHFN (BUILT_IN_HUGE_VAL)
1511       CASE_MATHFN (BUILT_IN_HYPOT)
1512       CASE_MATHFN (BUILT_IN_ILOGB)
1513       CASE_MATHFN (BUILT_IN_INF)
1514       CASE_MATHFN (BUILT_IN_J0)
1515       CASE_MATHFN (BUILT_IN_J1)
1516       CASE_MATHFN (BUILT_IN_JN)
1517       CASE_MATHFN (BUILT_IN_LDEXP)
1518       CASE_MATHFN (BUILT_IN_LGAMMA)
1519       CASE_MATHFN (BUILT_IN_LLRINT)
1520       CASE_MATHFN (BUILT_IN_LLROUND)
1521       CASE_MATHFN (BUILT_IN_LOG)
1522       CASE_MATHFN (BUILT_IN_LOG10)
1523       CASE_MATHFN (BUILT_IN_LOG1P)
1524       CASE_MATHFN (BUILT_IN_LOG2)
1525       CASE_MATHFN (BUILT_IN_LOGB)
1526       CASE_MATHFN (BUILT_IN_LRINT)
1527       CASE_MATHFN (BUILT_IN_LROUND)
1528       CASE_MATHFN (BUILT_IN_MODF)
1529       CASE_MATHFN (BUILT_IN_NAN)
1530       CASE_MATHFN (BUILT_IN_NANS)
1531       CASE_MATHFN (BUILT_IN_NEARBYINT)
1532       CASE_MATHFN (BUILT_IN_NEXTAFTER)
1533       CASE_MATHFN (BUILT_IN_NEXTTOWARD)
1534       CASE_MATHFN (BUILT_IN_POW)
1535       CASE_MATHFN (BUILT_IN_POW10)
1536       CASE_MATHFN (BUILT_IN_REMAINDER)
1537       CASE_MATHFN (BUILT_IN_REMQUO)
1538       CASE_MATHFN (BUILT_IN_RINT)
1539       CASE_MATHFN (BUILT_IN_ROUND)
1540       CASE_MATHFN (BUILT_IN_SCALB)
1541       CASE_MATHFN (BUILT_IN_SCALBLN)
1542       CASE_MATHFN (BUILT_IN_SCALBN)
1543       CASE_MATHFN (BUILT_IN_SIGNIFICAND)
1544       CASE_MATHFN (BUILT_IN_SIN)
1545       CASE_MATHFN (BUILT_IN_SINCOS)
1546       CASE_MATHFN (BUILT_IN_SINH)
1547       CASE_MATHFN (BUILT_IN_SQRT)
1548       CASE_MATHFN (BUILT_IN_TAN)
1549       CASE_MATHFN (BUILT_IN_TANH)
1550       CASE_MATHFN (BUILT_IN_TGAMMA)
1551       CASE_MATHFN (BUILT_IN_TRUNC)
1552       CASE_MATHFN (BUILT_IN_Y0)
1553       CASE_MATHFN (BUILT_IN_Y1)
1554       CASE_MATHFN (BUILT_IN_YN)
1555
1556       default:
1557         return 0;
1558       }
1559
1560   if (type_mode == TYPE_MODE (double_type_node))
1561     return implicit_built_in_decls[fcode];
1562   else if (type_mode == TYPE_MODE (float_type_node))
1563     return implicit_built_in_decls[fcodef];
1564   else if (type_mode == TYPE_MODE (long_double_type_node))
1565     return implicit_built_in_decls[fcodel];
1566   else
1567     return 0;
1568 }
1569
1570 /* If errno must be maintained, expand the RTL to check if the result,
1571    TARGET, of a built-in function call, EXP, is NaN, and if so set
1572    errno to EDOM.  */
1573
1574 static void
1575 expand_errno_check (tree exp, rtx target)
1576 {
1577   rtx lab = gen_label_rtx ();
1578
1579   /* Test the result; if it is NaN, set errno=EDOM because
1580      the argument was not in the domain.  */
1581   emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
1582                            0, lab);
1583
1584 #ifdef TARGET_EDOM
1585   /* If this built-in doesn't throw an exception, set errno directly.  */
1586   if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
1587     {
1588 #ifdef GEN_ERRNO_RTX
1589       rtx errno_rtx = GEN_ERRNO_RTX;
1590 #else
1591       rtx errno_rtx
1592           = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
1593 #endif
1594       emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
1595       emit_label (lab);
1596       return;
1597     }
1598 #endif
1599
1600   /* We can't set errno=EDOM directly; let the library call do it.
1601      Pop the arguments right away in case the call gets deleted.  */
1602   NO_DEFER_POP;
1603   expand_call (exp, target, 0);
1604   OK_DEFER_POP;
1605   emit_label (lab);
1606 }
1607
1608
1609 /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
1610    Return 0 if a normal call should be emitted rather than expanding the
1611    function in-line.  EXP is the expression that is a call to the builtin
1612    function; if convenient, the result should be placed in TARGET.
1613    SUBTARGET may be used as the target for computing one of EXP's operands.  */
1614
1615 static rtx
1616 expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
1617 {
1618   optab builtin_optab;
1619   rtx op0, insns, before_call;
1620   tree fndecl = get_callee_fndecl (exp);
1621   tree arglist = TREE_OPERAND (exp, 1);
1622   enum machine_mode mode;
1623   bool errno_set = false;
1624   tree arg, narg;
1625
1626   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
1627     return 0;
1628
1629   arg = TREE_VALUE (arglist);
1630
1631   switch (DECL_FUNCTION_CODE (fndecl))
1632     {
1633     case BUILT_IN_SIN:
1634     case BUILT_IN_SINF:
1635     case BUILT_IN_SINL:
1636       builtin_optab = sin_optab; break;
1637     case BUILT_IN_COS:
1638     case BUILT_IN_COSF:
1639     case BUILT_IN_COSL:
1640       builtin_optab = cos_optab; break;
1641     case BUILT_IN_SQRT:
1642     case BUILT_IN_SQRTF:
1643     case BUILT_IN_SQRTL:
1644       errno_set = ! tree_expr_nonnegative_p (arg);
1645       builtin_optab = sqrt_optab;
1646       break;
1647     case BUILT_IN_EXP:
1648     case BUILT_IN_EXPF:
1649     case BUILT_IN_EXPL:
1650       errno_set = true; builtin_optab = exp_optab; break;
1651     case BUILT_IN_LOG:
1652     case BUILT_IN_LOGF:
1653     case BUILT_IN_LOGL:
1654       errno_set = true; builtin_optab = log_optab; break;
1655     case BUILT_IN_TAN:
1656     case BUILT_IN_TANF:
1657     case BUILT_IN_TANL:
1658       builtin_optab = tan_optab; break;
1659     case BUILT_IN_ATAN:
1660     case BUILT_IN_ATANF:
1661     case BUILT_IN_ATANL:
1662       builtin_optab = atan_optab; break;
1663     case BUILT_IN_FLOOR:
1664     case BUILT_IN_FLOORF:
1665     case BUILT_IN_FLOORL:
1666       builtin_optab = floor_optab; break;
1667     case BUILT_IN_CEIL:
1668     case BUILT_IN_CEILF:
1669     case BUILT_IN_CEILL:
1670       builtin_optab = ceil_optab; break;
1671     case BUILT_IN_TRUNC:
1672     case BUILT_IN_TRUNCF:
1673     case BUILT_IN_TRUNCL:
1674       builtin_optab = btrunc_optab; break;
1675     case BUILT_IN_ROUND:
1676     case BUILT_IN_ROUNDF:
1677     case BUILT_IN_ROUNDL:
1678       builtin_optab = round_optab; break;
1679     case BUILT_IN_NEARBYINT:
1680     case BUILT_IN_NEARBYINTF:
1681     case BUILT_IN_NEARBYINTL:
1682       builtin_optab = nearbyint_optab; break;
1683     default:
1684       abort ();
1685     }
1686
1687   /* Make a suitable register to place result in.  */
1688   mode = TYPE_MODE (TREE_TYPE (exp));
1689
1690   if (! flag_errno_math || ! HONOR_NANS (mode))
1691     errno_set = false;
1692
1693   /* Before working hard, check whether the instruction is available.  */
1694   if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1695     {
1696       target = gen_reg_rtx (mode);
1697
1698       /* Wrap the computation of the argument in a SAVE_EXPR, as we may
1699          need to expand the argument again.  This way, we will not perform
1700          side-effects more the once.  */
1701       narg = save_expr (arg);
1702       if (narg != arg)
1703         {
1704           arglist = build_tree_list (NULL_TREE, arg);
1705           exp = build_function_call_expr (fndecl, arglist);
1706         }
1707
1708       op0 = expand_expr (arg, subtarget, VOIDmode, 0);
1709
1710       emit_queue ();
1711       start_sequence ();
1712
1713       /* Compute into TARGET.
1714          Set TARGET to wherever the result comes back.  */
1715       target = expand_unop (mode, builtin_optab, op0, target, 0);
1716
1717       if (target != 0)
1718         {
1719           if (errno_set)
1720             expand_errno_check (exp, target);
1721
1722           /* Output the entire sequence.  */
1723           insns = get_insns ();
1724           end_sequence ();
1725           emit_insn (insns);
1726           return target;
1727         }
1728
1729       /* If we were unable to expand via the builtin, stop the sequence
1730          (without outputting the insns) and call to the library function
1731          with the stabilized argument list.  */
1732       end_sequence ();
1733     }
1734
1735   before_call = get_last_insn ();
1736
1737   target = expand_call (exp, target, target == const0_rtx);
1738
1739   /* If this is a sqrt operation and we don't care about errno, try to
1740      attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
1741      This allows the semantics of the libcall to be visible to the RTL
1742      optimizers.  */
1743   if (builtin_optab == sqrt_optab && !errno_set)
1744     {
1745       /* Search backwards through the insns emitted by expand_call looking
1746          for the instruction with the REG_RETVAL note.  */
1747       rtx last = get_last_insn ();
1748       while (last != before_call)
1749         {
1750           if (find_reg_note (last, REG_RETVAL, NULL))
1751             {
1752               rtx note = find_reg_note (last, REG_EQUAL, NULL);
1753               /* Check that the REQ_EQUAL note is an EXPR_LIST with
1754                  two elements, i.e. symbol_ref(sqrt) and the operand.  */
1755               if (note
1756                   && GET_CODE (note) == EXPR_LIST
1757                   && GET_CODE (XEXP (note, 0)) == EXPR_LIST
1758                   && XEXP (XEXP (note, 0), 1) != NULL_RTX
1759                   && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
1760                 {
1761                   rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
1762                   /* Check operand is a register with expected mode.  */
1763                   if (operand
1764                       && GET_CODE (operand) == REG
1765                       && GET_MODE (operand) == mode)
1766                     {
1767                       /* Replace the REG_EQUAL note with a SQRT rtx.  */
1768                       rtx equiv = gen_rtx_SQRT (mode, operand);
1769                       set_unique_reg_note (last, REG_EQUAL, equiv);
1770                     }
1771                 }
1772               break;
1773             }
1774           last = PREV_INSN (last);
1775         }
1776     }
1777
1778   return target;
1779 }
1780
1781 /* Expand a call to the builtin binary math functions (pow and atan2).
1782    Return 0 if a normal call should be emitted rather than expanding the
1783    function in-line.  EXP is the expression that is a call to the builtin
1784    function; if convenient, the result should be placed in TARGET.
1785    SUBTARGET may be used as the target for computing one of EXP's
1786    operands.  */
1787
1788 static rtx
1789 expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
1790 {
1791   optab builtin_optab;
1792   rtx op0, op1, insns;
1793   tree fndecl = get_callee_fndecl (exp);
1794   tree arglist = TREE_OPERAND (exp, 1);
1795   tree arg0, arg1, temp, narg;
1796   enum machine_mode mode;
1797   bool errno_set = true;
1798   bool stable = true;
1799
1800   if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
1801     return 0;
1802
1803   arg0 = TREE_VALUE (arglist);
1804   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1805
1806   switch (DECL_FUNCTION_CODE (fndecl))
1807     {
1808     case BUILT_IN_POW:
1809     case BUILT_IN_POWF:
1810     case BUILT_IN_POWL:
1811       builtin_optab = pow_optab; break;
1812     case BUILT_IN_ATAN2:
1813     case BUILT_IN_ATAN2F:
1814     case BUILT_IN_ATAN2L:
1815       builtin_optab = atan2_optab; break;
1816     default:
1817       abort ();
1818     }
1819
1820   /* Make a suitable register to place result in.  */
1821   mode = TYPE_MODE (TREE_TYPE (exp));
1822
1823   /* Before working hard, check whether the instruction is available.  */
1824   if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
1825     return 0;
1826
1827   target = gen_reg_rtx (mode);
1828
1829   if (! flag_errno_math || ! HONOR_NANS (mode))
1830     errno_set = false;
1831
1832   /* Alway stabilize the argument list.  */
1833   narg = save_expr (arg1);
1834   if (narg != arg1)
1835     {
1836       temp = build_tree_list (NULL_TREE, narg);
1837       stable = false;
1838     }
1839   else
1840     temp = TREE_CHAIN (arglist);
1841
1842   narg = save_expr (arg0);
1843   if (narg != arg0)
1844     {
1845       arglist = tree_cons (NULL_TREE, narg, temp);
1846       stable = false;
1847     }
1848   else if (! stable)
1849     arglist = tree_cons (NULL_TREE, arg0, temp);
1850
1851   if (! stable)
1852     exp = build_function_call_expr (fndecl, arglist);
1853
1854   op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
1855   op1 = expand_expr (arg1, 0, VOIDmode, 0);
1856
1857   emit_queue ();
1858   start_sequence ();
1859
1860   /* Compute into TARGET.
1861      Set TARGET to wherever the result comes back.  */
1862   target = expand_binop (mode, builtin_optab, op0, op1,
1863                          target, 0, OPTAB_DIRECT);
1864
1865   /* If we were unable to expand via the builtin, stop the sequence
1866      (without outputting the insns) and call to the library function
1867      with the stabilized argument list.  */
1868   if (target == 0)
1869     {
1870       end_sequence ();
1871       return expand_call (exp, target, target == const0_rtx);
1872     }
1873
1874   if (errno_set)
1875     expand_errno_check (exp, target);
1876
1877   /* Output the entire sequence.  */
1878   insns = get_insns ();
1879   end_sequence ();
1880   emit_insn (insns);
1881
1882   return target;
1883 }
1884
1885 /* To evaluate powi(x,n), the floating point value x raised to the
1886    constant integer exponent n, we use a hybrid algorithm that
1887    combines the "window method" with look-up tables.  For an
1888    introduction to exponentiation algorithms and "addition chains",
1889    see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1890    "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1891    3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1892    Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.  */
1893
1894 /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1895    multiplications to inline before calling the system library's pow
1896    function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1897    so this default never requires calling pow, powf or powl.  */
1898  
1899 #ifndef POWI_MAX_MULTS
1900 #define POWI_MAX_MULTS  (2*HOST_BITS_PER_WIDE_INT-2)
1901 #endif
1902
1903 /* The size of the "optimal power tree" lookup table.  All
1904    exponents less than this value are simply looked up in the
1905    powi_table below.  This threshold is also used to size the
1906    cache of pseudo registers that hold intermediate results.  */
1907 #define POWI_TABLE_SIZE 256
1908
1909 /* The size, in bits of the window, used in the "window method"
1910    exponentiation algorithm.  This is equivalent to a radix of
1911    (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".  */
1912 #define POWI_WINDOW_SIZE 3
1913
1914 /* The following table is an efficient representation of an
1915    "optimal power tree".  For each value, i, the corresponding
1916    value, j, in the table states than an optimal evaluation
1917    sequence for calculating pow(x,i) can be found by evaluating
1918    pow(x,j)*pow(x,i-j).  An optimal power tree for the first
1919    100 integers is given in Knuth's "Seminumerical algorithms".  */
1920
1921 static const unsigned char powi_table[POWI_TABLE_SIZE] =
1922   {
1923       0,   1,   1,   2,   2,   3,   3,   4,  /*   0 -   7 */
1924       4,   6,   5,   6,   6,  10,   7,   9,  /*   8 -  15 */
1925       8,  16,   9,  16,  10,  12,  11,  13,  /*  16 -  23 */
1926      12,  17,  13,  18,  14,  24,  15,  26,  /*  24 -  31 */
1927      16,  17,  17,  19,  18,  33,  19,  26,  /*  32 -  39 */
1928      20,  25,  21,  40,  22,  27,  23,  44,  /*  40 -  47 */
1929      24,  32,  25,  34,  26,  29,  27,  44,  /*  48 -  55 */
1930      28,  31,  29,  34,  30,  60,  31,  36,  /*  56 -  63 */
1931      32,  64,  33,  34,  34,  46,  35,  37,  /*  64 -  71 */
1932      36,  65,  37,  50,  38,  48,  39,  69,  /*  72 -  79 */
1933      40,  49,  41,  43,  42,  51,  43,  58,  /*  80 -  87 */
1934      44,  64,  45,  47,  46,  59,  47,  76,  /*  88 -  95 */
1935      48,  65,  49,  66,  50,  67,  51,  66,  /*  96 - 103 */
1936      52,  70,  53,  74,  54, 104,  55,  74,  /* 104 - 111 */
1937      56,  64,  57,  69,  58,  78,  59,  68,  /* 112 - 119 */
1938      60,  61,  61,  80,  62,  75,  63,  68,  /* 120 - 127 */
1939      64,  65,  65, 128,  66, 129,  67,  90,  /* 128 - 135 */
1940      68,  73,  69, 131,  70,  94,  71,  88,  /* 136 - 143 */
1941      72, 128,  73,  98,  74, 132,  75, 121,  /* 144 - 151 */
1942      76, 102,  77, 124,  78, 132,  79, 106,  /* 152 - 159 */
1943      80,  97,  81, 160,  82,  99,  83, 134,  /* 160 - 167 */
1944      84,  86,  85,  95,  86, 160,  87, 100,  /* 168 - 175 */
1945      88, 113,  89,  98,  90, 107,  91, 122,  /* 176 - 183 */
1946      92, 111,  93, 102,  94, 126,  95, 150,  /* 184 - 191 */
1947      96, 128,  97, 130,  98, 133,  99, 195,  /* 192 - 199 */
1948     100, 128, 101, 123, 102, 164, 103, 138,  /* 200 - 207 */
1949     104, 145, 105, 146, 106, 109, 107, 149,  /* 208 - 215 */
1950     108, 200, 109, 146, 110, 170, 111, 157,  /* 216 - 223 */
1951     112, 128, 113, 130, 114, 182, 115, 132,  /* 224 - 231 */
1952     116, 200, 117, 132, 118, 158, 119, 206,  /* 232 - 239 */
1953     120, 240, 121, 162, 122, 147, 123, 152,  /* 240 - 247 */
1954     124, 166, 125, 214, 126, 138, 127, 153,  /* 248 - 255 */
1955   };
1956
1957
1958 /* Return the number of multiplications required to calculate
1959    powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
1960    subroutine of powi_cost.  CACHE is an array indicating
1961    which exponents have already been calculated.  */
1962
1963 static int
1964 powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1965 {
1966   /* If we've already calculated this exponent, then this evaluation
1967      doesn't require any additional multiplications.  */
1968   if (cache[n])
1969     return 0;
1970
1971   cache[n] = true;
1972   return powi_lookup_cost (n - powi_table[n], cache)
1973          + powi_lookup_cost (powi_table[n], cache) + 1;
1974 }
1975
1976 /* Return the number of multiplications required to calculate
1977    powi(x,n) for an arbitrary x, given the exponent N.  This
1978    function needs to be kept in sync with expand_powi below.  */
1979
1980 static int
1981 powi_cost (HOST_WIDE_INT n)
1982 {
1983   bool cache[POWI_TABLE_SIZE];
1984   unsigned HOST_WIDE_INT digit;
1985   unsigned HOST_WIDE_INT val;
1986   int result;
1987
1988   if (n == 0)
1989     return 0;
1990
1991   /* Ignore the reciprocal when calculating the cost.  */
1992   val = (n < 0) ? -n : n;
1993
1994   /* Initialize the exponent cache.  */
1995   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1996   cache[1] = true;
1997
1998   result = 0;
1999
2000   while (val >= POWI_TABLE_SIZE)
2001     {
2002       if (val & 1)
2003         {
2004           digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
2005           result += powi_lookup_cost (digit, cache)
2006                     + POWI_WINDOW_SIZE + 1;
2007           val >>= POWI_WINDOW_SIZE;
2008         }
2009       else
2010         {
2011           val >>= 1;
2012           result++;
2013         }
2014     }
2015   
2016   return result + powi_lookup_cost (val, cache);
2017 }
2018
2019 /* Recursive subroutine of expand_powi.  This function takes the array,
2020    CACHE, of already calculated exponents and an exponent N and returns
2021    an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE.  */
2022
2023 static rtx
2024 expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
2025 {
2026   unsigned HOST_WIDE_INT digit;
2027   rtx target, result;
2028   rtx op0, op1;
2029
2030   if (n < POWI_TABLE_SIZE)
2031     {
2032       if (cache[n])
2033         return cache[n];
2034
2035       target = gen_reg_rtx (mode);
2036       cache[n] = target;
2037
2038       op0 = expand_powi_1 (mode, n - powi_table[n], cache);
2039       op1 = expand_powi_1 (mode, powi_table[n], cache);
2040     }
2041   else if (n & 1)
2042     {
2043       target = gen_reg_rtx (mode);
2044       digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
2045       op0 = expand_powi_1 (mode, n - digit, cache);
2046       op1 = expand_powi_1 (mode, digit, cache);
2047     }
2048   else
2049     {
2050       target = gen_reg_rtx (mode);
2051       op0 = expand_powi_1 (mode, n >> 1, cache);
2052       op1 = op0;
2053     }
2054
2055   result = expand_mult (mode, op0, op1, target, 0);
2056   if (result != target)
2057     emit_move_insn (target, result);
2058   return target;
2059 }
2060
2061 /* Expand the RTL to evaluate powi(x,n) in mode MODE.  X is the
2062    floating point operand in mode MODE, and N is the exponent.  This
2063    function needs to be kept in sync with powi_cost above.  */
2064    
2065 static rtx
2066 expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
2067 {
2068   unsigned HOST_WIDE_INT val;
2069   rtx cache[POWI_TABLE_SIZE];
2070   rtx result;
2071
2072   if (n == 0)
2073     return CONST1_RTX (mode);
2074
2075   val = (n < 0) ? -n : n;
2076
2077   memset (cache, 0, sizeof (cache));
2078   cache[1] = x;
2079
2080   result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
2081
2082   /* If the original exponent was negative, reciprocate the result.  */
2083   if (n < 0)
2084     result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
2085                            result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
2086
2087   return result;
2088 }
2089
2090 /* Expand a call to the pow built-in mathematical function.  Return 0 if
2091    a normal call should be emitted rather than expanding the function
2092    in-line.  EXP is the expression that is a call to the builtin
2093    function; if convenient, the result should be placed in TARGET.  */
2094
2095 static rtx
2096 expand_builtin_pow (tree exp, rtx target, rtx subtarget)
2097 {
2098   tree arglist = TREE_OPERAND (exp, 1);
2099   tree arg0, arg1;
2100
2101   if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
2102     return 0;
2103
2104   arg0 = TREE_VALUE (arglist);
2105   arg1 = TREE_VALUE (TREE_CHAIN (arglist));
2106
2107   if (TREE_CODE (arg1) == REAL_CST
2108       && ! TREE_CONSTANT_OVERFLOW (arg1))
2109     {
2110       REAL_VALUE_TYPE cint;
2111       REAL_VALUE_TYPE c;
2112       HOST_WIDE_INT n;
2113
2114       c = TREE_REAL_CST (arg1);
2115       n = real_to_integer (&c);
2116       real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
2117       if (real_identical (&c, &cint))
2118         {
2119           /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
2120              Otherwise, check the number of multiplications required.
2121              Note that pow never sets errno for an integer exponent.  */
2122           if ((n >= -1 && n <= 2)
2123               || (flag_unsafe_math_optimizations
2124                   && ! optimize_size
2125                   && powi_cost (n) <= POWI_MAX_MULTS))
2126             {
2127               enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
2128               rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
2129               op = force_reg (mode, op);
2130               return expand_powi (op, mode, n);
2131             }
2132         }
2133     }
2134   return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
2135 }
2136
2137 /* Expand expression EXP which is a call to the strlen builtin.  Return 0
2138    if we failed the caller should emit a normal call, otherwise
2139    try to get the result in TARGET, if convenient.  */
2140
2141 static rtx
2142 expand_builtin_strlen (tree arglist, rtx target,
2143                        enum machine_mode target_mode)
2144 {
2145   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
2146     return 0;
2147   else
2148     {
2149       rtx pat;
2150       tree len, src = TREE_VALUE (arglist);
2151       rtx result, src_reg, char_rtx, before_strlen;
2152       enum machine_mode insn_mode = target_mode, char_mode;
2153       enum insn_code icode = CODE_FOR_nothing;
2154       int align;
2155
2156       /* If the length can be computed at compile-time, return it.  */
2157       len = c_strlen (src, 0);
2158       if (len)
2159         return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2160
2161       /* If the length can be computed at compile-time and is constant
2162          integer, but there are side-effects in src, evaluate
2163          src for side-effects, then return len.
2164          E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
2165          can be optimized into: i++; x = 3;  */
2166       len = c_strlen (src, 1);
2167       if (len && TREE_CODE (len) == INTEGER_CST)
2168         {
2169           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2170           return expand_expr (len, target, target_mode, EXPAND_NORMAL);
2171         }
2172
2173       align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
2174
2175       /* If SRC is not a pointer type, don't do this operation inline.  */
2176       if (align == 0)
2177         return 0;
2178
2179       /* Bail out if we can't compute strlen in the right mode.  */
2180       while (insn_mode != VOIDmode)
2181         {
2182           icode = strlen_optab->handlers[(int) insn_mode].insn_code;
2183           if (icode != CODE_FOR_nothing)
2184             break;
2185
2186           insn_mode = GET_MODE_WIDER_MODE (insn_mode);
2187         }
2188       if (insn_mode == VOIDmode)
2189         return 0;
2190
2191       /* Make a place to write the result of the instruction.  */
2192       result = target;
2193       if (! (result != 0
2194              && GET_CODE (result) == REG
2195              && GET_MODE (result) == insn_mode
2196              && REGNO (result) >= FIRST_PSEUDO_REGISTER))
2197         result = gen_reg_rtx (insn_mode);
2198
2199       /* Make a place to hold the source address.  We will not expand
2200          the actual source until we are sure that the expansion will
2201          not fail -- there are trees that cannot be expanded twice.  */
2202       src_reg = gen_reg_rtx (Pmode);
2203
2204       /* Mark the beginning of the strlen sequence so we can emit the
2205          source operand later.  */
2206       before_strlen = get_last_insn ();
2207
2208       char_rtx = const0_rtx;
2209       char_mode = insn_data[(int) icode].operand[2].mode;
2210       if (! (*insn_data[(int) icode].operand[2].predicate) (char_rtx,
2211                                                             char_mode))
2212         char_rtx = copy_to_mode_reg (char_mode, char_rtx);
2213
2214       pat = GEN_FCN (icode) (result, gen_rtx_MEM (BLKmode, src_reg),
2215                              char_rtx, GEN_INT (align));
2216       if (! pat)
2217         return 0;
2218       emit_insn (pat);
2219
2220       /* Now that we are assured of success, expand the source.  */
2221       start_sequence ();
2222       pat = memory_address (BLKmode,
2223                             expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
2224       if (pat != src_reg)
2225         emit_move_insn (src_reg, pat);
2226       pat = get_insns ();
2227       end_sequence ();
2228
2229       if (before_strlen)
2230         emit_insn_after (pat, before_strlen);
2231       else
2232         emit_insn_before (pat, get_insns ());
2233
2234       /* Return the value in the proper mode for this function.  */
2235       if (GET_MODE (result) == target_mode)
2236         target = result;
2237       else if (target != 0)
2238         convert_move (target, result, 0);
2239       else
2240         target = convert_to_mode (target_mode, result, 0);
2241
2242       return target;
2243     }
2244 }
2245
2246 /* Expand a call to the strstr builtin.  Return 0 if we failed the
2247    caller should emit a normal call, otherwise try to get the result
2248    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2249
2250 static rtx
2251 expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
2252 {
2253   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2254     return 0;
2255   else
2256     {
2257       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2258       tree fn;
2259       const char *p1, *p2;
2260
2261       p2 = c_getstr (s2);
2262       if (p2 == NULL)
2263         return 0;
2264
2265       p1 = c_getstr (s1);
2266       if (p1 != NULL)
2267         {
2268           const char *r = strstr (p1, p2);
2269
2270           if (r == NULL)
2271             return const0_rtx;
2272
2273           /* Return an offset into the constant string argument.  */
2274           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2275                                            s1, convert (TREE_TYPE (s1),
2276                                                         ssize_int (r - p1)))),
2277                               target, mode, EXPAND_NORMAL);
2278         }
2279
2280       if (p2[0] == '\0')
2281         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2282
2283       if (p2[1] != '\0')
2284         return 0;
2285
2286       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2287       if (!fn)
2288         return 0;
2289
2290       /* New argument list transforming strstr(s1, s2) to
2291          strchr(s1, s2[0]).  */
2292       arglist =
2293         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2294       arglist = tree_cons (NULL_TREE, s1, arglist);
2295       return expand_expr (build_function_call_expr (fn, arglist),
2296                           target, mode, EXPAND_NORMAL);
2297     }
2298 }
2299
2300 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2301    caller should emit a normal call, otherwise try to get the result
2302    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2303
2304 static rtx
2305 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2306 {
2307   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2308     return 0;
2309   else
2310     {
2311       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2312       const char *p1;
2313
2314       if (TREE_CODE (s2) != INTEGER_CST)
2315         return 0;
2316
2317       p1 = c_getstr (s1);
2318       if (p1 != NULL)
2319         {
2320           char c;
2321           const char *r;
2322
2323           if (target_char_cast (s2, &c))
2324             return 0;
2325
2326           r = strchr (p1, c);
2327
2328           if (r == NULL)
2329             return const0_rtx;
2330
2331           /* Return an offset into the constant string argument.  */
2332           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2333                                            s1, convert (TREE_TYPE (s1),
2334                                                         ssize_int (r - p1)))),
2335                               target, mode, EXPAND_NORMAL);
2336         }
2337
2338       /* FIXME: Should use here strchrM optab so that ports can optimize
2339          this.  */
2340       return 0;
2341     }
2342 }
2343
2344 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2345    caller should emit a normal call, otherwise try to get the result
2346    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2347
2348 static rtx
2349 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2350 {
2351   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2352     return 0;
2353   else
2354     {
2355       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2356       tree fn;
2357       const char *p1;
2358
2359       if (TREE_CODE (s2) != INTEGER_CST)
2360         return 0;
2361
2362       p1 = c_getstr (s1);
2363       if (p1 != NULL)
2364         {
2365           char c;
2366           const char *r;
2367
2368           if (target_char_cast (s2, &c))
2369             return 0;
2370
2371           r = strrchr (p1, c);
2372
2373           if (r == NULL)
2374             return const0_rtx;
2375
2376           /* Return an offset into the constant string argument.  */
2377           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2378                                            s1, convert (TREE_TYPE (s1),
2379                                                         ssize_int (r - p1)))),
2380                               target, mode, EXPAND_NORMAL);
2381         }
2382
2383       if (! integer_zerop (s2))
2384         return 0;
2385
2386       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2387       if (!fn)
2388         return 0;
2389
2390       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2391       return expand_expr (build_function_call_expr (fn, arglist),
2392                           target, mode, EXPAND_NORMAL);
2393     }
2394 }
2395
2396 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2397    caller should emit a normal call, otherwise try to get the result
2398    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2399
2400 static rtx
2401 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2402 {
2403   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2404     return 0;
2405   else
2406     {
2407       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2408       tree fn;
2409       const char *p1, *p2;
2410
2411       p2 = c_getstr (s2);
2412       if (p2 == NULL)
2413         return 0;
2414
2415       p1 = c_getstr (s1);
2416       if (p1 != NULL)
2417         {
2418           const char *r = strpbrk (p1, p2);
2419
2420           if (r == NULL)
2421             return const0_rtx;
2422
2423           /* Return an offset into the constant string argument.  */
2424           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2425                                            s1, convert (TREE_TYPE (s1),
2426                                                         ssize_int (r - p1)))),
2427                               target, mode, EXPAND_NORMAL);
2428         }
2429
2430       if (p2[0] == '\0')
2431         {
2432           /* strpbrk(x, "") == NULL.
2433              Evaluate and ignore the arguments in case they had
2434              side-effects.  */
2435           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2436           return const0_rtx;
2437         }
2438
2439       if (p2[1] != '\0')
2440         return 0;  /* Really call strpbrk.  */
2441
2442       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2443       if (!fn)
2444         return 0;
2445
2446       /* New argument list transforming strpbrk(s1, s2) to
2447          strchr(s1, s2[0]).  */
2448       arglist =
2449         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2450       arglist = tree_cons (NULL_TREE, s1, arglist);
2451       return expand_expr (build_function_call_expr (fn, arglist),
2452                           target, mode, EXPAND_NORMAL);
2453     }
2454 }
2455
2456 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2457    bytes from constant string DATA + OFFSET and return it as target
2458    constant.  */
2459
2460 static rtx
2461 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2462                          enum machine_mode mode)
2463 {
2464   const char *str = (const char *) data;
2465
2466   if (offset < 0
2467       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2468           > strlen (str) + 1))
2469     abort ();  /* Attempt to read past the end of constant string.  */
2470
2471   return c_readstr (str + offset, mode);
2472 }
2473
2474 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2475    Return 0 if we failed, the caller should emit a normal call,
2476    otherwise try to get the result in TARGET, if convenient (and in
2477    mode MODE if that's convenient).  */
2478 static rtx
2479 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2480 {
2481   if (!validate_arglist (arglist,
2482                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2483     return 0;
2484   else
2485     {
2486       tree dest = TREE_VALUE (arglist);
2487       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2488       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2489       const char *src_str;
2490       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2491       unsigned int dest_align
2492         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2493       rtx dest_mem, src_mem, dest_addr, len_rtx;
2494
2495       /* If DEST is not a pointer type, call the normal function.  */
2496       if (dest_align == 0)
2497         return 0;
2498
2499       /* If the LEN parameter is zero, return DEST.  */
2500       if (integer_zerop (len))
2501         {
2502           /* Evaluate and ignore SRC in case it has side-effects.  */
2503           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2504           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2505         }
2506
2507       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2508       if (operand_equal_p (src, dest, 0))
2509         {
2510           /* Evaluate and ignore LEN in case it has side-effects.  */
2511           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2512           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2513         }
2514
2515       /* If either SRC is not a pointer type, don't do this
2516          operation in-line.  */
2517       if (src_align == 0)
2518         return 0;
2519
2520       dest_mem = get_memory_rtx (dest);
2521       set_mem_align (dest_mem, dest_align);
2522       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2523       src_str = c_getstr (src);
2524
2525       /* If SRC is a string constant and block move would be done
2526          by pieces, we can avoid loading the string from memory
2527          and only stored the computed constants.  */
2528       if (src_str
2529           && GET_CODE (len_rtx) == CONST_INT
2530           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2531           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2532                                   (void *) src_str, dest_align))
2533         {
2534           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2535                                       builtin_memcpy_read_str,
2536                                       (void *) src_str, dest_align, 0);
2537           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2538           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2539           return dest_mem;
2540         }
2541
2542       src_mem = get_memory_rtx (src);
2543       set_mem_align (src_mem, src_align);
2544
2545       /* Copy word part most expediently.  */
2546       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2547                                    BLOCK_OP_NORMAL);
2548
2549       if (dest_addr == 0)
2550         {
2551           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2552           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2553         }
2554       return dest_addr;
2555     }
2556 }
2557
2558 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2559    Return 0 if we failed the caller should emit a normal call,
2560    otherwise try to get the result in TARGET, if convenient (and in
2561    mode MODE if that's convenient).  If ENDP is 0 return the
2562    destination pointer, if ENDP is 1 return the end pointer ala
2563    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2564    stpcpy.  */
2565
2566 static rtx
2567 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2568                         int endp)
2569 {
2570   if (!validate_arglist (arglist,
2571                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2572     return 0;
2573   /* If return value is ignored, transform mempcpy into memcpy.  */
2574   else if (target == const0_rtx)
2575     {
2576       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2577
2578       if (!fn)
2579         return 0;
2580
2581       return expand_expr (build_function_call_expr (fn, arglist),
2582                           target, mode, EXPAND_NORMAL);
2583     }
2584   else
2585     {
2586       tree dest = TREE_VALUE (arglist);
2587       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2588       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2589       const char *src_str;
2590       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2591       unsigned int dest_align
2592         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2593       rtx dest_mem, src_mem, len_rtx;
2594
2595       /* If DEST is not a pointer type, call the normal function.  */
2596       if (dest_align == 0)
2597         return 0;
2598
2599       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2600       if (operand_equal_p (src, dest, 0))
2601         {
2602           tree expr;
2603
2604           if (endp == 0)
2605             {
2606               /* Evaluate and ignore LEN in case it has side-effects.  */
2607               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2608               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2609             }
2610
2611           if (endp == 2)
2612             len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2613                                integer_one_node));
2614           len = convert (TREE_TYPE (dest), len);
2615           expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2616           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2617         }
2618
2619       /* If LEN is not constant, call the normal function.  */
2620       if (! host_integerp (len, 1))
2621         return 0;
2622   
2623       /* If the LEN parameter is zero, return DEST.  */
2624       if (tree_low_cst (len, 1) == 0)
2625         {
2626           /* Evaluate and ignore SRC in case it has side-effects.  */
2627           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2628           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2629         }
2630
2631       /* If either SRC is not a pointer type, don't do this
2632          operation in-line.  */
2633       if (src_align == 0)
2634         return 0;
2635
2636       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2637       src_str = c_getstr (src);
2638
2639       /* If SRC is a string constant and block move would be done
2640          by pieces, we can avoid loading the string from memory
2641          and only stored the computed constants.  */
2642       if (src_str
2643           && GET_CODE (len_rtx) == CONST_INT
2644           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2645           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2646                                   (void *) src_str, dest_align))
2647         {
2648           dest_mem = get_memory_rtx (dest);
2649           set_mem_align (dest_mem, dest_align);
2650           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2651                                       builtin_memcpy_read_str,
2652                                       (void *) src_str, dest_align, endp);
2653           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2654           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2655           return dest_mem;
2656         }
2657
2658       if (GET_CODE (len_rtx) == CONST_INT
2659           && can_move_by_pieces (INTVAL (len_rtx),
2660                                  MIN (dest_align, src_align)))
2661         {
2662           dest_mem = get_memory_rtx (dest);
2663           set_mem_align (dest_mem, dest_align);
2664           src_mem = get_memory_rtx (src);
2665           set_mem_align (src_mem, src_align);
2666           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2667                                      MIN (dest_align, src_align), endp);
2668           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2669           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2670           return dest_mem;
2671         }
2672
2673       return 0;
2674     }
2675 }
2676
2677 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2678    if we failed the caller should emit a normal call.  */
2679
2680 static rtx
2681 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2682 {
2683   if (!validate_arglist (arglist,
2684                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2685     return 0;
2686   else
2687     {
2688       tree dest = TREE_VALUE (arglist);
2689       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2690       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2691
2692       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2693       unsigned int dest_align
2694         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2695
2696       /* If DEST is not a pointer type, call the normal function.  */
2697       if (dest_align == 0)
2698         return 0;
2699
2700       /* If the LEN parameter is zero, return DEST.  */
2701       if (integer_zerop (len))
2702         {
2703           /* Evaluate and ignore SRC in case it has side-effects.  */
2704           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2705           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2706         }
2707
2708       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2709       if (operand_equal_p (src, dest, 0))
2710         {
2711           /* Evaluate and ignore LEN in case it has side-effects.  */
2712           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2713           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2714         }
2715
2716       /* If either SRC is not a pointer type, don't do this
2717          operation in-line.  */
2718       if (src_align == 0)
2719         return 0;
2720
2721       /* If src is categorized for a readonly section we can use
2722          normal memcpy.  */
2723       if (readonly_data_expr (src))
2724         {
2725           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2726           if (!fn)
2727             return 0;
2728           return expand_expr (build_function_call_expr (fn, arglist),
2729                               target, mode, EXPAND_NORMAL);
2730         }
2731
2732       /* Otherwise, call the normal function.  */
2733       return 0;
2734    }
2735 }
2736
2737 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2738    if we failed the caller should emit a normal call.  */
2739
2740 static rtx
2741 expand_builtin_bcopy (tree arglist)
2742 {
2743   tree src, dest, size, newarglist;
2744
2745   if (!validate_arglist (arglist,
2746                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2747     return NULL_RTX;
2748
2749   src = TREE_VALUE (arglist);
2750   dest = TREE_VALUE (TREE_CHAIN (arglist));
2751   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2752
2753   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2754      memmove(ptr y, ptr x, size_t z).   This is done this way
2755      so that if it isn't expanded inline, we fallback to
2756      calling bcopy instead of memmove.  */
2757
2758   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2759   newarglist = tree_cons (NULL_TREE, src, newarglist);
2760   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2761
2762   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2763 }
2764
2765 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2766    if we failed the caller should emit a normal call, otherwise try to get
2767    the result in TARGET, if convenient (and in mode MODE if that's
2768    convenient).  */
2769
2770 static rtx
2771 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2772 {
2773   tree fn, len, src, dst;
2774
2775   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2776     return 0;
2777
2778   src = TREE_VALUE (TREE_CHAIN (arglist));
2779   dst = TREE_VALUE (arglist);
2780
2781   /* If SRC and DST are equal (and not volatile), return DST.  */
2782   if (operand_equal_p (src, dst, 0))
2783     return expand_expr (dst, target, mode, EXPAND_NORMAL);
2784
2785   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2786   if (!fn)
2787     return 0;
2788
2789   len = c_strlen (src, 1);
2790   if (len == 0 || TREE_SIDE_EFFECTS (len))
2791     return 0;
2792
2793   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2794   arglist = build_tree_list (NULL_TREE, len);
2795   arglist = tree_cons (NULL_TREE, src, arglist);
2796   arglist = tree_cons (NULL_TREE, dst, arglist);
2797   return expand_expr (build_function_call_expr (fn, arglist),
2798                       target, mode, EXPAND_NORMAL);
2799 }
2800
2801 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2802    Return 0 if we failed the caller should emit a normal call,
2803    otherwise try to get the result in TARGET, if convenient (and in
2804    mode MODE if that's convenient).  */
2805
2806 static rtx
2807 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2808 {
2809   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2810     return 0;
2811   else
2812     {
2813       tree dst, src, len;
2814
2815       /* If return value is ignored, transform stpcpy into strcpy.  */
2816       if (target == const0_rtx)
2817         {
2818           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2819           if (!fn)
2820             return 0;
2821
2822           return expand_expr (build_function_call_expr (fn, arglist),
2823                               target, mode, EXPAND_NORMAL);
2824         }
2825
2826       /* Ensure we get an actual string whose length can be evaluated at
2827          compile-time, not an expression containing a string.  This is
2828          because the latter will potentially produce pessimized code
2829          when used to produce the return value.  */
2830       src = TREE_VALUE (TREE_CHAIN (arglist));
2831       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2832         return 0;
2833
2834       dst = TREE_VALUE (arglist);
2835       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2836       arglist = build_tree_list (NULL_TREE, len);
2837       arglist = tree_cons (NULL_TREE, src, arglist);
2838       arglist = tree_cons (NULL_TREE, dst, arglist);
2839       return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2840     }
2841 }
2842
2843 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2844    bytes from constant string DATA + OFFSET and return it as target
2845    constant.  */
2846
2847 static rtx
2848 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2849                           enum machine_mode mode)
2850 {
2851   const char *str = (const char *) data;
2852
2853   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2854     return const0_rtx;
2855
2856   return c_readstr (str + offset, mode);
2857 }
2858
2859 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2860    if we failed the caller should emit a normal call.  */
2861
2862 static rtx
2863 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2864 {
2865   if (!validate_arglist (arglist,
2866                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2867     return 0;
2868   else
2869     {
2870       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2871       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2872       tree fn;
2873
2874       /* We must be passed a constant len parameter.  */
2875       if (TREE_CODE (len) != INTEGER_CST)
2876         return 0;
2877
2878       /* If the len parameter is zero, return the dst parameter.  */
2879       if (integer_zerop (len))
2880         {
2881           /* Evaluate and ignore the src argument in case it has
2882              side-effects.  */
2883           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2884                        VOIDmode, EXPAND_NORMAL);
2885           /* Return the dst parameter.  */
2886           return expand_expr (TREE_VALUE (arglist), target, mode,
2887                               EXPAND_NORMAL);
2888         }
2889
2890       /* Now, we must be passed a constant src ptr parameter.  */
2891       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2892         return 0;
2893
2894       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2895
2896       /* We're required to pad with trailing zeros if the requested
2897          len is greater than strlen(s2)+1.  In that case try to
2898          use store_by_pieces, if it fails, punt.  */
2899       if (tree_int_cst_lt (slen, len))
2900         {
2901           tree dest = TREE_VALUE (arglist);
2902           unsigned int dest_align
2903             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2904           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2905           rtx dest_mem;
2906
2907           if (!p || dest_align == 0 || !host_integerp (len, 1)
2908               || !can_store_by_pieces (tree_low_cst (len, 1),
2909                                        builtin_strncpy_read_str,
2910                                        (void *) p, dest_align))
2911             return 0;
2912
2913           dest_mem = get_memory_rtx (dest);
2914           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2915                            builtin_strncpy_read_str,
2916                            (void *) p, dest_align, 0);
2917           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2918           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2919           return dest_mem;
2920         }
2921
2922       /* OK transform into builtin memcpy.  */
2923       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2924       if (!fn)
2925         return 0;
2926       return expand_expr (build_function_call_expr (fn, arglist),
2927                           target, mode, EXPAND_NORMAL);
2928     }
2929 }
2930
2931 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2932    bytes from constant string DATA + OFFSET and return it as target
2933    constant.  */
2934
2935 static rtx
2936 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2937                          enum machine_mode mode)
2938 {
2939   const char *c = (const char *) data;
2940   char *p = alloca (GET_MODE_SIZE (mode));
2941
2942   memset (p, *c, GET_MODE_SIZE (mode));
2943
2944   return c_readstr (p, mode);
2945 }
2946
2947 /* Callback routine for store_by_pieces.  Return the RTL of a register
2948    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2949    char value given in the RTL register data.  For example, if mode is
2950    4 bytes wide, return the RTL for 0x01010101*data.  */
2951
2952 static rtx
2953 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2954                         enum machine_mode mode)
2955 {
2956   rtx target, coeff;
2957   size_t size;
2958   char *p;
2959
2960   size = GET_MODE_SIZE (mode);
2961   if (size == 1)
2962     return (rtx) data;
2963
2964   p = alloca (size);
2965   memset (p, 1, size);
2966   coeff = c_readstr (p, mode);
2967
2968   target = convert_to_mode (mode, (rtx) data, 1);
2969   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2970   return force_reg (mode, target);
2971 }
2972
2973 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2974    if we failed the caller should emit a normal call, otherwise try to get
2975    the result in TARGET, if convenient (and in mode MODE if that's
2976    convenient).  */
2977
2978 static rtx
2979 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2980 {
2981   if (!validate_arglist (arglist,
2982                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2983     return 0;
2984   else
2985     {
2986       tree dest = TREE_VALUE (arglist);
2987       tree val = TREE_VALUE (TREE_CHAIN (arglist));
2988       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2989       char c;
2990
2991       unsigned int dest_align
2992         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2993       rtx dest_mem, dest_addr, len_rtx;
2994
2995       /* If DEST is not a pointer type, don't do this
2996          operation in-line.  */
2997       if (dest_align == 0)
2998         return 0;
2999
3000       /* If the LEN parameter is zero, return DEST.  */
3001       if (integer_zerop (len))
3002         {
3003           /* Evaluate and ignore VAL in case it has side-effects.  */
3004           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
3005           return expand_expr (dest, target, mode, EXPAND_NORMAL);
3006         }
3007
3008       if (TREE_CODE (val) != INTEGER_CST)
3009         {
3010           rtx val_rtx;
3011
3012           if (!host_integerp (len, 1))
3013             return 0;
3014
3015           if (optimize_size && tree_low_cst (len, 1) > 1)
3016             return 0;
3017
3018           /* Assume that we can memset by pieces if we can store the
3019            * the coefficients by pieces (in the required modes).
3020            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3021           c = 1;
3022           if (!can_store_by_pieces (tree_low_cst (len, 1),
3023                                     builtin_memset_read_str,
3024                                     &c, dest_align))
3025             return 0;
3026
3027           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3028           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3029           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3030                                val_rtx);
3031           dest_mem = get_memory_rtx (dest);
3032           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3033                            builtin_memset_gen_str,
3034                            val_rtx, dest_align, 0);
3035           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3036           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3037           return dest_mem;
3038         }
3039
3040       if (target_char_cast (val, &c))
3041         return 0;
3042
3043       if (c)
3044         {
3045           if (!host_integerp (len, 1))
3046             return 0;
3047           if (!can_store_by_pieces (tree_low_cst (len, 1),
3048                                     builtin_memset_read_str, &c,
3049                                     dest_align))
3050             return 0;
3051
3052           dest_mem = get_memory_rtx (dest);
3053           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3054                            builtin_memset_read_str,
3055                            &c, dest_align, 0);
3056           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3057           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3058           return dest_mem;
3059         }
3060
3061       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3062
3063       dest_mem = get_memory_rtx (dest);
3064       set_mem_align (dest_mem, dest_align);
3065       dest_addr = clear_storage (dest_mem, len_rtx);
3066
3067       if (dest_addr == 0)
3068         {
3069           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3070           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3071         }
3072
3073       return dest_addr;
3074     }
3075 }
3076
3077 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3078    if we failed the caller should emit a normal call.  */
3079
3080 static rtx
3081 expand_builtin_bzero (tree arglist)
3082 {
3083   tree dest, size, newarglist;
3084
3085   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3086     return NULL_RTX;
3087
3088   dest = TREE_VALUE (arglist);
3089   size = TREE_VALUE (TREE_CHAIN (arglist));
3090
3091   /* New argument list transforming bzero(ptr x, int y) to
3092      memset(ptr x, int 0, size_t y).   This is done this way
3093      so that if it isn't expanded inline, we fallback to
3094      calling bzero instead of memset.  */
3095
3096   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3097   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3098   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3099
3100   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3101 }
3102
3103 /* Expand expression EXP, which is a call to the memcmp built-in function.
3104    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3105    caller should emit a normal call, otherwise try to get the result in
3106    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3107
3108 static rtx
3109 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3110                        enum machine_mode mode)
3111 {
3112   tree arg1, arg2, len;
3113   const char *p1, *p2;
3114
3115   if (!validate_arglist (arglist,
3116                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3117     return 0;
3118
3119   arg1 = TREE_VALUE (arglist);
3120   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3121   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3122
3123   /* If the len parameter is zero, return zero.  */
3124   if (integer_zerop (len))
3125     {
3126       /* Evaluate and ignore arg1 and arg2 in case they have
3127          side-effects.  */
3128       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3129       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3130       return const0_rtx;
3131     }
3132
3133   /* If both arguments are equal (and not volatile), return zero.  */
3134   if (operand_equal_p (arg1, arg2, 0))
3135     {
3136       /* Evaluate and ignore len in case it has side-effects.  */
3137       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3138       return const0_rtx;
3139     }
3140
3141   p1 = c_getstr (arg1);
3142   p2 = c_getstr (arg2);
3143
3144   /* If all arguments are constant, and the value of len is not greater
3145      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3146   if (host_integerp (len, 1) && p1 && p2
3147       && compare_tree_int (len, strlen (p1) + 1) <= 0
3148       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3149     {
3150       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3151
3152       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3153     }
3154
3155   /* If len parameter is one, return an expression corresponding to
3156      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3157   if (integer_onep (len))
3158     {
3159       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3160       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3161       tree ind1 =
3162       fold (build1 (CONVERT_EXPR, integer_type_node,
3163                     build1 (INDIRECT_REF, cst_uchar_node,
3164                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3165       tree ind2 =
3166       fold (build1 (CONVERT_EXPR, integer_type_node,
3167                     build1 (INDIRECT_REF, cst_uchar_node,
3168                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3169       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3170       return expand_expr (result, target, mode, EXPAND_NORMAL);
3171     }
3172
3173 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3174   {
3175     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3176     rtx result;
3177     rtx insn;
3178
3179     int arg1_align
3180       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3181     int arg2_align
3182       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3183     enum machine_mode insn_mode;
3184
3185 #ifdef HAVE_cmpmemsi
3186     if (HAVE_cmpmemsi)
3187       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3188     else
3189 #endif
3190 #ifdef HAVE_cmpstrsi
3191     if (HAVE_cmpstrsi)
3192       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3193     else
3194 #endif
3195       return 0;     
3196
3197     /* If we don't have POINTER_TYPE, call the function.  */
3198     if (arg1_align == 0 || arg2_align == 0)
3199       return 0;
3200
3201     /* Make a place to write the result of the instruction.  */
3202     result = target;
3203     if (! (result != 0
3204            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3205            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3206       result = gen_reg_rtx (insn_mode);
3207
3208     arg1_rtx = get_memory_rtx (arg1);
3209     arg2_rtx = get_memory_rtx (arg2);
3210     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3211 #ifdef HAVE_cmpmemsi
3212     if (HAVE_cmpmemsi)
3213       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3214                            GEN_INT (MIN (arg1_align, arg2_align)));
3215     else
3216 #endif
3217 #ifdef HAVE_cmpstrsi
3218     if (HAVE_cmpstrsi)
3219       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3220                            GEN_INT (MIN (arg1_align, arg2_align)));
3221     else
3222 #endif
3223       abort ();
3224
3225     if (insn)
3226       emit_insn (insn);
3227     else
3228       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3229                                TYPE_MODE (integer_type_node), 3,
3230                                XEXP (arg1_rtx, 0), Pmode,
3231                                XEXP (arg2_rtx, 0), Pmode,
3232                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3233                                                 TREE_UNSIGNED (sizetype)),
3234                                TYPE_MODE (sizetype));
3235
3236     /* Return the value in the proper mode for this function.  */
3237     mode = TYPE_MODE (TREE_TYPE (exp));
3238     if (GET_MODE (result) == mode)
3239       return result;
3240     else if (target != 0)
3241       {
3242         convert_move (target, result, 0);
3243         return target;
3244       }
3245     else
3246       return convert_to_mode (mode, result, 0);
3247   }
3248 #endif
3249
3250   return 0;
3251 }
3252
3253 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3254    if we failed the caller should emit a normal call, otherwise try to get
3255    the result in TARGET, if convenient.  */
3256
3257 static rtx
3258 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3259 {
3260   tree arglist = TREE_OPERAND (exp, 1);
3261   tree arg1, arg2;
3262   const char *p1, *p2;
3263
3264   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3265     return 0;
3266
3267   arg1 = TREE_VALUE (arglist);
3268   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3269
3270   /* If both arguments are equal (and not volatile), return zero.  */
3271   if (operand_equal_p (arg1, arg2, 0))
3272     return const0_rtx;
3273
3274   p1 = c_getstr (arg1);
3275   p2 = c_getstr (arg2);
3276
3277   if (p1 && p2)
3278     {
3279       const int i = strcmp (p1, p2);
3280       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3281     }
3282
3283   /* If either arg is "", return an expression corresponding to
3284      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3285   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3286     {
3287       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3288       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3289       tree ind1 =
3290         fold (build1 (CONVERT_EXPR, integer_type_node,
3291                       build1 (INDIRECT_REF, cst_uchar_node,
3292                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3293       tree ind2 =
3294         fold (build1 (CONVERT_EXPR, integer_type_node,
3295                       build1 (INDIRECT_REF, cst_uchar_node,
3296                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3297       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3298       return expand_expr (result, target, mode, EXPAND_NORMAL);
3299     }
3300
3301 #ifdef HAVE_cmpstrsi
3302   if (HAVE_cmpstrsi)
3303   {
3304     tree len, len1, len2;
3305     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3306     rtx result, insn;
3307     tree fndecl;
3308
3309     int arg1_align
3310       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3311     int arg2_align
3312       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3313     enum machine_mode insn_mode
3314       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3315
3316     len1 = c_strlen (arg1, 1);
3317     len2 = c_strlen (arg2, 1);
3318
3319     if (len1)
3320       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3321     if (len2)
3322       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3323
3324     /* If we don't have a constant length for the first, use the length
3325        of the second, if we know it.  We don't require a constant for
3326        this case; some cost analysis could be done if both are available
3327        but neither is constant.  For now, assume they're equally cheap,
3328        unless one has side effects.  If both strings have constant lengths,
3329        use the smaller.  */
3330
3331     if (!len1)
3332       len = len2;
3333     else if (!len2)
3334       len = len1;
3335     else if (TREE_SIDE_EFFECTS (len1))
3336       len = len2;
3337     else if (TREE_SIDE_EFFECTS (len2))
3338       len = len1;
3339     else if (TREE_CODE (len1) != INTEGER_CST)
3340       len = len2;
3341     else if (TREE_CODE (len2) != INTEGER_CST)
3342       len = len1;
3343     else if (tree_int_cst_lt (len1, len2))
3344       len = len1;
3345     else
3346       len = len2;
3347
3348     /* If both arguments have side effects, we cannot optimize.  */
3349     if (!len || TREE_SIDE_EFFECTS (len))
3350       return 0;
3351
3352     /* If we don't have POINTER_TYPE, call the function.  */
3353     if (arg1_align == 0 || arg2_align == 0)
3354       return 0;
3355
3356     /* Make a place to write the result of the instruction.  */
3357     result = target;
3358     if (! (result != 0
3359            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3360            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3361       result = gen_reg_rtx (insn_mode);
3362
3363     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3364     arg1 = save_expr (arg1);
3365     arg2 = save_expr (arg2);
3366
3367     arg1_rtx = get_memory_rtx (arg1);
3368     arg2_rtx = get_memory_rtx (arg2);
3369     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3370     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3371                          GEN_INT (MIN (arg1_align, arg2_align)));
3372     if (insn)
3373       {
3374         emit_insn (insn);
3375
3376         /* Return the value in the proper mode for this function.  */
3377         mode = TYPE_MODE (TREE_TYPE (exp));
3378         if (GET_MODE (result) == mode)
3379           return result;
3380         if (target == 0)
3381           return convert_to_mode (mode, result, 0);
3382         convert_move (target, result, 0);
3383         return target;
3384       }
3385
3386     /* Expand the library call ourselves using a stabilized argument
3387        list to avoid re-evaluating the function's arguments twice.  */
3388     arglist = build_tree_list (NULL_TREE, arg2);
3389     arglist = tree_cons (NULL_TREE, arg1, arglist);
3390     fndecl = get_callee_fndecl (exp);
3391     exp = build_function_call_expr (fndecl, arglist);
3392     return expand_call (exp, target, target == const0_rtx);
3393   }
3394 #endif
3395   return 0;
3396 }
3397
3398 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3399    if we failed the caller should emit a normal call, otherwise try to get
3400    the result in TARGET, if convenient.  */
3401
3402 static rtx
3403 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3404 {
3405   tree arglist = TREE_OPERAND (exp, 1);
3406   tree arg1, arg2, arg3;
3407   const char *p1, *p2;
3408
3409   if (!validate_arglist (arglist,
3410                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3411     return 0;
3412
3413   arg1 = TREE_VALUE (arglist);
3414   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3415   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3416
3417   /* If the len parameter is zero, return zero.  */
3418   if (integer_zerop (arg3))
3419     {
3420       /* Evaluate and ignore arg1 and arg2 in case they have
3421          side-effects.  */
3422       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3423       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3424       return const0_rtx;
3425     }
3426
3427   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3428   if (operand_equal_p (arg1, arg2, 0))
3429     {
3430       /* Evaluate and ignore arg3 in case it has side-effects.  */
3431       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3432       return const0_rtx;
3433     }
3434
3435   p1 = c_getstr (arg1);
3436   p2 = c_getstr (arg2);
3437
3438   /* If all arguments are constant, evaluate at compile-time.  */
3439   if (host_integerp (arg3, 1) && p1 && p2)
3440     {
3441       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3442       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3443     }
3444
3445   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3446       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3447   if (host_integerp (arg3, 1)
3448       && (tree_low_cst (arg3, 1) == 1
3449           || (tree_low_cst (arg3, 1) > 1
3450               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3451     {
3452       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3453       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3454       tree ind1 =
3455         fold (build1 (CONVERT_EXPR, integer_type_node,
3456                       build1 (INDIRECT_REF, cst_uchar_node,
3457                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3458       tree ind2 =
3459         fold (build1 (CONVERT_EXPR, integer_type_node,
3460                       build1 (INDIRECT_REF, cst_uchar_node,
3461                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3462       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3463       return expand_expr (result, target, mode, EXPAND_NORMAL);
3464     }
3465
3466   /* If c_strlen can determine an expression for one of the string
3467      lengths, and it doesn't have side effects, then emit cmpstrsi
3468      using length MIN(strlen(string)+1, arg3).  */
3469 #ifdef HAVE_cmpstrsi
3470   if (HAVE_cmpstrsi)
3471   {
3472     tree len, len1, len2;
3473     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3474     rtx result, insn;
3475     tree fndecl;
3476
3477     int arg1_align
3478       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3479     int arg2_align
3480       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3481     enum machine_mode insn_mode
3482       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3483
3484     len1 = c_strlen (arg1, 1);
3485     len2 = c_strlen (arg2, 1);
3486
3487     if (len1)
3488       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3489     if (len2)
3490       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3491
3492     /* If we don't have a constant length for the first, use the length
3493        of the second, if we know it.  We don't require a constant for
3494        this case; some cost analysis could be done if both are available
3495        but neither is constant.  For now, assume they're equally cheap,
3496        unless one has side effects.  If both strings have constant lengths,
3497        use the smaller.  */
3498
3499     if (!len1)
3500       len = len2;
3501     else if (!len2)
3502       len = len1;
3503     else if (TREE_SIDE_EFFECTS (len1))
3504       len = len2;
3505     else if (TREE_SIDE_EFFECTS (len2))
3506       len = len1;
3507     else if (TREE_CODE (len1) != INTEGER_CST)
3508       len = len2;
3509     else if (TREE_CODE (len2) != INTEGER_CST)
3510       len = len1;
3511     else if (tree_int_cst_lt (len1, len2))
3512       len = len1;
3513     else
3514       len = len2;
3515
3516     /* If both arguments have side effects, we cannot optimize.  */
3517     if (!len || TREE_SIDE_EFFECTS (len))
3518       return 0;
3519
3520     /* The actual new length parameter is MIN(len,arg3).  */
3521     len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3522
3523     /* If we don't have POINTER_TYPE, call the function.  */
3524     if (arg1_align == 0 || arg2_align == 0)
3525       return 0;
3526
3527     /* Make a place to write the result of the instruction.  */
3528     result = target;
3529     if (! (result != 0
3530            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3531            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3532       result = gen_reg_rtx (insn_mode);
3533
3534     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3535     arg1 = save_expr (arg1);
3536     arg2 = save_expr (arg2);
3537     len = save_expr (len);
3538
3539     arg1_rtx = get_memory_rtx (arg1);
3540     arg2_rtx = get_memory_rtx (arg2);
3541     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3542     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3543                          GEN_INT (MIN (arg1_align, arg2_align)));
3544     if (insn)
3545       {
3546         emit_insn (insn);
3547
3548         /* Return the value in the proper mode for this function.  */
3549         mode = TYPE_MODE (TREE_TYPE (exp));
3550         if (GET_MODE (result) == mode)
3551           return result;
3552         if (target == 0)
3553           return convert_to_mode (mode, result, 0);
3554         convert_move (target, result, 0);
3555         return target;
3556       }
3557
3558     /* Expand the library call ourselves using a stabilized argument
3559        list to avoid re-evaluating the function's arguments twice.  */
3560     arglist = build_tree_list (NULL_TREE, len);
3561     arglist = tree_cons (NULL_TREE, arg2, arglist);
3562     arglist = tree_cons (NULL_TREE, arg1, arglist);
3563     fndecl = get_callee_fndecl (exp);
3564     exp = build_function_call_expr (fndecl, arglist);
3565     return expand_call (exp, target, target == const0_rtx);
3566   }
3567 #endif
3568   return 0;
3569 }
3570
3571 /* Expand expression EXP, which is a call to the strcat builtin.
3572    Return 0 if we failed the caller should emit a normal call,
3573    otherwise try to get the result in TARGET, if convenient.  */
3574
3575 static rtx
3576 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3577 {
3578   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3579     return 0;
3580   else
3581     {
3582       tree dst = TREE_VALUE (arglist),
3583         src = TREE_VALUE (TREE_CHAIN (arglist));
3584       const char *p = c_getstr (src);
3585
3586       if (p)
3587         {
3588           /* If the string length is zero, return the dst parameter.  */
3589           if (*p == '\0')
3590             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3591           else if (!optimize_size)
3592             {
3593               /* Otherwise if !optimize_size, see if we can store by
3594                  pieces into (dst + strlen(dst)).  */
3595               tree newdst, arglist,
3596                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3597               
3598               /* This is the length argument.  */
3599               arglist = build_tree_list (NULL_TREE,
3600                                          fold (size_binop (PLUS_EXPR,
3601                                                            c_strlen (src, 0),
3602                                                            ssize_int (1))));
3603               /* Prepend src argument.  */
3604               arglist = tree_cons (NULL_TREE, src, arglist);
3605               
3606               /* We're going to use dst more than once.  */
3607               dst = save_expr (dst);
3608
3609               /* Create strlen (dst).  */
3610               newdst =
3611                 fold (build_function_call_expr (strlen_fn,
3612                                                 build_tree_list (NULL_TREE,
3613                                                                  dst)));
3614               /* Create (dst + strlen (dst)).  */
3615               newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3616
3617               /* Prepend the new dst argument.  */
3618               arglist = tree_cons (NULL_TREE, newdst, arglist);
3619               
3620               /* We don't want to get turned into a memcpy if the
3621                  target is const0_rtx, i.e. when the return value
3622                  isn't used.  That would produce pessimized code so
3623                  pass in a target of zero, it should never actually be
3624                  used.  If this was successful return the original
3625                  dst, not the result of mempcpy.  */
3626               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3627                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3628               else
3629                 return 0;
3630             }
3631         }
3632
3633       return 0;
3634     }
3635 }
3636
3637 /* Expand expression EXP, which is a call to the strncat builtin.
3638    Return 0 if we failed the caller should emit a normal call,
3639    otherwise try to get the result in TARGET, if convenient.  */
3640
3641 static rtx
3642 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3643 {
3644   if (!validate_arglist (arglist,
3645                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3646     return 0;
3647   else
3648     {
3649       tree dst = TREE_VALUE (arglist),
3650         src = TREE_VALUE (TREE_CHAIN (arglist)),
3651         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3652       const char *p = c_getstr (src);
3653
3654       /* If the requested length is zero, or the src parameter string
3655           length is zero, return the dst parameter.  */
3656       if (integer_zerop (len) || (p && *p == '\0'))
3657         {
3658           /* Evaluate and ignore the src and len parameters in case
3659              they have side-effects.  */
3660           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3661           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3662           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3663         }
3664
3665       /* If the requested len is greater than or equal to the string
3666          length, call strcat.  */
3667       if (TREE_CODE (len) == INTEGER_CST && p
3668           && compare_tree_int (len, strlen (p)) >= 0)
3669         {
3670           tree newarglist
3671             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3672           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3673
3674           /* If the replacement _DECL isn't initialized, don't do the
3675              transformation.  */
3676           if (!fn)
3677             return 0;
3678
3679           return expand_expr (build_function_call_expr (fn, newarglist),
3680                               target, mode, EXPAND_NORMAL);
3681         }
3682       return 0;
3683     }
3684 }
3685
3686 /* Expand expression EXP, which is a call to the strspn builtin.
3687    Return 0 if we failed the caller should emit a normal call,
3688    otherwise try to get the result in TARGET, if convenient.  */
3689
3690 static rtx
3691 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3692 {
3693   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3694     return 0;
3695   else
3696     {
3697       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3698       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3699
3700       /* If both arguments are constants, evaluate at compile-time.  */
3701       if (p1 && p2)
3702         {
3703           const size_t r = strspn (p1, p2);
3704           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3705         }
3706
3707       /* If either argument is "", return 0.  */
3708       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3709         {
3710           /* Evaluate and ignore both arguments in case either one has
3711              side-effects.  */
3712           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3713           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3714           return const0_rtx;
3715         }
3716       return 0;
3717     }
3718 }
3719
3720 /* Expand expression EXP, which is a call to the strcspn builtin.
3721    Return 0 if we failed the caller should emit a normal call,
3722    otherwise try to get the result in TARGET, if convenient.  */
3723
3724 static rtx
3725 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3726 {
3727   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3728     return 0;
3729   else
3730     {
3731       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3732       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3733
3734       /* If both arguments are constants, evaluate at compile-time.  */
3735       if (p1 && p2)
3736         {
3737           const size_t r = strcspn (p1, p2);
3738           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3739         }
3740
3741       /* If the first argument is "", return 0.  */
3742       if (p1 && *p1 == '\0')
3743         {
3744           /* Evaluate and ignore argument s2 in case it has
3745              side-effects.  */
3746           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3747           return const0_rtx;
3748         }
3749
3750       /* If the second argument is "", return __builtin_strlen(s1).  */
3751       if (p2 && *p2 == '\0')
3752         {
3753           tree newarglist = build_tree_list (NULL_TREE, s1),
3754             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3755
3756           /* If the replacement _DECL isn't initialized, don't do the
3757              transformation.  */
3758           if (!fn)
3759             return 0;
3760
3761           return expand_expr (build_function_call_expr (fn, newarglist),
3762                               target, mode, EXPAND_NORMAL);
3763         }
3764       return 0;
3765     }
3766 }
3767
3768 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3769    if that's convenient.  */
3770
3771 rtx
3772 expand_builtin_saveregs (void)
3773 {
3774   rtx val, seq;
3775
3776   /* Don't do __builtin_saveregs more than once in a function.
3777      Save the result of the first call and reuse it.  */
3778   if (saveregs_value != 0)
3779     return saveregs_value;
3780
3781   /* When this function is called, it means that registers must be
3782      saved on entry to this function.  So we migrate the call to the
3783      first insn of this function.  */
3784
3785   start_sequence ();
3786
3787   /* Do whatever the machine needs done in this case.  */
3788   val = targetm.calls.expand_builtin_saveregs ();
3789
3790   seq = get_insns ();
3791   end_sequence ();
3792
3793   saveregs_value = val;
3794
3795   /* Put the insns after the NOTE that starts the function.  If this
3796      is inside a start_sequence, make the outer-level insn chain current, so
3797      the code is placed at the start of the function.  */
3798   push_topmost_sequence ();
3799   emit_insn_after (seq, get_insns ());
3800   pop_topmost_sequence ();
3801
3802   return val;
3803 }
3804
3805 /* __builtin_args_info (N) returns word N of the arg space info
3806    for the current function.  The number and meanings of words
3807    is controlled by the definition of CUMULATIVE_ARGS.  */
3808
3809 static rtx
3810 expand_builtin_args_info (tree arglist)
3811 {
3812   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3813   int *word_ptr = (int *) &current_function_args_info;
3814
3815   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3816     abort ();
3817
3818   if (arglist != 0)
3819     {
3820       if (!host_integerp (TREE_VALUE (arglist), 0))
3821         error ("argument of `__builtin_args_info' must be constant");
3822       else
3823         {
3824           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3825
3826           if (wordnum < 0 || wordnum >= nwords)
3827             error ("argument of `__builtin_args_info' out of range");
3828           else
3829             return GEN_INT (word_ptr[wordnum]);
3830         }
3831     }
3832   else
3833     error ("missing argument in `__builtin_args_info'");
3834
3835   return const0_rtx;
3836 }
3837
3838 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3839
3840 static rtx
3841 expand_builtin_next_arg (tree arglist)
3842 {
3843   tree fntype = TREE_TYPE (current_function_decl);
3844
3845   if (TYPE_ARG_TYPES (fntype) == 0
3846       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3847           == void_type_node))
3848     {
3849       error ("`va_start' used in function with fixed args");
3850       return const0_rtx;
3851     }
3852
3853   if (arglist)
3854     {
3855       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3856       tree arg = TREE_VALUE (arglist);
3857
3858       /* Strip off all nops for the sake of the comparison.  This
3859          is not quite the same as STRIP_NOPS.  It does more.
3860          We must also strip off INDIRECT_EXPR for C++ reference
3861          parameters.  */
3862       while (TREE_CODE (arg) == NOP_EXPR
3863              || TREE_CODE (arg) == CONVERT_EXPR
3864              || TREE_CODE (arg) == NON_LVALUE_EXPR
3865              || TREE_CODE (arg) == INDIRECT_REF)
3866         arg = TREE_OPERAND (arg, 0);
3867       if (arg != last_parm)
3868         warning ("second parameter of `va_start' not last named argument");
3869     }
3870   else
3871     /* Evidently an out of date version of <stdarg.h>; can't validate
3872        va_start's second argument, but can still work as intended.  */
3873     warning ("`__builtin_next_arg' called without an argument");
3874
3875   return expand_binop (Pmode, add_optab,
3876                        current_function_internal_arg_pointer,
3877                        current_function_arg_offset_rtx,
3878                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3879 }
3880
3881 /* Make it easier for the backends by protecting the valist argument
3882    from multiple evaluations.  */
3883
3884 static tree
3885 stabilize_va_list (tree valist, int needs_lvalue)
3886 {
3887   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3888     {
3889       if (TREE_SIDE_EFFECTS (valist))
3890         valist = save_expr (valist);
3891
3892       /* For this case, the backends will be expecting a pointer to
3893          TREE_TYPE (va_list_type_node), but it's possible we've
3894          actually been given an array (an actual va_list_type_node).
3895          So fix it.  */
3896       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3897         {
3898           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3899           tree p2 = build_pointer_type (va_list_type_node);
3900
3901           valist = build1 (ADDR_EXPR, p2, valist);
3902           valist = fold (build1 (NOP_EXPR, p1, valist));
3903         }
3904     }
3905   else
3906     {
3907       tree pt;
3908
3909       if (! needs_lvalue)
3910         {
3911           if (! TREE_SIDE_EFFECTS (valist))
3912             return valist;
3913
3914           pt = build_pointer_type (va_list_type_node);
3915           valist = fold (build1 (ADDR_EXPR, pt, valist));
3916           TREE_SIDE_EFFECTS (valist) = 1;
3917         }
3918
3919       if (TREE_SIDE_EFFECTS (valist))
3920         valist = save_expr (valist);
3921       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3922                              valist));
3923     }
3924
3925   return valist;
3926 }
3927
3928 /* The "standard" definition of va_list is void*.  */
3929
3930 tree
3931 std_build_builtin_va_list (void)
3932 {
3933   return ptr_type_node;
3934 }
3935
3936 /* The "standard" implementation of va_start: just assign `nextarg' to
3937    the variable.  */
3938
3939 void
3940 std_expand_builtin_va_start (tree valist, rtx nextarg)
3941 {
3942   tree t;
3943
3944   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3945              make_tree (ptr_type_node, nextarg));
3946   TREE_SIDE_EFFECTS (t) = 1;
3947
3948   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3949 }
3950
3951 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3952
3953 static rtx
3954 expand_builtin_va_start (tree arglist)
3955 {
3956   rtx nextarg;
3957   tree chain, valist;
3958
3959   chain = TREE_CHAIN (arglist);
3960
3961   if (TREE_CHAIN (chain))
3962     error ("too many arguments to function `va_start'");
3963
3964   nextarg = expand_builtin_next_arg (chain);
3965   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3966
3967 #ifdef EXPAND_BUILTIN_VA_START
3968   EXPAND_BUILTIN_VA_START (valist, nextarg);
3969 #else
3970   std_expand_builtin_va_start (valist, nextarg);
3971 #endif
3972
3973   return const0_rtx;
3974 }
3975
3976 /* The "standard" implementation of va_arg: read the value from the
3977    current (padded) address and increment by the (padded) size.  */
3978
3979 rtx
3980 std_expand_builtin_va_arg (tree valist, tree type)
3981 {
3982   tree addr_tree, t, type_size = NULL;
3983   tree align, alignm1;
3984   tree rounded_size;
3985   rtx addr;
3986
3987   /* Compute the rounded size of the type.  */
3988   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3989   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3990   if (type == error_mark_node
3991       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3992       || TREE_OVERFLOW (type_size))
3993     rounded_size = size_zero_node;
3994   else
3995     rounded_size = fold (build (MULT_EXPR, sizetype,
3996                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3997                                              fold (build (PLUS_EXPR, sizetype,
3998                                                           type_size, alignm1)),
3999                                              align)),
4000                                 align));
4001
4002   /* Get AP.  */
4003   addr_tree = valist;
4004   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
4005     {
4006       /* Small args are padded downward.  */
4007       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
4008                                fold (build (COND_EXPR, sizetype,
4009                                             fold (build (GT_EXPR, sizetype,
4010                                                          rounded_size,
4011                                                          align)),
4012                                             size_zero_node,
4013                                             fold (build (MINUS_EXPR, sizetype,
4014                                                          rounded_size,
4015                                                          type_size))))));
4016     }
4017
4018   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4019   addr = copy_to_reg (addr);
4020
4021   /* Compute new value for AP.  */
4022   if (! integer_zerop (rounded_size))
4023     {
4024       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4025                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
4026                         rounded_size));
4027       TREE_SIDE_EFFECTS (t) = 1;
4028       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4029     }
4030
4031   return addr;
4032 }
4033
4034 /* Expand __builtin_va_arg, which is not really a builtin function, but
4035    a very special sort of operator.  */
4036
4037 rtx
4038 expand_builtin_va_arg (tree valist, tree type)
4039 {
4040   rtx addr, result;
4041   tree promoted_type, want_va_type, have_va_type;
4042
4043   /* Verify that valist is of the proper type.  */
4044
4045   want_va_type = va_list_type_node;
4046   have_va_type = TREE_TYPE (valist);
4047   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4048     {
4049       /* If va_list is an array type, the argument may have decayed
4050          to a pointer type, e.g. by being passed to another function.
4051          In that case, unwrap both types so that we can compare the
4052          underlying records.  */
4053       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4054           || TREE_CODE (have_va_type) == POINTER_TYPE)
4055         {
4056           want_va_type = TREE_TYPE (want_va_type);
4057           have_va_type = TREE_TYPE (have_va_type);
4058         }
4059     }
4060   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4061     {
4062       error ("first argument to `va_arg' not of type `va_list'");
4063       addr = const0_rtx;
4064     }
4065
4066   /* Generate a diagnostic for requesting data of a type that cannot
4067      be passed through `...' due to type promotion at the call site.  */
4068   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4069            != type)
4070     {
4071       const char *name = "<anonymous type>", *pname = 0;
4072       static bool gave_help;
4073
4074       if (TYPE_NAME (type))
4075         {
4076           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4077             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4078           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4079                    && DECL_NAME (TYPE_NAME (type)))
4080             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4081         }
4082       if (TYPE_NAME (promoted_type))
4083         {
4084           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4085             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4086           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4087                    && DECL_NAME (TYPE_NAME (promoted_type)))
4088             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4089         }
4090
4091       /* Unfortunately, this is merely undefined, rather than a constraint
4092          violation, so we cannot make this an error.  If this call is never
4093          executed, the program is still strictly conforming.  */
4094       warning ("`%s' is promoted to `%s' when passed through `...'",
4095                name, pname);
4096       if (! gave_help)
4097         {
4098           gave_help = true;
4099           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4100                    pname, name);
4101         }
4102
4103       /* We can, however, treat "undefined" any way we please.
4104          Call abort to encourage the user to fix the program.  */
4105       expand_builtin_trap ();
4106
4107       /* This is dead code, but go ahead and finish so that the
4108          mode of the result comes out right.  */
4109       addr = const0_rtx;
4110     }
4111   else
4112     {
4113       /* Make it easier for the backends by protecting the valist argument
4114          from multiple evaluations.  */
4115       valist = stabilize_va_list (valist, 0);
4116
4117 #ifdef EXPAND_BUILTIN_VA_ARG
4118       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4119 #else
4120       addr = std_expand_builtin_va_arg (valist, type);
4121 #endif
4122     }
4123
4124   addr = convert_memory_address (Pmode, addr);
4125
4126   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4127   set_mem_alias_set (result, get_varargs_alias_set ());
4128
4129   return result;
4130 }
4131
4132 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4133
4134 static rtx
4135 expand_builtin_va_end (tree arglist)
4136 {
4137   tree valist = TREE_VALUE (arglist);
4138
4139 #ifdef EXPAND_BUILTIN_VA_END
4140   valist = stabilize_va_list (valist, 0);
4141   EXPAND_BUILTIN_VA_END (arglist);
4142 #else
4143   /* Evaluate for side effects, if needed.  I hate macros that don't
4144      do that.  */
4145   if (TREE_SIDE_EFFECTS (valist))
4146     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4147 #endif
4148
4149   return const0_rtx;
4150 }
4151
4152 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4153    builtin rather than just as an assignment in stdarg.h because of the
4154    nastiness of array-type va_list types.  */
4155
4156 static rtx
4157 expand_builtin_va_copy (tree arglist)
4158 {
4159   tree dst, src, t;
4160
4161   dst = TREE_VALUE (arglist);
4162   src = TREE_VALUE (TREE_CHAIN (arglist));
4163
4164   dst = stabilize_va_list (dst, 1);
4165   src = stabilize_va_list (src, 0);
4166
4167   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4168     {
4169       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4170       TREE_SIDE_EFFECTS (t) = 1;
4171       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4172     }
4173   else
4174     {
4175       rtx dstb, srcb, size;
4176
4177       /* Evaluate to pointers.  */
4178       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4179       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4180       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4181                           VOIDmode, EXPAND_NORMAL);
4182
4183       dstb = convert_memory_address (Pmode, dstb);
4184       srcb = convert_memory_address (Pmode, srcb);
4185
4186       /* "Dereference" to BLKmode memories.  */
4187       dstb = gen_rtx_MEM (BLKmode, dstb);
4188       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4189       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4190       srcb = gen_rtx_MEM (BLKmode, srcb);
4191       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4192       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4193
4194       /* Copy.  */
4195       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4196     }
4197
4198   return const0_rtx;
4199 }
4200
4201 /* Expand a call to one of the builtin functions __builtin_frame_address or
4202    __builtin_return_address.  */
4203
4204 static rtx
4205 expand_builtin_frame_address (tree fndecl, tree arglist)
4206 {
4207   /* The argument must be a nonnegative integer constant.
4208      It counts the number of frames to scan up the stack.
4209      The value is the return address saved in that frame.  */
4210   if (arglist == 0)
4211     /* Warning about missing arg was already issued.  */
4212     return const0_rtx;
4213   else if (! host_integerp (TREE_VALUE (arglist), 1))
4214     {
4215       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4216         error ("invalid arg to `__builtin_frame_address'");
4217       else
4218         error ("invalid arg to `__builtin_return_address'");
4219       return const0_rtx;
4220     }
4221   else
4222     {
4223       rtx tem
4224         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4225                                       tree_low_cst (TREE_VALUE (arglist), 1),
4226                                       hard_frame_pointer_rtx);
4227
4228       /* Some ports cannot access arbitrary stack frames.  */
4229       if (tem == NULL)
4230         {
4231           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4232             warning ("unsupported arg to `__builtin_frame_address'");
4233           else
4234             warning ("unsupported arg to `__builtin_return_address'");
4235           return const0_rtx;
4236         }
4237
4238       /* For __builtin_frame_address, return what we've got.  */
4239       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4240         return tem;
4241
4242       if (GET_CODE (tem) != REG
4243           && ! CONSTANT_P (tem))
4244         tem = copy_to_mode_reg (Pmode, tem);
4245       return tem;
4246     }
4247 }
4248
4249 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4250    we failed and the caller should emit a normal call, otherwise try to get
4251    the result in TARGET, if convenient.  */
4252
4253 static rtx
4254 expand_builtin_alloca (tree arglist, rtx target)
4255 {
4256   rtx op0;
4257   rtx result;
4258
4259   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4260     return 0;
4261
4262   /* Compute the argument.  */
4263   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4264
4265   /* Allocate the desired space.  */
4266   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4267   result = convert_memory_address (ptr_mode, result);
4268
4269   return result;
4270 }
4271
4272 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4273    Return 0 if a normal call should be emitted rather than expanding the
4274    function in-line.  If convenient, the result should be placed in TARGET.
4275    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4276
4277 static rtx
4278 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4279                      rtx subtarget, optab op_optab)
4280 {
4281   rtx op0;
4282   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4283     return 0;
4284
4285   /* Compute the argument.  */
4286   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4287   /* Compute op, into TARGET if possible.
4288      Set TARGET to wherever the result comes back.  */
4289   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4290                         op_optab, op0, target, 1);
4291   if (target == 0)
4292     abort ();
4293
4294   return convert_to_mode (target_mode, target, 0);
4295 }
4296
4297 /* If the string passed to fputs is a constant and is one character
4298    long, we attempt to transform this call into __builtin_fputc().  */
4299
4300 static rtx
4301 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4302 {
4303   tree len, fn;
4304   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4305     : implicit_built_in_decls[BUILT_IN_FPUTC];
4306   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4307     : implicit_built_in_decls[BUILT_IN_FWRITE];
4308
4309   /* If the return value is used, or the replacement _DECL isn't
4310      initialized, don't do the transformation.  */
4311   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4312     return 0;
4313
4314   /* Verify the arguments in the original call.  */
4315   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4316     return 0;
4317
4318   /* Get the length of the string passed to fputs.  If the length
4319      can't be determined, punt.  */
4320   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4321       || TREE_CODE (len) != INTEGER_CST)
4322     return 0;
4323
4324   switch (compare_tree_int (len, 1))
4325     {
4326     case -1: /* length is 0, delete the call entirely .  */
4327       {
4328         /* Evaluate and ignore the argument in case it has
4329            side-effects.  */
4330         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4331                      VOIDmode, EXPAND_NORMAL);
4332         return const0_rtx;
4333       }
4334     case 0: /* length is 1, call fputc.  */
4335       {
4336         const char *p = c_getstr (TREE_VALUE (arglist));
4337
4338         if (p != NULL)
4339           {
4340             /* New argument list transforming fputs(string, stream) to
4341                fputc(string[0], stream).  */
4342             arglist =
4343               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4344             arglist =
4345               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4346             fn = fn_fputc;
4347             break;
4348           }
4349       }
4350       /* FALLTHROUGH */
4351     case 1: /* length is greater than 1, call fwrite.  */
4352       {
4353         tree string_arg;
4354
4355         /* If optimizing for size keep fputs.  */
4356         if (optimize_size)
4357           return 0;
4358         string_arg = TREE_VALUE (arglist);
4359         /* New argument list transforming fputs(string, stream) to
4360            fwrite(string, 1, len, stream).  */
4361         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4362         arglist = tree_cons (NULL_TREE, len, arglist);
4363         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4364         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4365         fn = fn_fwrite;
4366         break;
4367       }
4368     default:
4369       abort ();
4370     }
4371
4372   return expand_expr (build_function_call_expr (fn, arglist),
4373                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4374 }
4375
4376 /* Expand a call to __builtin_expect.  We return our argument and emit a
4377    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4378    a non-jump context.  */
4379
4380 static rtx
4381 expand_builtin_expect (tree arglist, rtx target)
4382 {
4383   tree exp, c;
4384   rtx note, rtx_c;
4385
4386   if (arglist == NULL_TREE
4387       || TREE_CHAIN (arglist) == NULL_TREE)
4388     return const0_rtx;
4389   exp = TREE_VALUE (arglist);
4390   c = TREE_VALUE (TREE_CHAIN (arglist));
4391
4392   if (TREE_CODE (c) != INTEGER_CST)
4393     {
4394       error ("second arg to `__builtin_expect' must be a constant");
4395       c = integer_zero_node;
4396     }
4397
4398   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4399
4400   /* Don't bother with expected value notes for integral constants.  */
4401   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4402     {
4403       /* We do need to force this into a register so that we can be
4404          moderately sure to be able to correctly interpret the branch
4405          condition later.  */
4406       target = force_reg (GET_MODE (target), target);
4407
4408       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4409
4410       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4411       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4412     }
4413
4414   return target;
4415 }
4416
4417 /* Like expand_builtin_expect, except do this in a jump context.  This is
4418    called from do_jump if the conditional is a __builtin_expect.  Return either
4419    a list of insns to emit the jump or NULL if we cannot optimize
4420    __builtin_expect.  We need to optimize this at jump time so that machines
4421    like the PowerPC don't turn the test into a SCC operation, and then jump
4422    based on the test being 0/1.  */
4423
4424 rtx
4425 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4426 {
4427   tree arglist = TREE_OPERAND (exp, 1);
4428   tree arg0 = TREE_VALUE (arglist);
4429   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4430   rtx ret = NULL_RTX;
4431
4432   /* Only handle __builtin_expect (test, 0) and
4433      __builtin_expect (test, 1).  */
4434   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4435       && (integer_zerop (arg1) || integer_onep (arg1)))
4436     {
4437       int num_jumps = 0;
4438       int save_pending_stack_adjust = pending_stack_adjust;
4439       rtx insn;
4440
4441       /* If we fail to locate an appropriate conditional jump, we'll
4442          fall back to normal evaluation.  Ensure that the expression
4443          can be re-evaluated.  */
4444       switch (unsafe_for_reeval (arg0))
4445         {
4446         case 0: /* Safe.  */
4447           break;
4448
4449         case 1: /* Mildly unsafe.  */
4450           arg0 = unsave_expr (arg0);
4451           break;
4452
4453         case 2: /* Wildly unsafe.  */
4454           return NULL_RTX;
4455         }
4456
4457       /* Expand the jump insns.  */
4458       start_sequence ();
4459       do_jump (arg0, if_false_label, if_true_label);
4460       ret = get_insns ();
4461       end_sequence ();
4462
4463       /* Now that the __builtin_expect has been validated, go through and add
4464          the expect's to each of the conditional jumps.  If we run into an
4465          error, just give up and generate the 'safe' code of doing a SCC
4466          operation and then doing a branch on that.  */
4467       insn = ret;
4468       while (insn != NULL_RTX)
4469         {
4470           rtx next = NEXT_INSN (insn);
4471
4472           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4473             {
4474               rtx ifelse = SET_SRC (pc_set (insn));
4475               rtx label;
4476               int taken;
4477
4478               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4479                 {
4480                   taken = 1;
4481                   label = XEXP (XEXP (ifelse, 1), 0);
4482                 }
4483               /* An inverted jump reverses the probabilities.  */
4484               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4485                 {
4486                   taken = 0;
4487                   label = XEXP (XEXP (ifelse, 2), 0);
4488                 }
4489               /* We shouldn't have to worry about conditional returns during
4490                  the expansion stage, but handle it gracefully anyway.  */
4491               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4492                 {
4493                   taken = 1;
4494                   label = NULL_RTX;
4495                 }
4496               /* An inverted return reverses the probabilities.  */
4497               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4498                 {
4499                   taken = 0;
4500                   label = NULL_RTX;
4501                 }
4502               else
4503                 goto do_next_insn;
4504
4505               /* If the test is expected to fail, reverse the
4506                  probabilities.  */
4507               if (integer_zerop (arg1))
4508                 taken = 1 - taken;
4509
4510               /* If we are jumping to the false label, reverse the
4511                  probabilities.  */
4512               if (label == NULL_RTX)
4513                 ;               /* conditional return */
4514               else if (label == if_false_label)
4515                 taken = 1 - taken;
4516               else if (label != if_true_label)
4517                 goto do_next_insn;
4518
4519               num_jumps++;
4520               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4521             }
4522
4523         do_next_insn:
4524           insn = next;
4525         }
4526
4527       /* If no jumps were modified, fail and do __builtin_expect the normal
4528          way.  */
4529       if (num_jumps == 0)
4530         {
4531           ret = NULL_RTX;
4532           pending_stack_adjust = save_pending_stack_adjust;
4533         }
4534     }
4535
4536   return ret;
4537 }
4538
4539 void
4540 expand_builtin_trap (void)
4541 {
4542 #ifdef HAVE_trap
4543   if (HAVE_trap)
4544     emit_insn (gen_trap ());
4545   else
4546 #endif
4547     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4548   emit_barrier ();
4549 }
4550
4551 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4552    Return 0 if a normal call should be emitted rather than expanding
4553    the function inline.  If convenient, the result should be placed
4554    in TARGET.  SUBTARGET may be used as the target for computing
4555    the operand.  */
4556
4557 static rtx
4558 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4559 {
4560   enum machine_mode mode;
4561   tree arg;
4562   rtx op0;
4563
4564   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4565     return 0;
4566
4567   arg = TREE_VALUE (arglist);
4568   mode = TYPE_MODE (TREE_TYPE (arg));
4569   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4570   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4571 }
4572
4573 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4574    Return 0 if a normal call should be emitted rather than expanding
4575    the function inline.  If convenient, the result should be placed
4576    in target.  */
4577
4578 static rtx
4579 expand_builtin_cabs (tree arglist, rtx target)
4580 {
4581   enum machine_mode mode;
4582   tree arg;
4583   rtx op0;
4584
4585   if (arglist == 0 || TREE_CHAIN (arglist))
4586     return 0;
4587   arg = TREE_VALUE (arglist);
4588   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4589       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4590     return 0;
4591
4592   mode = TYPE_MODE (TREE_TYPE (arg));
4593   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4594   return expand_complex_abs (mode, op0, target, 0);
4595 }
4596
4597 /* Create a new constant string literal and return a char* pointer to it.
4598    The STRING_CST value is the LEN characters at STR.  */
4599 static tree
4600 build_string_literal (int len, const char *str)
4601 {
4602   tree t, elem, index, type;
4603
4604   t = build_string (len, str);
4605   elem = build_type_variant (char_type_node, 1, 0);
4606   index = build_index_type (build_int_2 (len - 1, 0));
4607   type = build_array_type (elem, index);
4608   TREE_TYPE (t) = type;
4609   TREE_CONSTANT (t) = 1;
4610   TREE_READONLY (t) = 1;
4611   TREE_STATIC (t) = 1;
4612
4613   type = build_pointer_type (type);
4614   t = build1 (ADDR_EXPR, type, t);
4615
4616   type = build_pointer_type (elem);
4617   t = build1 (NOP_EXPR, type, t);
4618   return t;
4619 }
4620
4621 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4622    Return 0 if a normal call should be emitted rather than transforming
4623    the function inline.  If convenient, the result should be placed in
4624    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
4625    call.  */
4626 static rtx
4627 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4628                        bool unlocked)
4629 {
4630   tree fn_putchar = unlocked
4631                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4632                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4633   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4634                           : implicit_built_in_decls[BUILT_IN_PUTS];
4635   const char *fmt_str;
4636   tree fn, fmt, arg;
4637
4638   /* If the return value is used, don't do the transformation.  */
4639   if (target != const0_rtx)
4640     return 0;
4641
4642   /* Verify the required arguments in the original call.  */
4643   if (! arglist)
4644     return 0;
4645   fmt = TREE_VALUE (arglist);
4646   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4647     return 0;
4648   arglist = TREE_CHAIN (arglist);
4649
4650   /* Check whether the format is a literal string constant.  */
4651   fmt_str = c_getstr (fmt);
4652   if (fmt_str == NULL)
4653     return 0;
4654
4655   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4656   if (strcmp (fmt_str, "%s\n") == 0)
4657     {
4658       if (! arglist
4659           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4660           || TREE_CHAIN (arglist))
4661         return 0;
4662       fn = fn_puts;
4663     }
4664   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4665   else if (strcmp (fmt_str, "%c") == 0)
4666     {
4667       if (! arglist
4668           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4669           || TREE_CHAIN (arglist))
4670         return 0;
4671       fn = fn_putchar;
4672     }
4673   else
4674     {
4675       /* We can't handle anything else with % args or %% ... yet.  */
4676       if (strchr (fmt_str, '%'))
4677         return 0;
4678
4679       if (arglist)
4680         return 0;
4681
4682       /* If the format specifier was "", printf does nothing.  */
4683       if (fmt_str[0] == '\0')
4684         return const0_rtx;
4685       /* If the format specifier has length of 1, call putchar.  */
4686       if (fmt_str[1] == '\0')
4687         {
4688           /* Given printf("c"), (where c is any one character,)
4689              convert "c"[0] to an int and pass that to the replacement
4690              function.  */
4691           arg = build_int_2 (fmt_str[0], 0);
4692           arglist = build_tree_list (NULL_TREE, arg);
4693           fn = fn_putchar;
4694         }
4695       else
4696         {
4697           /* If the format specifier was "string\n", call puts("string").  */
4698           size_t len = strlen (fmt_str);
4699           if (fmt_str[len - 1] == '\n')
4700             {
4701               /* Create a NUL-terminated string that's one char shorter
4702                  than the original, stripping off the trailing '\n'.  */
4703               char *newstr = (char *) alloca (len);
4704               memcpy (newstr, fmt_str, len - 1);
4705               newstr[len - 1] = 0;
4706
4707               arg = build_string_literal (len, newstr);
4708               arglist = build_tree_list (NULL_TREE, arg);
4709               fn = fn_puts;
4710             }
4711           else
4712             /* We'd like to arrange to call fputs(string,stdout) here,
4713                but we need stdout and don't have a way to get it yet.  */
4714             return 0;
4715         }
4716     }
4717
4718   if (!fn)
4719     return 0;
4720   return expand_expr (build_function_call_expr (fn, arglist),
4721                       target, mode, EXPAND_NORMAL);
4722 }
4723
4724 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4725    Return 0 if a normal call should be emitted rather than transforming
4726    the function inline.  If convenient, the result should be placed in
4727    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
4728    call.  */
4729 static rtx
4730 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4731                         bool unlocked)
4732 {
4733   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4734                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4735   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4736                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4737   const char *fmt_str;
4738   tree fn, fmt, fp, arg;
4739
4740   /* If the return value is used, don't do the transformation.  */
4741   if (target != const0_rtx)
4742     return 0;
4743
4744   /* Verify the required arguments in the original call.  */
4745   if (! arglist)
4746     return 0;
4747   fp = TREE_VALUE (arglist);
4748   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4749     return 0;
4750   arglist = TREE_CHAIN (arglist);
4751   if (! arglist)
4752     return 0;
4753   fmt = TREE_VALUE (arglist);
4754   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4755     return 0;
4756   arglist = TREE_CHAIN (arglist);
4757
4758   /* Check whether the format is a literal string constant.  */
4759   fmt_str = c_getstr (fmt);
4760   if (fmt_str == NULL)
4761     return 0;
4762
4763   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4764   if (strcmp (fmt_str, "%s") == 0)
4765     {
4766       if (! arglist
4767           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4768           || TREE_CHAIN (arglist))
4769         return 0;
4770       arg = TREE_VALUE (arglist);
4771       arglist = build_tree_list (NULL_TREE, fp);
4772       arglist = tree_cons (NULL_TREE, arg, arglist);
4773       fn = fn_fputs;
4774     }
4775   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4776   else if (strcmp (fmt_str, "%c") == 0)
4777     {
4778       if (! arglist
4779           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4780           || TREE_CHAIN (arglist))
4781         return 0;
4782       arg = TREE_VALUE (arglist);
4783       arglist = build_tree_list (NULL_TREE, fp);
4784       arglist = tree_cons (NULL_TREE, arg, arglist);
4785       fn = fn_fputc;
4786     }
4787   else
4788     {
4789       /* We can't handle anything else with % args or %% ... yet.  */
4790       if (strchr (fmt_str, '%'))
4791         return 0;
4792
4793       if (arglist)
4794         return 0;
4795
4796       /* If the format specifier was "", fprintf does nothing.  */
4797       if (fmt_str[0] == '\0')
4798         {
4799           /* Evaluate and ignore FILE* argument for side-effects.  */
4800           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4801           return const0_rtx;
4802         }
4803
4804       /* When "string" doesn't contain %, replace all cases of
4805          fprintf(stream,string) with fputs(string,stream).  The fputs
4806          builtin will take care of special cases like length == 1.  */
4807       arglist = build_tree_list (NULL_TREE, fp);
4808       arglist = tree_cons (NULL_TREE, fmt, arglist);
4809       fn = fn_fputs;
4810     }
4811
4812   if (!fn)
4813     return 0;
4814   return expand_expr (build_function_call_expr (fn, arglist),
4815                       target, mode, EXPAND_NORMAL);
4816 }
4817
4818 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4819    a normal call should be emitted rather than expanding the function
4820    inline.  If convenient, the result should be placed in TARGET with
4821    mode MODE.  */
4822
4823 static rtx
4824 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4825 {
4826   tree orig_arglist, dest, fmt;
4827   const char *fmt_str;
4828
4829   orig_arglist = arglist;
4830
4831   /* Verify the required arguments in the original call.  */
4832   if (! arglist)
4833     return 0;
4834   dest = TREE_VALUE (arglist);
4835   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4836     return 0;
4837   arglist = TREE_CHAIN (arglist);
4838   if (! arglist)
4839     return 0;
4840   fmt = TREE_VALUE (arglist);
4841   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4842     return 0;
4843   arglist = TREE_CHAIN (arglist);
4844
4845   /* Check whether the format is a literal string constant.  */
4846   fmt_str = c_getstr (fmt);
4847   if (fmt_str == NULL)
4848     return 0;
4849
4850   /* If the format doesn't contain % args or %%, use strcpy.  */
4851   if (strchr (fmt_str, '%') == 0)
4852     {
4853       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4854       tree exp;
4855
4856       if (arglist || ! fn)
4857         return 0;
4858       expand_expr (build_function_call_expr (fn, orig_arglist),
4859                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4860       if (target == const0_rtx)
4861         return const0_rtx;
4862       exp = build_int_2 (strlen (fmt_str), 0);
4863       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4864       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4865     }
4866   /* If the format is "%s", use strcpy if the result isn't used.  */
4867   else if (strcmp (fmt_str, "%s") == 0)
4868     {
4869       tree fn, arg, len;
4870       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4871
4872       if (! fn)
4873         return 0;
4874
4875       if (! arglist || TREE_CHAIN (arglist))
4876         return 0;
4877       arg = TREE_VALUE (arglist);
4878       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4879         return 0;
4880
4881       if (target != const0_rtx)
4882         {
4883           len = c_strlen (arg, 1);
4884           if (! len || TREE_CODE (len) != INTEGER_CST)
4885             return 0;
4886         }
4887       else
4888         len = NULL_TREE;
4889
4890       arglist = build_tree_list (NULL_TREE, arg);
4891       arglist = tree_cons (NULL_TREE, dest, arglist);
4892       expand_expr (build_function_call_expr (fn, arglist),
4893                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4894
4895       if (target == const0_rtx)
4896         return const0_rtx;
4897       return expand_expr (len, target, mode, EXPAND_NORMAL);
4898     }
4899
4900   return 0;
4901 }
4902 \f
4903 /* Expand an expression EXP that calls a built-in function,
4904    with result going to TARGET if that's convenient
4905    (and in mode MODE if that's convenient).
4906    SUBTARGET may be used as the target for computing one of EXP's operands.
4907    IGNORE is nonzero if the value is to be ignored.  */
4908
4909 rtx
4910 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4911                 int ignore)
4912 {
4913   tree fndecl = get_callee_fndecl (exp);
4914   tree arglist = TREE_OPERAND (exp, 1);
4915   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4916   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4917
4918   /* Perform postincrements before expanding builtin functions.  */
4919   emit_queue ();
4920
4921   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4922     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4923
4924   /* When not optimizing, generate calls to library functions for a certain
4925      set of builtins.  */
4926   if (!optimize
4927       && !CALLED_AS_BUILT_IN (fndecl)
4928       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4929       && fcode != BUILT_IN_ALLOCA)
4930     return expand_call (exp, target, ignore);
4931
4932   /* The built-in function expanders test for target == const0_rtx
4933      to determine whether the function's result will be ignored.  */
4934   if (ignore)
4935     target = const0_rtx;
4936
4937   /* If the result of a pure or const built-in function is ignored, and
4938      none of its arguments are volatile, we can avoid expanding the
4939      built-in call and just evaluate the arguments for side-effects.  */
4940   if (target == const0_rtx
4941       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4942     {
4943       bool volatilep = false;
4944       tree arg;
4945
4946       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4947         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4948           {
4949             volatilep = true;
4950             break;
4951           }
4952
4953       if (! volatilep)
4954         {
4955           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4956             expand_expr (TREE_VALUE (arg), const0_rtx,
4957                          VOIDmode, EXPAND_NORMAL);
4958           return const0_rtx;
4959         }
4960     }
4961
4962   switch (fcode)
4963     {
4964     case BUILT_IN_ABS:
4965     case BUILT_IN_LABS:
4966     case BUILT_IN_LLABS:
4967     case BUILT_IN_IMAXABS:
4968       /* build_function_call changes these into ABS_EXPR.  */
4969       abort ();
4970
4971     case BUILT_IN_FABS:
4972     case BUILT_IN_FABSF:
4973     case BUILT_IN_FABSL:
4974       target = expand_builtin_fabs (arglist, target, subtarget);
4975       if (target)
4976         return target;
4977       break;
4978
4979     case BUILT_IN_CABS:
4980     case BUILT_IN_CABSF:
4981     case BUILT_IN_CABSL:
4982       if (flag_unsafe_math_optimizations)
4983         {
4984           target = expand_builtin_cabs (arglist, target);
4985           if (target)
4986             return target;
4987         }
4988       break;
4989
4990     case BUILT_IN_CONJ:
4991     case BUILT_IN_CONJF:
4992     case BUILT_IN_CONJL:
4993     case BUILT_IN_CREAL:
4994     case BUILT_IN_CREALF:
4995     case BUILT_IN_CREALL:
4996     case BUILT_IN_CIMAG:
4997     case BUILT_IN_CIMAGF:
4998     case BUILT_IN_CIMAGL:
4999       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
5000          and IMAGPART_EXPR.  */
5001       abort ();
5002
5003     case BUILT_IN_SIN:
5004     case BUILT_IN_SINF:
5005     case BUILT_IN_SINL:
5006     case BUILT_IN_COS:
5007     case BUILT_IN_COSF:
5008     case BUILT_IN_COSL:
5009     case BUILT_IN_EXP:
5010     case BUILT_IN_EXPF:
5011     case BUILT_IN_EXPL:
5012     case BUILT_IN_LOG:
5013     case BUILT_IN_LOGF:
5014     case BUILT_IN_LOGL:
5015     case BUILT_IN_TAN:
5016     case BUILT_IN_TANF:
5017     case BUILT_IN_TANL:
5018     case BUILT_IN_ATAN:
5019     case BUILT_IN_ATANF:
5020     case BUILT_IN_ATANL:
5021       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5022          because of possible accuracy problems.  */
5023       if (! flag_unsafe_math_optimizations)
5024         break;
5025     case BUILT_IN_SQRT:
5026     case BUILT_IN_SQRTF:
5027     case BUILT_IN_SQRTL:
5028     case BUILT_IN_FLOOR:
5029     case BUILT_IN_FLOORF:
5030     case BUILT_IN_FLOORL:
5031     case BUILT_IN_CEIL:
5032     case BUILT_IN_CEILF:
5033     case BUILT_IN_CEILL:
5034     case BUILT_IN_TRUNC:
5035     case BUILT_IN_TRUNCF:
5036     case BUILT_IN_TRUNCL:
5037     case BUILT_IN_ROUND:
5038     case BUILT_IN_ROUNDF:
5039     case BUILT_IN_ROUNDL:
5040     case BUILT_IN_NEARBYINT:
5041     case BUILT_IN_NEARBYINTF:
5042     case BUILT_IN_NEARBYINTL:
5043       target = expand_builtin_mathfn (exp, target, subtarget);
5044       if (target)
5045         return target;
5046       break;
5047
5048     case BUILT_IN_POW:
5049     case BUILT_IN_POWF:
5050     case BUILT_IN_POWL:
5051       if (! flag_unsafe_math_optimizations)
5052         break;
5053       target = expand_builtin_pow (exp, target, subtarget);
5054       if (target)
5055         return target;
5056       break;
5057
5058     case BUILT_IN_ATAN2:
5059     case BUILT_IN_ATAN2F:
5060     case BUILT_IN_ATAN2L:
5061       if (! flag_unsafe_math_optimizations)
5062         break;
5063       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5064       if (target)
5065         return target;
5066       break;
5067
5068     case BUILT_IN_APPLY_ARGS:
5069       return expand_builtin_apply_args ();
5070
5071       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5072          FUNCTION with a copy of the parameters described by
5073          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5074          allocated on the stack into which is stored all the registers
5075          that might possibly be used for returning the result of a
5076          function.  ARGUMENTS is the value returned by
5077          __builtin_apply_args.  ARGSIZE is the number of bytes of
5078          arguments that must be copied.  ??? How should this value be
5079          computed?  We'll also need a safe worst case value for varargs
5080          functions.  */
5081     case BUILT_IN_APPLY:
5082       if (!validate_arglist (arglist, POINTER_TYPE,
5083                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5084           && !validate_arglist (arglist, REFERENCE_TYPE,
5085                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5086         return const0_rtx;
5087       else
5088         {
5089           int i;
5090           tree t;
5091           rtx ops[3];
5092
5093           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5094             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5095
5096           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5097         }
5098
5099       /* __builtin_return (RESULT) causes the function to return the
5100          value described by RESULT.  RESULT is address of the block of
5101          memory returned by __builtin_apply.  */
5102     case BUILT_IN_RETURN:
5103       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5104         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5105                                             NULL_RTX, VOIDmode, 0));
5106       return const0_rtx;
5107
5108     case BUILT_IN_SAVEREGS:
5109       return expand_builtin_saveregs ();
5110
5111     case BUILT_IN_ARGS_INFO:
5112       return expand_builtin_args_info (arglist);
5113
5114       /* Return the address of the first anonymous stack arg.  */
5115     case BUILT_IN_NEXT_ARG:
5116       return expand_builtin_next_arg (arglist);
5117
5118     case BUILT_IN_CLASSIFY_TYPE:
5119       return expand_builtin_classify_type (arglist);
5120
5121     case BUILT_IN_CONSTANT_P:
5122       return expand_builtin_constant_p (arglist, target_mode);
5123
5124     case BUILT_IN_FRAME_ADDRESS:
5125     case BUILT_IN_RETURN_ADDRESS:
5126       return expand_builtin_frame_address (fndecl, arglist);
5127
5128     /* Returns the address of the area where the structure is returned.
5129        0 otherwise.  */
5130     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5131       if (arglist != 0
5132           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5133           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5134         return const0_rtx;
5135       else
5136         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5137
5138     case BUILT_IN_ALLOCA:
5139       target = expand_builtin_alloca (arglist, target);
5140       if (target)
5141         return target;
5142       break;
5143
5144     case BUILT_IN_FFS:
5145     case BUILT_IN_FFSL:
5146     case BUILT_IN_FFSLL:
5147       target = expand_builtin_unop (target_mode, arglist, target,
5148                                     subtarget, ffs_optab);
5149       if (target)
5150         return target;
5151       break;
5152
5153     case BUILT_IN_CLZ:
5154     case BUILT_IN_CLZL:
5155     case BUILT_IN_CLZLL:
5156       target = expand_builtin_unop (target_mode, arglist, target,
5157                                     subtarget, clz_optab);
5158       if (target)
5159         return target;
5160       break;
5161
5162     case BUILT_IN_CTZ:
5163     case BUILT_IN_CTZL:
5164     case BUILT_IN_CTZLL:
5165       target = expand_builtin_unop (target_mode, arglist, target,
5166                                     subtarget, ctz_optab);
5167       if (target)
5168         return target;
5169       break;
5170
5171     case BUILT_IN_POPCOUNT:
5172     case BUILT_IN_POPCOUNTL:
5173     case BUILT_IN_POPCOUNTLL:
5174       target = expand_builtin_unop (target_mode, arglist, target,
5175                                     subtarget, popcount_optab);
5176       if (target)
5177         return target;
5178       break;
5179
5180     case BUILT_IN_PARITY:
5181     case BUILT_IN_PARITYL:
5182     case BUILT_IN_PARITYLL:
5183       target = expand_builtin_unop (target_mode, arglist, target,
5184                                     subtarget, parity_optab);
5185       if (target)
5186         return target;
5187       break;
5188
5189     case BUILT_IN_STRLEN:
5190       target = expand_builtin_strlen (arglist, target, target_mode);
5191       if (target)
5192         return target;
5193       break;
5194
5195     case BUILT_IN_STRCPY:
5196       target = expand_builtin_strcpy (arglist, target, mode);
5197       if (target)
5198         return target;
5199       break;
5200
5201     case BUILT_IN_STRNCPY:
5202       target = expand_builtin_strncpy (arglist, target, mode);
5203       if (target)
5204         return target;
5205       break;
5206
5207     case BUILT_IN_STPCPY:
5208       target = expand_builtin_stpcpy (arglist, target, mode);
5209       if (target)
5210         return target;
5211       break;
5212
5213     case BUILT_IN_STRCAT:
5214       target = expand_builtin_strcat (arglist, target, mode);
5215       if (target)
5216         return target;
5217       break;
5218
5219     case BUILT_IN_STRNCAT:
5220       target = expand_builtin_strncat (arglist, target, mode);
5221       if (target)
5222         return target;
5223       break;
5224
5225     case BUILT_IN_STRSPN:
5226       target = expand_builtin_strspn (arglist, target, mode);
5227       if (target)
5228         return target;
5229       break;
5230
5231     case BUILT_IN_STRCSPN:
5232       target = expand_builtin_strcspn (arglist, target, mode);
5233       if (target)
5234         return target;
5235       break;
5236
5237     case BUILT_IN_STRSTR:
5238       target = expand_builtin_strstr (arglist, target, mode);
5239       if (target)
5240         return target;
5241       break;
5242
5243     case BUILT_IN_STRPBRK:
5244       target = expand_builtin_strpbrk (arglist, target, mode);
5245       if (target)
5246         return target;
5247       break;
5248
5249     case BUILT_IN_INDEX:
5250     case BUILT_IN_STRCHR:
5251       target = expand_builtin_strchr (arglist, target, mode);
5252       if (target)
5253         return target;
5254       break;
5255
5256     case BUILT_IN_RINDEX:
5257     case BUILT_IN_STRRCHR:
5258       target = expand_builtin_strrchr (arglist, target, mode);
5259       if (target)
5260         return target;
5261       break;
5262
5263     case BUILT_IN_MEMCPY:
5264       target = expand_builtin_memcpy (arglist, target, mode);
5265       if (target)
5266         return target;
5267       break;
5268
5269     case BUILT_IN_MEMPCPY:
5270       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5271       if (target)
5272         return target;
5273       break;
5274
5275     case BUILT_IN_MEMMOVE:
5276       target = expand_builtin_memmove (arglist, target, mode);
5277       if (target)
5278         return target;
5279       break;
5280
5281     case BUILT_IN_BCOPY:
5282       target = expand_builtin_bcopy (arglist);
5283       if (target)
5284         return target;
5285       break;
5286
5287     case BUILT_IN_MEMSET:
5288       target = expand_builtin_memset (arglist, target, mode);
5289       if (target)
5290         return target;
5291       break;
5292
5293     case BUILT_IN_BZERO:
5294       target = expand_builtin_bzero (arglist);
5295       if (target)
5296         return target;
5297       break;
5298
5299     case BUILT_IN_STRCMP:
5300       target = expand_builtin_strcmp (exp, target, mode);
5301       if (target)
5302         return target;
5303       break;
5304
5305     case BUILT_IN_STRNCMP:
5306       target = expand_builtin_strncmp (exp, target, mode);
5307       if (target)
5308         return target;
5309       break;
5310
5311     case BUILT_IN_BCMP:
5312     case BUILT_IN_MEMCMP:
5313       target = expand_builtin_memcmp (exp, arglist, target, mode);
5314       if (target)
5315         return target;
5316       break;
5317
5318     case BUILT_IN_SETJMP:
5319       target = expand_builtin_setjmp (arglist, target);
5320       if (target)
5321         return target;
5322       break;
5323
5324       /* __builtin_longjmp is passed a pointer to an array of five words.
5325          It's similar to the C library longjmp function but works with
5326          __builtin_setjmp above.  */
5327     case BUILT_IN_LONGJMP:
5328       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5329         break;
5330       else
5331         {
5332           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5333                                       VOIDmode, 0);
5334           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5335                                    NULL_RTX, VOIDmode, 0);
5336
5337           if (value != const1_rtx)
5338             {
5339               error ("__builtin_longjmp second argument must be 1");
5340               return const0_rtx;
5341             }
5342
5343           expand_builtin_longjmp (buf_addr, value);
5344           return const0_rtx;
5345         }
5346
5347     case BUILT_IN_TRAP:
5348       expand_builtin_trap ();
5349       return const0_rtx;
5350
5351     case BUILT_IN_PRINTF:
5352       target = expand_builtin_printf (arglist, target, mode, false);
5353       if (target)
5354         return target;
5355       break;
5356
5357     case BUILT_IN_PRINTF_UNLOCKED:
5358       target = expand_builtin_printf (arglist, target, mode, true);
5359       if (target)
5360         return target;
5361       break;
5362
5363     case BUILT_IN_FPUTS:
5364       target = expand_builtin_fputs (arglist, target, false);
5365       if (target)
5366         return target;
5367       break;
5368
5369     case BUILT_IN_FPUTS_UNLOCKED:
5370       target = expand_builtin_fputs (arglist, target, true);
5371       if (target)
5372         return target;
5373       break;
5374
5375     case BUILT_IN_FPRINTF:
5376       target = expand_builtin_fprintf (arglist, target, mode, false);
5377       if (target)
5378         return target;
5379       break;
5380
5381     case BUILT_IN_FPRINTF_UNLOCKED:
5382       target = expand_builtin_fprintf (arglist, target, mode, true);
5383       if (target)
5384         return target;
5385       break;
5386
5387     case BUILT_IN_SPRINTF:
5388       target = expand_builtin_sprintf (arglist, target, mode);
5389       if (target)
5390         return target;
5391       break;
5392
5393       /* Various hooks for the DWARF 2 __throw routine.  */
5394     case BUILT_IN_UNWIND_INIT:
5395       expand_builtin_unwind_init ();
5396       return const0_rtx;
5397     case BUILT_IN_DWARF_CFA:
5398       return virtual_cfa_rtx;
5399 #ifdef DWARF2_UNWIND_INFO
5400     case BUILT_IN_DWARF_SP_COLUMN:
5401       return expand_builtin_dwarf_sp_column ();
5402     case BUILT_IN_INIT_DWARF_REG_SIZES:
5403       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5404       return const0_rtx;
5405 #endif
5406     case BUILT_IN_FROB_RETURN_ADDR:
5407       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5408     case BUILT_IN_EXTRACT_RETURN_ADDR:
5409       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5410     case BUILT_IN_EH_RETURN:
5411       expand_builtin_eh_return (TREE_VALUE (arglist),
5412                                 TREE_VALUE (TREE_CHAIN (arglist)));
5413       return const0_rtx;
5414 #ifdef EH_RETURN_DATA_REGNO
5415     case BUILT_IN_EH_RETURN_DATA_REGNO:
5416       return expand_builtin_eh_return_data_regno (arglist);
5417 #endif
5418     case BUILT_IN_VA_START:
5419     case BUILT_IN_STDARG_START:
5420       return expand_builtin_va_start (arglist);
5421     case BUILT_IN_VA_END:
5422       return expand_builtin_va_end (arglist);
5423     case BUILT_IN_VA_COPY:
5424       return expand_builtin_va_copy (arglist);
5425     case BUILT_IN_EXPECT:
5426       return expand_builtin_expect (arglist, target);
5427     case BUILT_IN_PREFETCH:
5428       expand_builtin_prefetch (arglist);
5429       return const0_rtx;
5430
5431
5432     default:    /* just do library call, if unknown builtin */
5433       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5434         error ("built-in function `%s' not currently supported",
5435                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5436     }
5437
5438   /* The switch statement above can drop through to cause the function
5439      to be called normally.  */
5440   return expand_call (exp, target, ignore);
5441 }
5442
5443 /* Determine whether a tree node represents a call to a built-in
5444    function.  If the tree T is a call to a built-in function with
5445    the right number of arguments of the appropriate types, return
5446    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5447    Otherwise the return value is END_BUILTINS.  */
5448
5449 enum built_in_function
5450 builtin_mathfn_code (tree t)
5451 {
5452   tree fndecl, arglist, parmlist;
5453   tree argtype, parmtype;
5454
5455   if (TREE_CODE (t) != CALL_EXPR
5456       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5457     return END_BUILTINS;
5458
5459   fndecl = get_callee_fndecl (t);
5460   if (fndecl == NULL_TREE
5461       || TREE_CODE (fndecl) != FUNCTION_DECL
5462       || ! DECL_BUILT_IN (fndecl)
5463       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5464     return END_BUILTINS;
5465
5466   arglist = TREE_OPERAND (t, 1);
5467   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5468   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5469     {
5470       /* If a function doesn't take a variable number of arguments,
5471          the last element in the list will have type `void'.  */
5472       parmtype = TREE_VALUE (parmlist);
5473       if (VOID_TYPE_P (parmtype))
5474         {
5475           if (arglist)
5476             return END_BUILTINS;
5477           return DECL_FUNCTION_CODE (fndecl);
5478         }
5479
5480       if (! arglist)
5481         return END_BUILTINS;
5482
5483       argtype = TREE_TYPE (TREE_VALUE (arglist));
5484
5485       if (SCALAR_FLOAT_TYPE_P (parmtype))
5486         {
5487           if (! SCALAR_FLOAT_TYPE_P (argtype))
5488             return END_BUILTINS;
5489         }
5490       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5491         {
5492           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5493             return END_BUILTINS;
5494         }
5495       else if (POINTER_TYPE_P (parmtype))
5496         {
5497           if (! POINTER_TYPE_P (argtype))
5498             return END_BUILTINS;
5499         }
5500       else if (INTEGRAL_TYPE_P (parmtype))
5501         {
5502           if (! INTEGRAL_TYPE_P (argtype))
5503             return END_BUILTINS;
5504         }
5505       else
5506         return END_BUILTINS;
5507
5508       arglist = TREE_CHAIN (arglist);
5509     }
5510
5511   /* Variable-length argument list.  */
5512   return DECL_FUNCTION_CODE (fndecl);
5513 }
5514
5515 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5516    constant.  ARGLIST is the argument list of the call.  */
5517
5518 static tree
5519 fold_builtin_constant_p (tree arglist)
5520 {
5521   if (arglist == 0)
5522     return 0;
5523
5524   arglist = TREE_VALUE (arglist);
5525
5526   /* We return 1 for a numeric type that's known to be a constant
5527      value at compile-time or for an aggregate type that's a
5528      literal constant.  */
5529   STRIP_NOPS (arglist);
5530
5531   /* If we know this is a constant, emit the constant of one.  */
5532   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5533       || (TREE_CODE (arglist) == CONSTRUCTOR
5534           && TREE_CONSTANT (arglist))
5535       || (TREE_CODE (arglist) == ADDR_EXPR
5536           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5537     return integer_one_node;
5538
5539   /* If this expression has side effects, show we don't know it to be a
5540      constant.  Likewise if it's a pointer or aggregate type since in
5541      those case we only want literals, since those are only optimized
5542      when generating RTL, not later.
5543      And finally, if we are compiling an initializer, not code, we
5544      need to return a definite result now; there's not going to be any
5545      more optimization done.  */
5546   if (TREE_SIDE_EFFECTS (arglist)
5547       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5548       || POINTER_TYPE_P (TREE_TYPE (arglist))
5549       || cfun == 0)
5550     return integer_zero_node;
5551
5552   return 0;
5553 }
5554
5555 /* Fold a call to __builtin_classify_type.  */
5556
5557 static tree
5558 fold_builtin_classify_type (tree arglist)
5559 {
5560   if (arglist == 0)
5561     return build_int_2 (no_type_class, 0);
5562
5563   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5564 }
5565
5566 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5567
5568 static tree
5569 fold_builtin_inf (tree type, int warn)
5570 {
5571   REAL_VALUE_TYPE real;
5572
5573   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5574     warning ("target format does not support infinity");
5575
5576   real_inf (&real);
5577   return build_real (type, real);
5578 }
5579
5580 /* Fold a call to __builtin_nan or __builtin_nans.  */
5581
5582 static tree
5583 fold_builtin_nan (tree arglist, tree type, int quiet)
5584 {
5585   REAL_VALUE_TYPE real;
5586   const char *str;
5587
5588   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5589     return 0;
5590   str = c_getstr (TREE_VALUE (arglist));
5591   if (!str)
5592     return 0;
5593
5594   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5595     return 0;
5596
5597   return build_real (type, real);
5598 }
5599
5600 /* Return true if the floating point expression T has an integer value.
5601    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5602
5603 static bool
5604 integer_valued_real_p (tree t)
5605 {
5606   switch (TREE_CODE (t))
5607     {
5608     case FLOAT_EXPR:
5609       return true;
5610
5611     case ABS_EXPR:
5612     case SAVE_EXPR:
5613     case NON_LVALUE_EXPR:
5614       return integer_valued_real_p (TREE_OPERAND (t, 0));
5615
5616     case COMPOUND_EXPR:
5617     case MODIFY_EXPR:
5618     case BIND_EXPR:
5619       return integer_valued_real_p (TREE_OPERAND (t, 1));
5620
5621     case PLUS_EXPR:
5622     case MINUS_EXPR:
5623     case MULT_EXPR:
5624     case MIN_EXPR:
5625     case MAX_EXPR:
5626       return integer_valued_real_p (TREE_OPERAND (t, 0))
5627              && integer_valued_real_p (TREE_OPERAND (t, 1));
5628
5629     case COND_EXPR:
5630       return integer_valued_real_p (TREE_OPERAND (t, 1))
5631              && integer_valued_real_p (TREE_OPERAND (t, 2));
5632
5633     case REAL_CST:
5634       if (! TREE_CONSTANT_OVERFLOW (t))
5635       {
5636         REAL_VALUE_TYPE c, cint;
5637
5638         c = TREE_REAL_CST (t);
5639         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5640         return real_identical (&c, &cint);
5641       }
5642
5643     case NOP_EXPR:
5644       {
5645         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5646         if (TREE_CODE (type) == INTEGER_TYPE)
5647           return true;
5648         if (TREE_CODE (type) == REAL_TYPE)
5649           return integer_valued_real_p (TREE_OPERAND (t, 0));
5650         break;
5651       }
5652
5653     case CALL_EXPR:
5654       switch (builtin_mathfn_code (t))
5655         {
5656         case BUILT_IN_CEIL:
5657         case BUILT_IN_CEILF:
5658         case BUILT_IN_CEILL:
5659         case BUILT_IN_FLOOR:
5660         case BUILT_IN_FLOORF:
5661         case BUILT_IN_FLOORL:
5662         case BUILT_IN_NEARBYINT:
5663         case BUILT_IN_NEARBYINTF:
5664         case BUILT_IN_NEARBYINTL:
5665         case BUILT_IN_ROUND:
5666         case BUILT_IN_ROUNDF:
5667         case BUILT_IN_ROUNDL:
5668         case BUILT_IN_TRUNC:
5669         case BUILT_IN_TRUNCF:
5670         case BUILT_IN_TRUNCL:
5671           return true;
5672
5673         default:
5674           break;
5675         }
5676       break;
5677
5678     default:
5679       break;
5680     }
5681   return false;
5682 }
5683
5684 /* EXP is assumed to be builtin call where truncation can be propagated
5685    across (for instance floor((double)f) == (double)floorf (f).
5686    Do the transformation.  */
5687
5688 static tree
5689 fold_trunc_transparent_mathfn (tree exp)
5690 {
5691   tree fndecl = get_callee_fndecl (exp);
5692   tree arglist = TREE_OPERAND (exp, 1);
5693   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5694   tree arg;
5695
5696   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5697     return 0;
5698
5699   arg = TREE_VALUE (arglist);
5700   /* Integer rounding functions are idempotent.  */
5701   if (fcode == builtin_mathfn_code (arg))
5702     return arg;
5703
5704   /* If argument is already integer valued, and we don't need to worry
5705      about setting errno, there's no need to perform rounding.  */
5706   if (! flag_errno_math && integer_valued_real_p (arg))
5707     return arg;
5708
5709   if (optimize)
5710     {
5711       tree arg0 = strip_float_extensions (arg);
5712       tree ftype = TREE_TYPE (exp);
5713       tree newtype = TREE_TYPE (arg0);
5714       tree decl;
5715
5716       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5717           && (decl = mathfn_built_in (newtype, fcode)))
5718         {
5719           arglist =
5720             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5721           return convert (ftype,
5722                           build_function_call_expr (decl, arglist));
5723         }
5724     }
5725   return 0;
5726 }
5727
5728 /* Fold function call to builtin cabs, cabsf or cabsl.  FNDECL is the
5729    function's DECL, ARGLIST is the argument list and TYPE is the return
5730    type.  Return NULL_TREE if no simplification can be made.  */
5731
5732 static tree
5733 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5734 {
5735   tree arg;
5736
5737   if (!arglist || TREE_CHAIN (arglist))
5738     return NULL_TREE;
5739
5740   arg = TREE_VALUE (arglist);
5741   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5742       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5743     return NULL_TREE;
5744
5745   /* Evaluate cabs of a constant at compile-time.  */
5746   if (flag_unsafe_math_optimizations
5747       && TREE_CODE (arg) == COMPLEX_CST
5748       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5749       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5750       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5751       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5752     {
5753       REAL_VALUE_TYPE r, i;
5754
5755       r = TREE_REAL_CST (TREE_REALPART (arg));
5756       i = TREE_REAL_CST (TREE_IMAGPART (arg));
5757
5758       real_arithmetic (&r, MULT_EXPR, &r, &r);
5759       real_arithmetic (&i, MULT_EXPR, &i, &i);
5760       real_arithmetic (&r, PLUS_EXPR, &r, &i);
5761       if (real_sqrt (&r, TYPE_MODE (type), &r)
5762           || ! flag_trapping_math)
5763         return build_real (type, r);
5764     }
5765
5766   /* If either part is zero, cabs is fabs of the other.  */
5767   if (TREE_CODE (arg) == COMPLEX_EXPR
5768       && real_zerop (TREE_OPERAND (arg, 0)))
5769     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5770   if (TREE_CODE (arg) == COMPLEX_EXPR
5771       && real_zerop (TREE_OPERAND (arg, 1)))
5772     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5773
5774   if (flag_unsafe_math_optimizations)
5775     {
5776       enum built_in_function fcode;
5777       tree sqrtfn;
5778
5779       fcode = DECL_FUNCTION_CODE (fndecl);
5780       if (fcode == BUILT_IN_CABS)
5781         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5782       else if (fcode == BUILT_IN_CABSF)
5783         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5784       else if (fcode == BUILT_IN_CABSL)
5785         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5786       else
5787         sqrtfn = NULL_TREE;
5788
5789       if (sqrtfn != NULL_TREE)
5790         {
5791           tree rpart, ipart, result, arglist;
5792
5793           arg = save_expr (arg);
5794
5795           rpart = fold (build1 (REALPART_EXPR, type, arg));
5796           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5797
5798           rpart = save_expr (rpart);
5799           ipart = save_expr (ipart);
5800
5801           result = fold (build (PLUS_EXPR, type,
5802                                 fold (build (MULT_EXPR, type,
5803                                              rpart, rpart)),
5804                                 fold (build (MULT_EXPR, type,
5805                                              ipart, ipart))));
5806
5807           arglist = build_tree_list (NULL_TREE, result);
5808           return build_function_call_expr (sqrtfn, arglist);
5809         }
5810     }
5811
5812   return NULL_TREE;
5813 }
5814
5815 /* Fold function call to builtin trunc, truncf or truncl.  Return
5816    NULL_TREE if no simplification can be made.  */
5817
5818 static tree
5819 fold_builtin_trunc (tree exp)
5820 {
5821   tree arglist = TREE_OPERAND (exp, 1);
5822   tree arg;
5823
5824   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5825     return 0;
5826
5827   /* Optimize trunc of constant value.  */
5828   arg = TREE_VALUE (arglist);
5829   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5830     {
5831       REAL_VALUE_TYPE r, x;
5832       tree type = TREE_TYPE (exp);
5833
5834       x = TREE_REAL_CST (arg);
5835       real_trunc (&r, TYPE_MODE (type), &x);
5836       return build_real (type, r);
5837     }
5838
5839   return fold_trunc_transparent_mathfn (exp);
5840 }
5841
5842 /* Fold function call to builtin floor, floorf or floorl.  Return
5843    NULL_TREE if no simplification can be made.  */
5844
5845 static tree
5846 fold_builtin_floor (tree exp)
5847 {
5848   tree arglist = TREE_OPERAND (exp, 1);
5849   tree arg;
5850
5851   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5852     return 0;
5853
5854   /* Optimize floor of constant value.  */
5855   arg = TREE_VALUE (arglist);
5856   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5857     {
5858       REAL_VALUE_TYPE x;
5859
5860       x = TREE_REAL_CST (arg);
5861       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5862         {
5863           tree type = TREE_TYPE (exp);
5864           REAL_VALUE_TYPE r;
5865
5866           real_floor (&r, TYPE_MODE (type), &x);
5867           return build_real (type, r);
5868         }
5869     }
5870
5871   return fold_trunc_transparent_mathfn (exp);
5872 }
5873
5874 /* Fold function call to builtin ceil, ceilf or ceill.  Return
5875    NULL_TREE if no simplification can be made.  */
5876
5877 static tree
5878 fold_builtin_ceil (tree exp)
5879 {
5880   tree arglist = TREE_OPERAND (exp, 1);
5881   tree arg;
5882
5883   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5884     return 0;
5885
5886   /* Optimize ceil of constant value.  */
5887   arg = TREE_VALUE (arglist);
5888   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5889     {
5890       REAL_VALUE_TYPE x;
5891
5892       x = TREE_REAL_CST (arg);
5893       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5894         {
5895           tree type = TREE_TYPE (exp);
5896           REAL_VALUE_TYPE r;
5897
5898           real_ceil (&r, TYPE_MODE (type), &x);
5899           return build_real (type, r);
5900         }
5901     }
5902
5903   return fold_trunc_transparent_mathfn (exp);
5904 }
5905
5906 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
5907    and their long and long long variants (i.e. ffsl and ffsll).
5908    Return NULL_TREE if no simplification can be made.  */
5909
5910 static tree
5911 fold_builtin_bitop (tree exp)
5912 {
5913   tree fndecl = get_callee_fndecl (exp);
5914   tree arglist = TREE_OPERAND (exp, 1);
5915   tree arg;
5916
5917   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
5918     return NULL_TREE;
5919
5920   /* Optimize for constant argument.  */
5921   arg = TREE_VALUE (arglist);
5922   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5923     {
5924       HOST_WIDE_INT hi, width, result;
5925       unsigned HOST_WIDE_INT lo;
5926       tree type, t;
5927
5928       type = TREE_TYPE (arg);
5929       width = TYPE_PRECISION (type);
5930       lo = TREE_INT_CST_LOW (arg);
5931
5932       /* Clear all the bits that are beyond the type's precision.  */
5933       if (width > HOST_BITS_PER_WIDE_INT)
5934         {
5935           hi = TREE_INT_CST_HIGH (arg);
5936           if (width < 2 * HOST_BITS_PER_WIDE_INT)
5937             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
5938         }
5939       else
5940         {
5941           hi = 0;
5942           if (width < HOST_BITS_PER_WIDE_INT)
5943             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
5944         }
5945
5946       switch (DECL_FUNCTION_CODE (fndecl))
5947         {
5948         case BUILT_IN_FFS:
5949         case BUILT_IN_FFSL:
5950         case BUILT_IN_FFSLL:
5951           if (lo != 0)
5952             result = exact_log2 (lo & -lo) + 1;
5953           else if (hi != 0)
5954             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
5955           else
5956             result = 0;
5957           break;
5958
5959         case BUILT_IN_CLZ:
5960         case BUILT_IN_CLZL:
5961         case BUILT_IN_CLZLL:
5962           if (hi != 0)
5963             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
5964           else if (lo != 0)
5965             result = width - floor_log2 (lo) - 1;
5966           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5967             result = width;
5968           break;
5969
5970         case BUILT_IN_CTZ:
5971         case BUILT_IN_CTZL:
5972         case BUILT_IN_CTZLL:
5973           if (lo != 0)
5974             result = exact_log2 (lo & -lo);
5975           else if (hi != 0)
5976             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
5977           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5978             result = width;
5979           break;
5980
5981         case BUILT_IN_POPCOUNT:
5982         case BUILT_IN_POPCOUNTL:
5983         case BUILT_IN_POPCOUNTLL:
5984           result = 0;
5985           while (lo)
5986             result++, lo &= lo - 1;
5987           while (hi)
5988             result++, hi &= hi - 1;
5989           break;
5990
5991         case BUILT_IN_PARITY:
5992         case BUILT_IN_PARITYL:
5993         case BUILT_IN_PARITYLL:
5994           result = 0;
5995           while (lo)
5996             result++, lo &= lo - 1;
5997           while (hi)
5998             result++, hi &= hi - 1;
5999           result &= 1;
6000           break;
6001
6002         default:
6003           abort();
6004         }
6005
6006       t = build_int_2 (result, 0);
6007       TREE_TYPE (t) = TREE_TYPE (exp);
6008       return t;
6009     }
6010
6011   return NULL_TREE;
6012 }
6013
6014 /* Return true if EXPR is the real constant contained in VALUE.  */
6015
6016 static bool
6017 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6018 {
6019   STRIP_NOPS (expr);
6020
6021   return ((TREE_CODE (expr) == REAL_CST
6022            && ! TREE_CONSTANT_OVERFLOW (expr)
6023            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6024           || (TREE_CODE (expr) == COMPLEX_CST
6025               && real_dconstp (TREE_REALPART (expr), value)
6026               && real_zerop (TREE_IMAGPART (expr))));
6027 }
6028
6029 /* A subroutine of fold_builtin to fold the various logarithmic
6030    functions.  EXP is the CALL_EXPR of a call to a builtin log*
6031    function.  VALUE is the base of the log* function.  */
6032
6033 static tree
6034 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6035 {
6036   tree arglist = TREE_OPERAND (exp, 1);
6037
6038   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6039     {
6040       tree fndecl = get_callee_fndecl (exp);
6041       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6042       tree arg = TREE_VALUE (arglist);
6043       const enum built_in_function fcode = builtin_mathfn_code (arg);
6044         
6045       /* Optimize log*(1.0) = 0.0.  */
6046       if (real_onep (arg))
6047         return build_real (type, dconst0);
6048
6049       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6050          exactly, then only do this if flag_unsafe_math_optimizations.  */
6051       if (exact_real_truncate (TYPE_MODE (type), value)
6052           || flag_unsafe_math_optimizations)
6053         {
6054           const REAL_VALUE_TYPE value_truncate =
6055             real_value_truncate (TYPE_MODE (type), *value);
6056           if (real_dconstp (arg, &value_truncate))
6057             return build_real (type, dconst1);
6058         }
6059       
6060       /* Special case, optimize logN(expN(x)) = x.  */
6061       if (flag_unsafe_math_optimizations
6062           && ((value == &dconste
6063                && (fcode == BUILT_IN_EXP
6064                    || fcode == BUILT_IN_EXPF
6065                    || fcode == BUILT_IN_EXPL))
6066               || (value == &dconst2
6067                   && (fcode == BUILT_IN_EXP2
6068                       || fcode == BUILT_IN_EXP2F
6069                       || fcode == BUILT_IN_EXP2L))
6070               || (value == &dconst10
6071                   && (fcode == BUILT_IN_EXP10
6072                       || fcode == BUILT_IN_EXP10F
6073                       || fcode == BUILT_IN_EXP10L))))
6074         return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6075
6076       /* Optimize log*(func()) for various exponential functions.  We
6077          want to determine the value "x" and the power "exponent" in
6078          order to transform logN(x**exponent) into exponent*logN(x).  */
6079       if (flag_unsafe_math_optimizations)
6080         {
6081           tree exponent = 0, x = 0;
6082           
6083           switch (fcode)
6084           {
6085           case BUILT_IN_EXP:
6086           case BUILT_IN_EXPF:
6087           case BUILT_IN_EXPL:
6088             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6089             x = build_real (type,
6090                             real_value_truncate (TYPE_MODE (type), dconste));
6091             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6092             break;
6093           case BUILT_IN_EXP2:
6094           case BUILT_IN_EXP2F:
6095           case BUILT_IN_EXP2L:
6096             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6097             x = build_real (type, dconst2);
6098             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6099             break;
6100           case BUILT_IN_EXP10:
6101           case BUILT_IN_EXP10F:
6102           case BUILT_IN_EXP10L:
6103           case BUILT_IN_POW10:
6104           case BUILT_IN_POW10F:
6105           case BUILT_IN_POW10L:
6106             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6107             x = build_real (type, dconst10);
6108             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6109             break;
6110           case BUILT_IN_SQRT:
6111           case BUILT_IN_SQRTF:
6112           case BUILT_IN_SQRTL:
6113             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6114             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6115             exponent = build_real (type, dconsthalf);
6116             break;
6117           case BUILT_IN_CBRT:
6118           case BUILT_IN_CBRTF:
6119           case BUILT_IN_CBRTL:
6120             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6121             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6122             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6123                                                               dconstthird));
6124             break;
6125           case BUILT_IN_POW:
6126           case BUILT_IN_POWF:
6127           case BUILT_IN_POWL:
6128             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6129             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6130             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6131             break;
6132           default:
6133             break;
6134           }
6135
6136           /* Now perform the optimization.  */
6137           if (x && exponent)
6138             {
6139               tree logfn;
6140               arglist = build_tree_list (NULL_TREE, x);
6141               logfn = build_function_call_expr (fndecl, arglist);
6142               return fold (build (MULT_EXPR, type, exponent, logfn));
6143             }
6144         }
6145     }
6146
6147   return 0;
6148 }
6149           
6150 /* A subroutine of fold_builtin to fold the various exponent
6151    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6152    VALUE is the value which will be raised to a power.  */
6153
6154 static tree
6155 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6156 {
6157   tree arglist = TREE_OPERAND (exp, 1);
6158
6159   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6160     {
6161       tree fndecl = get_callee_fndecl (exp);
6162       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6163       tree arg = TREE_VALUE (arglist);
6164
6165       /* Optimize exp*(0.0) = 1.0.  */
6166       if (real_zerop (arg))
6167         return build_real (type, dconst1);
6168
6169       /* Optimize expN(1.0) = N.  */
6170       if (real_onep (arg))
6171         {
6172           REAL_VALUE_TYPE cst;
6173
6174           real_convert (&cst, TYPE_MODE (type), value);
6175           return build_real (type, cst);
6176         }
6177
6178       /* Attempt to evaluate expN(integer) at compile-time.  */
6179       if (flag_unsafe_math_optimizations
6180           && TREE_CODE (arg) == REAL_CST
6181           && ! TREE_CONSTANT_OVERFLOW (arg))
6182         {
6183           REAL_VALUE_TYPE cint;
6184           REAL_VALUE_TYPE c;
6185           HOST_WIDE_INT n;
6186
6187           c = TREE_REAL_CST (arg);
6188           n = real_to_integer (&c);
6189           real_from_integer (&cint, VOIDmode, n,
6190                              n < 0 ? -1 : 0, 0);
6191           if (real_identical (&c, &cint))
6192             {
6193               REAL_VALUE_TYPE x;
6194
6195               real_powi (&x, TYPE_MODE (type), value, n);
6196               return build_real (type, x);
6197             }
6198         }
6199
6200       /* Optimize expN(logN(x)) = x.  */
6201       if (flag_unsafe_math_optimizations)
6202         {
6203           const enum built_in_function fcode = builtin_mathfn_code (arg);
6204
6205           if ((value == &dconste
6206                && (fcode == BUILT_IN_LOG
6207                    || fcode == BUILT_IN_LOGF
6208                    || fcode == BUILT_IN_LOGL))
6209               || (value == &dconst2
6210                   && (fcode == BUILT_IN_LOG2
6211                       || fcode == BUILT_IN_LOG2F
6212                       || fcode == BUILT_IN_LOG2L))
6213               || (value == &dconst10
6214                   && (fcode == BUILT_IN_LOG10
6215                       || fcode == BUILT_IN_LOG10F
6216                       || fcode == BUILT_IN_LOG10L)))
6217             return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6218         }
6219     }
6220
6221   return 0;
6222 }
6223
6224 /* Fold function call to builtin memcpy.  Return
6225    NULL_TREE if no simplification can be made.  */
6226
6227 static tree
6228 fold_builtin_memcpy (tree exp)
6229 {
6230   tree arglist = TREE_OPERAND (exp, 1);
6231   tree dest, src, len;
6232
6233   if (!validate_arglist (arglist,
6234                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6235     return 0;
6236
6237   dest = TREE_VALUE (arglist);
6238   src = TREE_VALUE (TREE_CHAIN (arglist));
6239   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6240
6241   /* If the LEN parameter is zero, return DEST.  */
6242   if (integer_zerop (len))
6243     return omit_one_operand (TREE_TYPE (exp), dest, src);
6244
6245   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6246   if (operand_equal_p (src, dest, 0))
6247     return omit_one_operand (TREE_TYPE (exp), dest, len);
6248
6249   return 0;
6250 }
6251
6252 /* Fold function call to builtin mempcpy.  Return
6253    NULL_TREE if no simplification can be made.  */
6254
6255 static tree
6256 fold_builtin_mempcpy (tree exp)
6257 {
6258   tree arglist = TREE_OPERAND (exp, 1);
6259   tree dest, src, len;
6260
6261   if (!validate_arglist (arglist,
6262                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6263     return 0;
6264
6265   dest = TREE_VALUE (arglist);
6266   src = TREE_VALUE (TREE_CHAIN (arglist));
6267   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6268
6269   /* If the LEN parameter is zero, return DEST.  */
6270   if (integer_zerop (len))
6271     return omit_one_operand (TREE_TYPE (exp), dest, src);
6272
6273   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6274   if (operand_equal_p (src, dest, 0))
6275     {
6276       tree temp = convert (TREE_TYPE (dest), len);
6277       temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6278       return convert (TREE_TYPE (exp), temp);
6279     }
6280
6281   return 0;
6282 }
6283
6284 /* Fold function call to builtin memmove.  Return
6285    NULL_TREE if no simplification can be made.  */
6286
6287 static tree
6288 fold_builtin_memmove (tree exp)
6289 {
6290   tree arglist = TREE_OPERAND (exp, 1);
6291   tree dest, src, len;
6292
6293   if (!validate_arglist (arglist,
6294                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6295     return 0;
6296
6297   dest = TREE_VALUE (arglist);
6298   src = TREE_VALUE (TREE_CHAIN (arglist));
6299   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6300
6301   /* If the LEN parameter is zero, return DEST.  */
6302   if (integer_zerop (len))
6303     return omit_one_operand (TREE_TYPE (exp), dest, src);
6304
6305   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6306   if (operand_equal_p (src, dest, 0))
6307     return omit_one_operand (TREE_TYPE (exp), dest, len);
6308
6309   return 0;
6310 }
6311
6312 /* Fold function call to builtin strcpy.  Return
6313    NULL_TREE if no simplification can be made.  */
6314
6315 static tree
6316 fold_builtin_strcpy (tree exp)
6317 {
6318   tree arglist = TREE_OPERAND (exp, 1);
6319   tree dest, src;
6320
6321   if (!validate_arglist (arglist,
6322                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6323     return 0;
6324
6325   dest = TREE_VALUE (arglist);
6326   src = TREE_VALUE (TREE_CHAIN (arglist));
6327
6328   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6329   if (operand_equal_p (src, dest, 0))
6330     return convert (TREE_TYPE (exp), dest);
6331
6332   return 0;
6333 }
6334
6335 /* Fold function call to builtin strncpy.  Return
6336    NULL_TREE if no simplification can be made.  */
6337
6338 static tree
6339 fold_builtin_strncpy (tree exp)
6340 {
6341   tree arglist = TREE_OPERAND (exp, 1);
6342   tree dest, src, len;
6343
6344   if (!validate_arglist (arglist,
6345                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6346     return 0;
6347
6348   dest = TREE_VALUE (arglist);
6349   src = TREE_VALUE (TREE_CHAIN (arglist));
6350   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6351
6352   /* If the LEN parameter is zero, return DEST.  */
6353   if (integer_zerop (len))
6354     return omit_one_operand (TREE_TYPE (exp), dest, src);
6355
6356   return 0;
6357 }
6358
6359 /* Fold function call to builtin memcmp.  Return
6360    NULL_TREE if no simplification can be made.  */
6361
6362 static tree
6363 fold_builtin_memcmp (tree exp)
6364 {
6365   tree arglist = TREE_OPERAND (exp, 1);
6366   tree arg1, arg2, len;
6367
6368   if (!validate_arglist (arglist,
6369                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6370     return 0;
6371
6372   arg1 = TREE_VALUE (arglist);
6373   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6374   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6375
6376   /* If the LEN parameter is zero, return zero.  */
6377   if (integer_zerop (len))
6378     {
6379       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6380       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6381     }
6382
6383   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6384   if (operand_equal_p (arg1, arg2, 0))
6385     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6386
6387   return 0;
6388 }
6389
6390 /* Fold function call to builtin strcmp.  Return
6391    NULL_TREE if no simplification can be made.  */
6392
6393 static tree
6394 fold_builtin_strcmp (tree exp)
6395 {
6396   tree arglist = TREE_OPERAND (exp, 1);
6397   tree arg1, arg2;
6398   const char *p1, *p2;
6399
6400   if (!validate_arglist (arglist,
6401                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6402     return 0;
6403
6404   arg1 = TREE_VALUE (arglist);
6405   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6406
6407   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6408   if (operand_equal_p (arg1, arg2, 0))
6409     return convert (TREE_TYPE (exp), integer_zero_node);
6410
6411   p1 = c_getstr (arg1);
6412   p2 = c_getstr (arg2);
6413
6414   if (p1 && p2)
6415     {
6416       tree temp;
6417       const int i = strcmp (p1, p2);
6418       if (i < 0)
6419         temp = integer_minus_one_node;
6420       else if (i > 0)
6421         temp = integer_one_node;
6422       else
6423         temp = integer_zero_node;
6424       return convert (TREE_TYPE (exp), temp);
6425     }
6426
6427   return 0;
6428 }
6429
6430 /* Fold function call to builtin strncmp.  Return
6431    NULL_TREE if no simplification can be made.  */
6432
6433 static tree
6434 fold_builtin_strncmp (tree exp)
6435 {
6436   tree arglist = TREE_OPERAND (exp, 1);
6437   tree arg1, arg2, len;
6438   const char *p1, *p2;
6439
6440   if (!validate_arglist (arglist,
6441                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6442     return 0;
6443
6444   arg1 = TREE_VALUE (arglist);
6445   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6446   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6447
6448   /* If the LEN parameter is zero, return zero.  */
6449   if (integer_zerop (len))
6450     {
6451       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6452       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6453     }
6454
6455   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6456   if (operand_equal_p (arg1, arg2, 0))
6457     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6458
6459   p1 = c_getstr (arg1);
6460   p2 = c_getstr (arg2);
6461
6462   if (host_integerp (len, 1) && p1 && p2)
6463     {
6464       tree temp;
6465       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6466       if (i < 0)
6467         temp = integer_minus_one_node;
6468       else if (i > 0)
6469         temp = integer_one_node;
6470       else
6471         temp = integer_zero_node;
6472       return convert (TREE_TYPE (exp), temp);
6473     }
6474
6475   return 0;
6476 }
6477
6478 /* Used by constant folding to eliminate some builtin calls early.  EXP is
6479    the CALL_EXPR of a call to a builtin function.  */
6480
6481 tree
6482 fold_builtin (tree exp)
6483 {
6484   tree fndecl = get_callee_fndecl (exp);
6485   tree arglist = TREE_OPERAND (exp, 1);
6486   tree type = TREE_TYPE (TREE_TYPE (fndecl));
6487
6488   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6489     return 0;
6490
6491   switch (DECL_FUNCTION_CODE (fndecl))
6492     {
6493     case BUILT_IN_CONSTANT_P:
6494       return fold_builtin_constant_p (arglist);
6495
6496     case BUILT_IN_CLASSIFY_TYPE:
6497       return fold_builtin_classify_type (arglist);
6498
6499     case BUILT_IN_STRLEN:
6500       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6501         {
6502           tree len = c_strlen (TREE_VALUE (arglist), 0);
6503           if (len)
6504             {
6505               /* Convert from the internal "sizetype" type to "size_t".  */
6506               if (size_type_node)
6507                 len = convert (size_type_node, len);
6508               return len;
6509             }
6510         }
6511       break;
6512
6513     case BUILT_IN_FABS:
6514     case BUILT_IN_FABSF:
6515     case BUILT_IN_FABSL:
6516       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6517         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6518       break;
6519
6520     case BUILT_IN_CABS:
6521     case BUILT_IN_CABSF:
6522     case BUILT_IN_CABSL:
6523       return fold_builtin_cabs (fndecl, arglist, type);
6524
6525     case BUILT_IN_SQRT:
6526     case BUILT_IN_SQRTF:
6527     case BUILT_IN_SQRTL:
6528       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6529         {
6530           enum built_in_function fcode;
6531           tree arg = TREE_VALUE (arglist);
6532
6533           /* Optimize sqrt of constant value.  */
6534           if (TREE_CODE (arg) == REAL_CST
6535               && ! TREE_CONSTANT_OVERFLOW (arg))
6536             {
6537               REAL_VALUE_TYPE r, x;
6538
6539               x = TREE_REAL_CST (arg);
6540               if (real_sqrt (&r, TYPE_MODE (type), &x)
6541                   || (!flag_trapping_math && !flag_errno_math))
6542                 return build_real (type, r);
6543             }
6544
6545           /* Optimize sqrt(exp(x)) = exp(x*0.5).  */
6546           fcode = builtin_mathfn_code (arg);
6547           if (flag_unsafe_math_optimizations
6548               && (fcode == BUILT_IN_EXP
6549                   || fcode == BUILT_IN_EXPF
6550                   || fcode == BUILT_IN_EXPL))
6551             {
6552               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6553               arg = fold (build (MULT_EXPR, type,
6554                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
6555                                  build_real (type, dconsthalf)));
6556               arglist = build_tree_list (NULL_TREE, arg);
6557               return build_function_call_expr (expfn, arglist);
6558             }
6559
6560           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6561           if (flag_unsafe_math_optimizations
6562               && (fcode == BUILT_IN_POW
6563                   || fcode == BUILT_IN_POWF
6564                   || fcode == BUILT_IN_POWL))
6565             {
6566               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6567               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6568               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6569               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6570                                         build_real (type, dconsthalf)));
6571               arglist = tree_cons (NULL_TREE, arg0,
6572                                    build_tree_list (NULL_TREE, narg1));
6573               return build_function_call_expr (powfn, arglist);
6574             }
6575         }
6576       break;
6577
6578     case BUILT_IN_SIN:
6579     case BUILT_IN_SINF:
6580     case BUILT_IN_SINL:
6581       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6582         {
6583           tree arg = TREE_VALUE (arglist);
6584
6585           /* Optimize sin(0.0) = 0.0.  */
6586           if (real_zerop (arg))
6587             return arg;
6588         }
6589       break;
6590
6591     case BUILT_IN_COS:
6592     case BUILT_IN_COSF:
6593     case BUILT_IN_COSL:
6594       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6595         {
6596           tree arg = TREE_VALUE (arglist);
6597
6598           /* Optimize cos(0.0) = 1.0.  */
6599           if (real_zerop (arg))
6600             return build_real (type, dconst1);
6601
6602           /* Optimize cos(-x) into cos(x).  */
6603           if (TREE_CODE (arg) == NEGATE_EXPR)
6604             {
6605               tree arglist = build_tree_list (NULL_TREE,
6606                                               TREE_OPERAND (arg, 0));
6607               return build_function_call_expr (fndecl, arglist);
6608             }
6609         }
6610       break;
6611
6612     case BUILT_IN_EXP:
6613     case BUILT_IN_EXPF:
6614     case BUILT_IN_EXPL:
6615       return fold_builtin_exponent (exp, &dconste);
6616     case BUILT_IN_EXP2:
6617     case BUILT_IN_EXP2F:
6618     case BUILT_IN_EXP2L:
6619       return fold_builtin_exponent (exp, &dconst2);
6620     case BUILT_IN_EXP10:
6621     case BUILT_IN_EXP10F:
6622     case BUILT_IN_EXP10L:
6623     case BUILT_IN_POW10:
6624     case BUILT_IN_POW10F:
6625     case BUILT_IN_POW10L:
6626       return fold_builtin_exponent (exp, &dconst10);
6627     case BUILT_IN_LOG:
6628     case BUILT_IN_LOGF:
6629     case BUILT_IN_LOGL:
6630       return fold_builtin_logarithm (exp, &dconste);
6631       break;
6632     case BUILT_IN_LOG2:
6633     case BUILT_IN_LOG2F:
6634     case BUILT_IN_LOG2L:
6635       return fold_builtin_logarithm (exp, &dconst2);
6636       break;
6637     case BUILT_IN_LOG10:
6638     case BUILT_IN_LOG10F:
6639     case BUILT_IN_LOG10L:
6640       return fold_builtin_logarithm (exp, &dconst10);
6641       break;
6642
6643     case BUILT_IN_TAN:
6644     case BUILT_IN_TANF:
6645     case BUILT_IN_TANL:
6646       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6647         {
6648           enum built_in_function fcode;
6649           tree arg = TREE_VALUE (arglist);
6650
6651           /* Optimize tan(0.0) = 0.0.  */
6652           if (real_zerop (arg))
6653             return arg;
6654
6655           /* Optimize tan(atan(x)) = x.  */
6656           fcode = builtin_mathfn_code (arg);
6657           if (flag_unsafe_math_optimizations
6658               && (fcode == BUILT_IN_ATAN
6659                   || fcode == BUILT_IN_ATANF
6660                   || fcode == BUILT_IN_ATANL))
6661             return TREE_VALUE (TREE_OPERAND (arg, 1));
6662         }
6663       break;
6664
6665     case BUILT_IN_ATAN:
6666     case BUILT_IN_ATANF:
6667     case BUILT_IN_ATANL:
6668       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6669         {
6670           tree arg = TREE_VALUE (arglist);
6671
6672           /* Optimize atan(0.0) = 0.0.  */
6673           if (real_zerop (arg))
6674             return arg;
6675
6676           /* Optimize atan(1.0) = pi/4.  */
6677           if (real_onep (arg))
6678             {
6679               REAL_VALUE_TYPE cst;
6680
6681               real_convert (&cst, TYPE_MODE (type), &dconstpi);
6682               cst.exp -= 2;
6683               return build_real (type, cst);
6684             }
6685         }
6686       break;
6687
6688     case BUILT_IN_POW:
6689     case BUILT_IN_POWF:
6690     case BUILT_IN_POWL:
6691       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6692         {
6693           enum built_in_function fcode;
6694           tree arg0 = TREE_VALUE (arglist);
6695           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6696
6697           /* Optimize pow(1.0,y) = 1.0.  */
6698           if (real_onep (arg0))
6699             return omit_one_operand (type, build_real (type, dconst1), arg1);
6700
6701           if (TREE_CODE (arg1) == REAL_CST
6702               && ! TREE_CONSTANT_OVERFLOW (arg1))
6703             {
6704               REAL_VALUE_TYPE c;
6705               c = TREE_REAL_CST (arg1);
6706
6707               /* Optimize pow(x,0.0) = 1.0.  */
6708               if (REAL_VALUES_EQUAL (c, dconst0))
6709                 return omit_one_operand (type, build_real (type, dconst1),
6710                                          arg0);
6711
6712               /* Optimize pow(x,1.0) = x.  */
6713               if (REAL_VALUES_EQUAL (c, dconst1))
6714                 return arg0;
6715
6716               /* Optimize pow(x,-1.0) = 1.0/x.  */
6717               if (REAL_VALUES_EQUAL (c, dconstm1))
6718                 return fold (build (RDIV_EXPR, type,
6719                                     build_real (type, dconst1),
6720                                     arg0));
6721
6722               /* Optimize pow(x,0.5) = sqrt(x).  */
6723               if (flag_unsafe_math_optimizations
6724                   && REAL_VALUES_EQUAL (c, dconsthalf))
6725                 {
6726                   tree sqrtfn;
6727
6728                   fcode = DECL_FUNCTION_CODE (fndecl);
6729                   if (fcode == BUILT_IN_POW)
6730                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6731                   else if (fcode == BUILT_IN_POWF)
6732                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6733                   else if (fcode == BUILT_IN_POWL)
6734                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6735                   else
6736                     sqrtfn = NULL_TREE;
6737
6738                   if (sqrtfn != NULL_TREE)
6739                     {
6740                       tree arglist = build_tree_list (NULL_TREE, arg0);
6741                       return build_function_call_expr (sqrtfn, arglist);
6742                     }
6743                 }
6744
6745               /* Attempt to evaluate pow at compile-time.  */
6746               if (TREE_CODE (arg0) == REAL_CST
6747                   && ! TREE_CONSTANT_OVERFLOW (arg0))
6748                 {
6749                   REAL_VALUE_TYPE cint;
6750                   HOST_WIDE_INT n;
6751
6752                   n = real_to_integer (&c);
6753                   real_from_integer (&cint, VOIDmode, n,
6754                                      n < 0 ? -1 : 0, 0);
6755                   if (real_identical (&c, &cint))
6756                     {
6757                       REAL_VALUE_TYPE x;
6758                       bool inexact;
6759
6760                       x = TREE_REAL_CST (arg0);
6761                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6762                       if (flag_unsafe_math_optimizations || !inexact)
6763                         return build_real (type, x);
6764                     }
6765                 }
6766             }
6767
6768           /* Optimize pow(exp(x),y) = exp(x*y).  */
6769           fcode = builtin_mathfn_code (arg0);
6770           if (flag_unsafe_math_optimizations
6771               && (fcode == BUILT_IN_EXP
6772                   || fcode == BUILT_IN_EXPF
6773                   || fcode == BUILT_IN_EXPL))
6774             {
6775               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6776               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6777               arg = fold (build (MULT_EXPR, type, arg, arg1));
6778               arglist = build_tree_list (NULL_TREE, arg);
6779               return build_function_call_expr (expfn, arglist);
6780             }
6781
6782           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6783           if (flag_unsafe_math_optimizations
6784               && (fcode == BUILT_IN_SQRT
6785                   || fcode == BUILT_IN_SQRTF
6786                   || fcode == BUILT_IN_SQRTL))
6787             {
6788               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6789               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6790                                         build_real (type, dconsthalf)));
6791
6792               arglist = tree_cons (NULL_TREE, narg0,
6793                                    build_tree_list (NULL_TREE, narg1));
6794               return build_function_call_expr (fndecl, arglist);
6795             }
6796
6797           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6798           if (flag_unsafe_math_optimizations
6799               && (fcode == BUILT_IN_POW
6800                   || fcode == BUILT_IN_POWF
6801                   || fcode == BUILT_IN_POWL))
6802             {
6803               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6804               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6805               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6806               arglist = tree_cons (NULL_TREE, arg00,
6807                                    build_tree_list (NULL_TREE, narg1));
6808               return build_function_call_expr (fndecl, arglist);
6809             }
6810         }
6811       break;
6812
6813     case BUILT_IN_INF:
6814     case BUILT_IN_INFF:
6815     case BUILT_IN_INFL:
6816       return fold_builtin_inf (type, true);
6817
6818     case BUILT_IN_HUGE_VAL:
6819     case BUILT_IN_HUGE_VALF:
6820     case BUILT_IN_HUGE_VALL:
6821       return fold_builtin_inf (type, false);
6822
6823     case BUILT_IN_NAN:
6824     case BUILT_IN_NANF:
6825     case BUILT_IN_NANL:
6826       return fold_builtin_nan (arglist, type, true);
6827
6828     case BUILT_IN_NANS:
6829     case BUILT_IN_NANSF:
6830     case BUILT_IN_NANSL:
6831       return fold_builtin_nan (arglist, type, false);
6832
6833     case BUILT_IN_FLOOR:
6834     case BUILT_IN_FLOORF:
6835     case BUILT_IN_FLOORL:
6836       return fold_builtin_floor (exp);
6837
6838     case BUILT_IN_CEIL:
6839     case BUILT_IN_CEILF:
6840     case BUILT_IN_CEILL:
6841       return fold_builtin_ceil (exp);
6842
6843     case BUILT_IN_TRUNC:
6844     case BUILT_IN_TRUNCF:
6845     case BUILT_IN_TRUNCL:
6846       return fold_builtin_trunc (exp);
6847
6848     case BUILT_IN_ROUND:
6849     case BUILT_IN_ROUNDF:
6850     case BUILT_IN_ROUNDL:
6851     case BUILT_IN_NEARBYINT:
6852     case BUILT_IN_NEARBYINTF:
6853     case BUILT_IN_NEARBYINTL:
6854       return fold_trunc_transparent_mathfn (exp);
6855
6856     case BUILT_IN_FFS:
6857     case BUILT_IN_FFSL:
6858     case BUILT_IN_FFSLL:
6859     case BUILT_IN_CLZ:
6860     case BUILT_IN_CLZL:
6861     case BUILT_IN_CLZLL:
6862     case BUILT_IN_CTZ:
6863     case BUILT_IN_CTZL:
6864     case BUILT_IN_CTZLL:
6865     case BUILT_IN_POPCOUNT:
6866     case BUILT_IN_POPCOUNTL:
6867     case BUILT_IN_POPCOUNTLL:
6868     case BUILT_IN_PARITY:
6869     case BUILT_IN_PARITYL:
6870     case BUILT_IN_PARITYLL:
6871       return fold_builtin_bitop (exp);
6872
6873     case BUILT_IN_MEMCPY:
6874       return fold_builtin_memcpy (exp);
6875
6876     case BUILT_IN_MEMPCPY:
6877       return fold_builtin_mempcpy (exp);
6878
6879     case BUILT_IN_MEMMOVE:
6880       return fold_builtin_memmove (exp);
6881
6882     case BUILT_IN_STRCPY:
6883       return fold_builtin_strcpy (exp);
6884
6885     case BUILT_IN_STRNCPY:
6886       return fold_builtin_strncpy (exp);
6887
6888     case BUILT_IN_MEMCMP:
6889       return fold_builtin_memcmp (exp);
6890
6891     case BUILT_IN_STRCMP:
6892       return fold_builtin_strcmp (exp);
6893
6894     case BUILT_IN_STRNCMP:
6895       return fold_builtin_strncmp (exp);
6896
6897     default:
6898       break;
6899     }
6900
6901   return 0;
6902 }
6903
6904 /* Conveniently construct a function call expression.  */
6905
6906 tree
6907 build_function_call_expr (tree fn, tree arglist)
6908 {
6909   tree call_expr;
6910
6911   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6912   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6913                      call_expr, arglist);
6914   return fold (call_expr);
6915 }
6916
6917 /* This function validates the types of a function call argument list
6918    represented as a tree chain of parameters against a specified list
6919    of tree_codes.  If the last specifier is a 0, that represents an
6920    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
6921
6922 static int
6923 validate_arglist (tree arglist, ...)
6924 {
6925   enum tree_code code;
6926   int res = 0;
6927   va_list ap;
6928
6929   va_start (ap, arglist);
6930
6931   do
6932     {
6933       code = va_arg (ap, enum tree_code);
6934       switch (code)
6935         {
6936         case 0:
6937           /* This signifies an ellipses, any further arguments are all ok.  */
6938           res = 1;
6939           goto end;
6940         case VOID_TYPE:
6941           /* This signifies an endlink, if no arguments remain, return
6942              true, otherwise return false.  */
6943           res = arglist == 0;
6944           goto end;
6945         default:
6946           /* If no parameters remain or the parameter's code does not
6947              match the specified code, return false.  Otherwise continue
6948              checking any remaining arguments.  */
6949           if (arglist == 0
6950               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6951             goto end;
6952           break;
6953         }
6954       arglist = TREE_CHAIN (arglist);
6955     }
6956   while (1);
6957
6958   /* We need gotos here since we can only have one VA_CLOSE in a
6959      function.  */
6960  end: ;
6961   va_end (ap);
6962
6963   return res;
6964 }
6965
6966 /* Default target-specific builtin expander that does nothing.  */
6967
6968 rtx
6969 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6970                         rtx target ATTRIBUTE_UNUSED,
6971                         rtx subtarget ATTRIBUTE_UNUSED,
6972                         enum machine_mode mode ATTRIBUTE_UNUSED,
6973                         int ignore ATTRIBUTE_UNUSED)
6974 {
6975   return NULL_RTX;
6976 }
6977
6978 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
6979
6980 void
6981 purge_builtin_constant_p (void)
6982 {
6983   rtx insn, set, arg, new, note;
6984
6985   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6986     if (INSN_P (insn)
6987         && (set = single_set (insn)) != NULL_RTX
6988         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6989             || (GET_CODE (arg) == SUBREG
6990                 && (GET_CODE (arg = SUBREG_REG (arg))
6991                     == CONSTANT_P_RTX))))
6992       {
6993         arg = XEXP (arg, 0);
6994         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6995         validate_change (insn, &SET_SRC (set), new, 0);
6996
6997         /* Remove the REG_EQUAL note from the insn.  */
6998         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6999           remove_note (insn, note);
7000       }
7001 }
7002
7003 /* Returns true is EXP represents data that would potentially reside
7004    in a readonly section.  */
7005
7006 static bool
7007 readonly_data_expr (tree exp)
7008 {
7009   STRIP_NOPS (exp);
7010
7011   if (TREE_CODE (exp) == ADDR_EXPR)
7012     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
7013   else
7014     return false;
7015 }