OSDN Git Service

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