OSDN Git Service

* config/i386/i386.c (ix86_expand_prologue): Use
[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, ssize_int (r - p1))),
2265                               target, mode, EXPAND_NORMAL);
2266         }
2267
2268       if (p2[0] == '\0')
2269         return expand_expr (s1, target, mode, EXPAND_NORMAL);
2270
2271       if (p2[1] != '\0')
2272         return 0;
2273
2274       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2275       if (!fn)
2276         return 0;
2277
2278       /* New argument list transforming strstr(s1, s2) to
2279          strchr(s1, s2[0]).  */
2280       arglist =
2281         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2282       arglist = tree_cons (NULL_TREE, s1, arglist);
2283       return expand_expr (build_function_call_expr (fn, arglist),
2284                           target, mode, EXPAND_NORMAL);
2285     }
2286 }
2287
2288 /* Expand a call to the strchr builtin.  Return 0 if we failed the
2289    caller should emit a normal call, otherwise try to get the result
2290    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2291
2292 static rtx
2293 expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
2294 {
2295   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2296     return 0;
2297   else
2298     {
2299       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2300       const char *p1;
2301
2302       if (TREE_CODE (s2) != INTEGER_CST)
2303         return 0;
2304
2305       p1 = c_getstr (s1);
2306       if (p1 != NULL)
2307         {
2308           char c;
2309           const char *r;
2310
2311           if (target_char_cast (s2, &c))
2312             return 0;
2313
2314           r = strchr (p1, c);
2315
2316           if (r == NULL)
2317             return const0_rtx;
2318
2319           /* Return an offset into the constant string argument.  */
2320           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2321                                            s1, ssize_int (r - p1))),
2322                               target, mode, EXPAND_NORMAL);
2323         }
2324
2325       /* FIXME: Should use here strchrM optab so that ports can optimize
2326          this.  */
2327       return 0;
2328     }
2329 }
2330
2331 /* Expand a call to the strrchr builtin.  Return 0 if we failed the
2332    caller should emit a normal call, otherwise try to get the result
2333    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2334
2335 static rtx
2336 expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
2337 {
2338   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2339     return 0;
2340   else
2341     {
2342       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2343       tree fn;
2344       const char *p1;
2345
2346       if (TREE_CODE (s2) != INTEGER_CST)
2347         return 0;
2348
2349       p1 = c_getstr (s1);
2350       if (p1 != NULL)
2351         {
2352           char c;
2353           const char *r;
2354
2355           if (target_char_cast (s2, &c))
2356             return 0;
2357
2358           r = strrchr (p1, c);
2359
2360           if (r == NULL)
2361             return const0_rtx;
2362
2363           /* Return an offset into the constant string argument.  */
2364           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2365                                            s1, ssize_int (r - p1))),
2366                               target, mode, EXPAND_NORMAL);
2367         }
2368
2369       if (! integer_zerop (s2))
2370         return 0;
2371
2372       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2373       if (!fn)
2374         return 0;
2375
2376       /* Transform strrchr(s1, '\0') to strchr(s1, '\0').  */
2377       return expand_expr (build_function_call_expr (fn, arglist),
2378                           target, mode, EXPAND_NORMAL);
2379     }
2380 }
2381
2382 /* Expand a call to the strpbrk builtin.  Return 0 if we failed the
2383    caller should emit a normal call, otherwise try to get the result
2384    in TARGET, if convenient (and in mode MODE if that's convenient).  */
2385
2386 static rtx
2387 expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
2388 {
2389   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2390     return 0;
2391   else
2392     {
2393       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
2394       tree fn;
2395       const char *p1, *p2;
2396
2397       p2 = c_getstr (s2);
2398       if (p2 == NULL)
2399         return 0;
2400
2401       p1 = c_getstr (s1);
2402       if (p1 != NULL)
2403         {
2404           const char *r = strpbrk (p1, p2);
2405
2406           if (r == NULL)
2407             return const0_rtx;
2408
2409           /* Return an offset into the constant string argument.  */
2410           return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
2411                                            s1, ssize_int (r - p1))),
2412                               target, mode, EXPAND_NORMAL);
2413         }
2414
2415       if (p2[0] == '\0')
2416         {
2417           /* strpbrk(x, "") == NULL.
2418              Evaluate and ignore the arguments in case they had
2419              side-effects.  */
2420           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
2421           return const0_rtx;
2422         }
2423
2424       if (p2[1] != '\0')
2425         return 0;  /* Really call strpbrk.  */
2426
2427       fn = implicit_built_in_decls[BUILT_IN_STRCHR];
2428       if (!fn)
2429         return 0;
2430
2431       /* New argument list transforming strpbrk(s1, s2) to
2432          strchr(s1, s2[0]).  */
2433       arglist =
2434         build_tree_list (NULL_TREE, build_int_2 (p2[0], 0));
2435       arglist = tree_cons (NULL_TREE, s1, arglist);
2436       return expand_expr (build_function_call_expr (fn, arglist),
2437                           target, mode, EXPAND_NORMAL);
2438     }
2439 }
2440
2441 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2442    bytes from constant string DATA + OFFSET and return it as target
2443    constant.  */
2444
2445 static rtx
2446 builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
2447                          enum machine_mode mode)
2448 {
2449   const char *str = (const char *) data;
2450
2451   if (offset < 0
2452       || ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
2453           > strlen (str) + 1))
2454     abort ();  /* Attempt to read past the end of constant string.  */
2455
2456   return c_readstr (str + offset, mode);
2457 }
2458
2459 /* Expand a call to the memcpy builtin, with arguments in ARGLIST.
2460    Return 0 if we failed, the caller should emit a normal call,
2461    otherwise try to get the result in TARGET, if convenient (and in
2462    mode MODE if that's convenient).  */
2463 static rtx
2464 expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
2465 {
2466   if (!validate_arglist (arglist,
2467                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2468     return 0;
2469   else
2470     {
2471       tree dest = TREE_VALUE (arglist);
2472       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2473       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2474       const char *src_str;
2475       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2476       unsigned int dest_align
2477         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2478       rtx dest_mem, src_mem, dest_addr, len_rtx;
2479
2480       /* If DEST is not a pointer type, call the normal function.  */
2481       if (dest_align == 0)
2482         return 0;
2483
2484       /* If the LEN parameter is zero, return DEST.  */
2485       if (integer_zerop (len))
2486         {
2487           /* Evaluate and ignore SRC in case it has side-effects.  */
2488           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2489           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2490         }
2491
2492       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2493       if (operand_equal_p (src, dest, 0))
2494         {
2495           /* Evaluate and ignore LEN in case it has side-effects.  */
2496           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2497           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2498         }
2499
2500       /* If either SRC is not a pointer type, don't do this
2501          operation in-line.  */
2502       if (src_align == 0)
2503         return 0;
2504
2505       dest_mem = get_memory_rtx (dest);
2506       set_mem_align (dest_mem, dest_align);
2507       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2508       src_str = c_getstr (src);
2509
2510       /* If SRC is a string constant and block move would be done
2511          by pieces, we can avoid loading the string from memory
2512          and only stored the computed constants.  */
2513       if (src_str
2514           && GET_CODE (len_rtx) == CONST_INT
2515           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2516           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2517                                   (void *) src_str, dest_align))
2518         {
2519           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2520                                       builtin_memcpy_read_str,
2521                                       (void *) src_str, dest_align, 0);
2522           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2523           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2524           return dest_mem;
2525         }
2526
2527       src_mem = get_memory_rtx (src);
2528       set_mem_align (src_mem, src_align);
2529
2530       /* Copy word part most expediently.  */
2531       dest_addr = emit_block_move (dest_mem, src_mem, len_rtx,
2532                                    BLOCK_OP_NORMAL);
2533
2534       if (dest_addr == 0)
2535         {
2536           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2537           dest_addr = convert_memory_address (ptr_mode, dest_addr);
2538         }
2539       return dest_addr;
2540     }
2541 }
2542
2543 /* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
2544    Return 0 if we failed the caller should emit a normal call,
2545    otherwise try to get the result in TARGET, if convenient (and in
2546    mode MODE if that's convenient).  If ENDP is 0 return the
2547    destination pointer, if ENDP is 1 return the end pointer ala
2548    mempcpy, and if ENDP is 2 return the end pointer minus one ala
2549    stpcpy.  */
2550
2551 static rtx
2552 expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
2553                         int endp)
2554 {
2555   if (!validate_arglist (arglist,
2556                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2557     return 0;
2558   /* If return value is ignored, transform mempcpy into memcpy.  */
2559   else if (target == const0_rtx)
2560     {
2561       tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2562
2563       if (!fn)
2564         return 0;
2565
2566       return expand_expr (build_function_call_expr (fn, arglist),
2567                           target, mode, EXPAND_NORMAL);
2568     }
2569   else
2570     {
2571       tree dest = TREE_VALUE (arglist);
2572       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2573       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2574       const char *src_str;
2575       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2576       unsigned int dest_align
2577         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2578       rtx dest_mem, src_mem, len_rtx;
2579
2580       /* If DEST is not a pointer type, call the normal function.  */
2581       if (dest_align == 0)
2582         return 0;
2583
2584       /* If SRC and DEST are the same (and not volatile), do nothing.  */
2585       if (operand_equal_p (src, dest, 0))
2586         {
2587           tree expr;
2588
2589           if (endp == 0)
2590             {
2591               /* Evaluate and ignore LEN in case it has side-effects.  */
2592               expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2593               return expand_expr (dest, target, mode, EXPAND_NORMAL);
2594             }
2595
2596           if (endp == 2)
2597             len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
2598                                integer_one_node));
2599           len = convert (TREE_TYPE (dest), len);
2600           expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
2601           return expand_expr (expr, target, mode, EXPAND_NORMAL);
2602         }
2603
2604       /* If LEN is not constant, call the normal function.  */
2605       if (! host_integerp (len, 1))
2606         return 0;
2607   
2608       /* If the LEN parameter is zero, return DEST.  */
2609       if (tree_low_cst (len, 1) == 0)
2610         {
2611           /* Evaluate and ignore SRC in case it has side-effects.  */
2612           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2613           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2614         }
2615
2616       /* If either SRC is not a pointer type, don't do this
2617          operation in-line.  */
2618       if (src_align == 0)
2619         return 0;
2620
2621       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
2622       src_str = c_getstr (src);
2623
2624       /* If SRC is a string constant and block move would be done
2625          by pieces, we can avoid loading the string from memory
2626          and only stored the computed constants.  */
2627       if (src_str
2628           && GET_CODE (len_rtx) == CONST_INT
2629           && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
2630           && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
2631                                   (void *) src_str, dest_align))
2632         {
2633           dest_mem = get_memory_rtx (dest);
2634           set_mem_align (dest_mem, dest_align);
2635           dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
2636                                       builtin_memcpy_read_str,
2637                                       (void *) src_str, dest_align, endp);
2638           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2639           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2640           return dest_mem;
2641         }
2642
2643       if (GET_CODE (len_rtx) == CONST_INT
2644           && can_move_by_pieces (INTVAL (len_rtx),
2645                                  MIN (dest_align, src_align)))
2646         {
2647           dest_mem = get_memory_rtx (dest);
2648           set_mem_align (dest_mem, dest_align);
2649           src_mem = get_memory_rtx (src);
2650           set_mem_align (src_mem, src_align);
2651           dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
2652                                      MIN (dest_align, src_align), endp);
2653           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2654           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2655           return dest_mem;
2656         }
2657
2658       return 0;
2659     }
2660 }
2661
2662 /* Expand expression EXP, which is a call to the memmove builtin.  Return 0
2663    if we failed the caller should emit a normal call.  */
2664
2665 static rtx
2666 expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
2667 {
2668   if (!validate_arglist (arglist,
2669                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2670     return 0;
2671   else
2672     {
2673       tree dest = TREE_VALUE (arglist);
2674       tree src = TREE_VALUE (TREE_CHAIN (arglist));
2675       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2676
2677       unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
2678       unsigned int dest_align
2679         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2680
2681       /* If DEST is not a pointer type, call the normal function.  */
2682       if (dest_align == 0)
2683         return 0;
2684
2685       /* If the LEN parameter is zero, return DEST.  */
2686       if (integer_zerop (len))
2687         {
2688           /* Evaluate and ignore SRC in case it has side-effects.  */
2689           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
2690           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2691         }
2692
2693       /* If SRC and DEST are the same (and not volatile), return DEST.  */
2694       if (operand_equal_p (src, dest, 0))
2695         {
2696           /* Evaluate and ignore LEN in case it has side-effects.  */
2697           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
2698           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2699         }
2700
2701       /* If either SRC is not a pointer type, don't do this
2702          operation in-line.  */
2703       if (src_align == 0)
2704         return 0;
2705
2706       /* If src is categorized for a readonly section we can use
2707          normal memcpy.  */
2708       if (readonly_data_expr (src))
2709         {
2710           tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2711           if (!fn)
2712             return 0;
2713           return expand_expr (build_function_call_expr (fn, arglist),
2714                               target, mode, EXPAND_NORMAL);
2715         }
2716
2717       /* Otherwise, call the normal function.  */
2718       return 0;
2719    }
2720 }
2721
2722 /* Expand expression EXP, which is a call to the bcopy builtin.  Return 0
2723    if we failed the caller should emit a normal call.  */
2724
2725 static rtx
2726 expand_builtin_bcopy (tree arglist)
2727 {
2728   tree src, dest, size, newarglist;
2729
2730   if (!validate_arglist (arglist,
2731                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2732     return NULL_RTX;
2733
2734   src = TREE_VALUE (arglist);
2735   dest = TREE_VALUE (TREE_CHAIN (arglist));
2736   size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2737
2738   /* New argument list transforming bcopy(ptr x, ptr y, int z) to
2739      memmove(ptr y, ptr x, size_t z).   This is done this way
2740      so that if it isn't expanded inline, we fallback to
2741      calling bcopy instead of memmove.  */
2742
2743   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
2744   newarglist = tree_cons (NULL_TREE, src, newarglist);
2745   newarglist = tree_cons (NULL_TREE, dest, newarglist);
2746
2747   return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
2748 }
2749
2750 /* Expand expression EXP, which is a call to the strcpy builtin.  Return 0
2751    if we failed the caller should emit a normal call, otherwise try to get
2752    the result in TARGET, if convenient (and in mode MODE if that's
2753    convenient).  */
2754
2755 static rtx
2756 expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
2757 {
2758   tree fn, len, src, dst;
2759
2760   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2761     return 0;
2762
2763   src = TREE_VALUE (TREE_CHAIN (arglist));
2764   dst = TREE_VALUE (arglist);
2765
2766   /* If SRC and DST are equal (and not volatile), return DST.  */
2767   if (operand_equal_p (src, dst, 0))
2768     return expand_expr (dst, target, mode, EXPAND_NORMAL);
2769
2770   fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2771   if (!fn)
2772     return 0;
2773
2774   len = c_strlen (src, 1);
2775   if (len == 0 || TREE_SIDE_EFFECTS (len))
2776     return 0;
2777
2778   len = size_binop (PLUS_EXPR, len, ssize_int (1));
2779   arglist = build_tree_list (NULL_TREE, len);
2780   arglist = tree_cons (NULL_TREE, src, arglist);
2781   arglist = tree_cons (NULL_TREE, dst, arglist);
2782   return expand_expr (build_function_call_expr (fn, arglist),
2783                       target, mode, EXPAND_NORMAL);
2784 }
2785
2786 /* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
2787    Return 0 if we failed the caller should emit a normal call,
2788    otherwise try to get the result in TARGET, if convenient (and in
2789    mode MODE if that's convenient).  */
2790
2791 static rtx
2792 expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
2793 {
2794   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
2795     return 0;
2796   else
2797     {
2798       tree dst, src, len;
2799
2800       /* If return value is ignored, transform stpcpy into strcpy.  */
2801       if (target == const0_rtx)
2802         {
2803           tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
2804           if (!fn)
2805             return 0;
2806
2807           return expand_expr (build_function_call_expr (fn, arglist),
2808                               target, mode, EXPAND_NORMAL);
2809         }
2810
2811       /* Ensure we get an actual string whose length can be evaluated at
2812          compile-time, not an expression containing a string.  This is
2813          because the latter will potentially produce pessimized code
2814          when used to produce the return value.  */
2815       src = TREE_VALUE (TREE_CHAIN (arglist));
2816       if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
2817         return 0;
2818
2819       dst = TREE_VALUE (arglist);
2820       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
2821       arglist = build_tree_list (NULL_TREE, len);
2822       arglist = tree_cons (NULL_TREE, src, arglist);
2823       arglist = tree_cons (NULL_TREE, dst, arglist);
2824       return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
2825     }
2826 }
2827
2828 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2829    bytes from constant string DATA + OFFSET and return it as target
2830    constant.  */
2831
2832 static rtx
2833 builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
2834                           enum machine_mode mode)
2835 {
2836   const char *str = (const char *) data;
2837
2838   if ((unsigned HOST_WIDE_INT) offset > strlen (str))
2839     return const0_rtx;
2840
2841   return c_readstr (str + offset, mode);
2842 }
2843
2844 /* Expand expression EXP, which is a call to the strncpy builtin.  Return 0
2845    if we failed the caller should emit a normal call.  */
2846
2847 static rtx
2848 expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
2849 {
2850   if (!validate_arglist (arglist,
2851                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
2852     return 0;
2853   else
2854     {
2855       tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
2856       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2857       tree fn;
2858
2859       /* We must be passed a constant len parameter.  */
2860       if (TREE_CODE (len) != INTEGER_CST)
2861         return 0;
2862
2863       /* If the len parameter is zero, return the dst parameter.  */
2864       if (integer_zerop (len))
2865         {
2866           /* Evaluate and ignore the src argument in case it has
2867              side-effects.  */
2868           expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
2869                        VOIDmode, EXPAND_NORMAL);
2870           /* Return the dst parameter.  */
2871           return expand_expr (TREE_VALUE (arglist), target, mode,
2872                               EXPAND_NORMAL);
2873         }
2874
2875       /* Now, we must be passed a constant src ptr parameter.  */
2876       if (slen == 0 || TREE_CODE (slen) != INTEGER_CST)
2877         return 0;
2878
2879       slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
2880
2881       /* We're required to pad with trailing zeros if the requested
2882          len is greater than strlen(s2)+1.  In that case try to
2883          use store_by_pieces, if it fails, punt.  */
2884       if (tree_int_cst_lt (slen, len))
2885         {
2886           tree dest = TREE_VALUE (arglist);
2887           unsigned int dest_align
2888             = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2889           const char *p = c_getstr (TREE_VALUE (TREE_CHAIN (arglist)));
2890           rtx dest_mem;
2891
2892           if (!p || dest_align == 0 || !host_integerp (len, 1)
2893               || !can_store_by_pieces (tree_low_cst (len, 1),
2894                                        builtin_strncpy_read_str,
2895                                        (void *) p, dest_align))
2896             return 0;
2897
2898           dest_mem = get_memory_rtx (dest);
2899           store_by_pieces (dest_mem, tree_low_cst (len, 1),
2900                            builtin_strncpy_read_str,
2901                            (void *) p, dest_align, 0);
2902           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
2903           dest_mem = convert_memory_address (ptr_mode, dest_mem);
2904           return dest_mem;
2905         }
2906
2907       /* OK transform into builtin memcpy.  */
2908       fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
2909       if (!fn)
2910         return 0;
2911       return expand_expr (build_function_call_expr (fn, arglist),
2912                           target, mode, EXPAND_NORMAL);
2913     }
2914 }
2915
2916 /* Callback routine for store_by_pieces.  Read GET_MODE_BITSIZE (MODE)
2917    bytes from constant string DATA + OFFSET and return it as target
2918    constant.  */
2919
2920 static rtx
2921 builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2922                          enum machine_mode mode)
2923 {
2924   const char *c = (const char *) data;
2925   char *p = alloca (GET_MODE_SIZE (mode));
2926
2927   memset (p, *c, GET_MODE_SIZE (mode));
2928
2929   return c_readstr (p, mode);
2930 }
2931
2932 /* Callback routine for store_by_pieces.  Return the RTL of a register
2933    containing GET_MODE_SIZE (MODE) consecutive copies of the unsigned
2934    char value given in the RTL register data.  For example, if mode is
2935    4 bytes wide, return the RTL for 0x01010101*data.  */
2936
2937 static rtx
2938 builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
2939                         enum machine_mode mode)
2940 {
2941   rtx target, coeff;
2942   size_t size;
2943   char *p;
2944
2945   size = GET_MODE_SIZE (mode);
2946   if (size == 1)
2947     return (rtx) data;
2948
2949   p = alloca (size);
2950   memset (p, 1, size);
2951   coeff = c_readstr (p, mode);
2952
2953   target = convert_to_mode (mode, (rtx) data, 1);
2954   target = expand_mult (mode, target, coeff, NULL_RTX, 1);
2955   return force_reg (mode, target);
2956 }
2957
2958 /* Expand expression EXP, which is a call to the memset builtin.  Return 0
2959    if we failed the caller should emit a normal call, otherwise try to get
2960    the result in TARGET, if convenient (and in mode MODE if that's
2961    convenient).  */
2962
2963 static rtx
2964 expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
2965 {
2966   if (!validate_arglist (arglist,
2967                          POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
2968     return 0;
2969   else
2970     {
2971       tree dest = TREE_VALUE (arglist);
2972       tree val = TREE_VALUE (TREE_CHAIN (arglist));
2973       tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
2974       char c;
2975
2976       unsigned int dest_align
2977         = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
2978       rtx dest_mem, dest_addr, len_rtx;
2979
2980       /* If DEST is not a pointer type, don't do this
2981          operation in-line.  */
2982       if (dest_align == 0)
2983         return 0;
2984
2985       /* If the LEN parameter is zero, return DEST.  */
2986       if (integer_zerop (len))
2987         {
2988           /* Evaluate and ignore VAL in case it has side-effects.  */
2989           expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
2990           return expand_expr (dest, target, mode, EXPAND_NORMAL);
2991         }
2992
2993       if (TREE_CODE (val) != INTEGER_CST)
2994         {
2995           rtx val_rtx;
2996
2997           if (!host_integerp (len, 1))
2998             return 0;
2999
3000           if (optimize_size && tree_low_cst (len, 1) > 1)
3001             return 0;
3002
3003           /* Assume that we can memset by pieces if we can store the
3004            * the coefficients by pieces (in the required modes).
3005            * We can't pass builtin_memset_gen_str as that emits RTL.  */
3006           c = 1;
3007           if (!can_store_by_pieces (tree_low_cst (len, 1),
3008                                     builtin_memset_read_str,
3009                                     &c, dest_align))
3010             return 0;
3011
3012           val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
3013           val_rtx = expand_expr (val, NULL_RTX, VOIDmode, 0);
3014           val_rtx = force_reg (TYPE_MODE (unsigned_char_type_node),
3015                                val_rtx);
3016           dest_mem = get_memory_rtx (dest);
3017           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3018                            builtin_memset_gen_str,
3019                            val_rtx, dest_align, 0);
3020           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3021           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3022           return dest_mem;
3023         }
3024
3025       if (target_char_cast (val, &c))
3026         return 0;
3027
3028       if (c)
3029         {
3030           if (!host_integerp (len, 1))
3031             return 0;
3032           if (!can_store_by_pieces (tree_low_cst (len, 1),
3033                                     builtin_memset_read_str, &c,
3034                                     dest_align))
3035             return 0;
3036
3037           dest_mem = get_memory_rtx (dest);
3038           store_by_pieces (dest_mem, tree_low_cst (len, 1),
3039                            builtin_memset_read_str,
3040                            &c, dest_align, 0);
3041           dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3042           dest_mem = convert_memory_address (ptr_mode, dest_mem);
3043           return dest_mem;
3044         }
3045
3046       len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3047
3048       dest_mem = get_memory_rtx (dest);
3049       set_mem_align (dest_mem, dest_align);
3050       dest_addr = clear_storage (dest_mem, len_rtx);
3051
3052       if (dest_addr == 0)
3053         {
3054           dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
3055           dest_addr = convert_memory_address (ptr_mode, dest_addr);
3056         }
3057
3058       return dest_addr;
3059     }
3060 }
3061
3062 /* Expand expression EXP, which is a call to the bzero builtin.  Return 0
3063    if we failed the caller should emit a normal call.  */
3064
3065 static rtx
3066 expand_builtin_bzero (tree arglist)
3067 {
3068   tree dest, size, newarglist;
3069
3070   if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3071     return NULL_RTX;
3072
3073   dest = TREE_VALUE (arglist);
3074   size = TREE_VALUE (TREE_CHAIN (arglist));
3075
3076   /* New argument list transforming bzero(ptr x, int y) to
3077      memset(ptr x, int 0, size_t y).   This is done this way
3078      so that if it isn't expanded inline, we fallback to
3079      calling bzero instead of memset.  */
3080
3081   newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
3082   newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
3083   newarglist = tree_cons (NULL_TREE, dest, newarglist);
3084
3085   return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
3086 }
3087
3088 /* Expand expression EXP, which is a call to the memcmp built-in function.
3089    ARGLIST is the argument list for this call.  Return 0 if we failed and the
3090    caller should emit a normal call, otherwise try to get the result in
3091    TARGET, if convenient (and in mode MODE, if that's convenient).  */
3092
3093 static rtx
3094 expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
3095                        enum machine_mode mode)
3096 {
3097   tree arg1, arg2, len;
3098   const char *p1, *p2;
3099
3100   if (!validate_arglist (arglist,
3101                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3102     return 0;
3103
3104   arg1 = TREE_VALUE (arglist);
3105   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3106   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3107
3108   /* If the len parameter is zero, return zero.  */
3109   if (integer_zerop (len))
3110     {
3111       /* Evaluate and ignore arg1 and arg2 in case they have
3112          side-effects.  */
3113       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3114       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3115       return const0_rtx;
3116     }
3117
3118   /* If both arguments are equal (and not volatile), return zero.  */
3119   if (operand_equal_p (arg1, arg2, 0))
3120     {
3121       /* Evaluate and ignore len in case it has side-effects.  */
3122       expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3123       return const0_rtx;
3124     }
3125
3126   p1 = c_getstr (arg1);
3127   p2 = c_getstr (arg2);
3128
3129   /* If all arguments are constant, and the value of len is not greater
3130      than the lengths of arg1 and arg2, evaluate at compile-time.  */
3131   if (host_integerp (len, 1) && p1 && p2
3132       && compare_tree_int (len, strlen (p1) + 1) <= 0
3133       && compare_tree_int (len, strlen (p2) + 1) <= 0)
3134     {
3135       const int r = memcmp (p1, p2, tree_low_cst (len, 1));
3136
3137       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3138     }
3139
3140   /* If len parameter is one, return an expression corresponding to
3141      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3142   if (integer_onep (len))
3143     {
3144       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3145       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3146       tree ind1 =
3147       fold (build1 (CONVERT_EXPR, integer_type_node,
3148                     build1 (INDIRECT_REF, cst_uchar_node,
3149                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3150       tree ind2 =
3151       fold (build1 (CONVERT_EXPR, integer_type_node,
3152                     build1 (INDIRECT_REF, cst_uchar_node,
3153                             build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3154       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3155       return expand_expr (result, target, mode, EXPAND_NORMAL);
3156     }
3157
3158 #if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
3159   {
3160     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3161     rtx result;
3162     rtx insn;
3163
3164     int arg1_align
3165       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3166     int arg2_align
3167       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3168     enum machine_mode insn_mode;
3169
3170 #ifdef HAVE_cmpmemsi
3171     if (HAVE_cmpmemsi)
3172       insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
3173     else
3174 #endif
3175 #ifdef HAVE_cmpstrsi
3176     if (HAVE_cmpstrsi)
3177       insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3178     else
3179 #endif
3180       return 0;     
3181
3182     /* If we don't have POINTER_TYPE, call the function.  */
3183     if (arg1_align == 0 || arg2_align == 0)
3184       return 0;
3185
3186     /* Make a place to write the result of the instruction.  */
3187     result = target;
3188     if (! (result != 0
3189            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3190            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3191       result = gen_reg_rtx (insn_mode);
3192
3193     arg1_rtx = get_memory_rtx (arg1);
3194     arg2_rtx = get_memory_rtx (arg2);
3195     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3196 #ifdef HAVE_cmpmemsi
3197     if (HAVE_cmpmemsi)
3198       insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3199                            GEN_INT (MIN (arg1_align, arg2_align)));
3200     else
3201 #endif
3202 #ifdef HAVE_cmpstrsi
3203     if (HAVE_cmpstrsi)
3204       insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3205                            GEN_INT (MIN (arg1_align, arg2_align)));
3206     else
3207 #endif
3208       abort ();
3209
3210     if (insn)
3211       emit_insn (insn);
3212     else
3213       emit_library_call_value (memcmp_libfunc, result, LCT_PURE_MAKE_BLOCK,
3214                                TYPE_MODE (integer_type_node), 3,
3215                                XEXP (arg1_rtx, 0), Pmode,
3216                                XEXP (arg2_rtx, 0), Pmode,
3217                                convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
3218                                                 TREE_UNSIGNED (sizetype)),
3219                                TYPE_MODE (sizetype));
3220
3221     /* Return the value in the proper mode for this function.  */
3222     mode = TYPE_MODE (TREE_TYPE (exp));
3223     if (GET_MODE (result) == mode)
3224       return result;
3225     else if (target != 0)
3226       {
3227         convert_move (target, result, 0);
3228         return target;
3229       }
3230     else
3231       return convert_to_mode (mode, result, 0);
3232   }
3233 #endif
3234
3235   return 0;
3236 }
3237
3238 /* Expand expression EXP, which is a call to the strcmp builtin.  Return 0
3239    if we failed the caller should emit a normal call, otherwise try to get
3240    the result in TARGET, if convenient.  */
3241
3242 static rtx
3243 expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
3244 {
3245   tree arglist = TREE_OPERAND (exp, 1);
3246   tree arg1, arg2;
3247   const char *p1, *p2;
3248
3249   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3250     return 0;
3251
3252   arg1 = TREE_VALUE (arglist);
3253   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3254
3255   /* If both arguments are equal (and not volatile), return zero.  */
3256   if (operand_equal_p (arg1, arg2, 0))
3257     return const0_rtx;
3258
3259   p1 = c_getstr (arg1);
3260   p2 = c_getstr (arg2);
3261
3262   if (p1 && p2)
3263     {
3264       const int i = strcmp (p1, p2);
3265       return (i < 0 ? constm1_rtx : (i > 0 ? const1_rtx : const0_rtx));
3266     }
3267
3268   /* If either arg is "", return an expression corresponding to
3269      (*(const unsigned char*)arg1 - (const unsigned char*)arg2).  */
3270   if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3271     {
3272       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3273       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3274       tree ind1 =
3275         fold (build1 (CONVERT_EXPR, integer_type_node,
3276                       build1 (INDIRECT_REF, cst_uchar_node,
3277                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3278       tree ind2 =
3279         fold (build1 (CONVERT_EXPR, integer_type_node,
3280                       build1 (INDIRECT_REF, cst_uchar_node,
3281                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3282       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3283       return expand_expr (result, target, mode, EXPAND_NORMAL);
3284     }
3285
3286 #ifdef HAVE_cmpstrsi
3287   if (HAVE_cmpstrsi)
3288   {
3289     tree len, len1, len2;
3290     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3291     rtx result, insn;
3292     tree fndecl;
3293
3294     int arg1_align
3295       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3296     int arg2_align
3297       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3298     enum machine_mode insn_mode
3299       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3300
3301     len1 = c_strlen (arg1, 1);
3302     len2 = c_strlen (arg2, 1);
3303
3304     if (len1)
3305       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3306     if (len2)
3307       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3308
3309     /* If we don't have a constant length for the first, use the length
3310        of the second, if we know it.  We don't require a constant for
3311        this case; some cost analysis could be done if both are available
3312        but neither is constant.  For now, assume they're equally cheap,
3313        unless one has side effects.  If both strings have constant lengths,
3314        use the smaller.  */
3315
3316     if (!len1)
3317       len = len2;
3318     else if (!len2)
3319       len = len1;
3320     else if (TREE_SIDE_EFFECTS (len1))
3321       len = len2;
3322     else if (TREE_SIDE_EFFECTS (len2))
3323       len = len1;
3324     else if (TREE_CODE (len1) != INTEGER_CST)
3325       len = len2;
3326     else if (TREE_CODE (len2) != INTEGER_CST)
3327       len = len1;
3328     else if (tree_int_cst_lt (len1, len2))
3329       len = len1;
3330     else
3331       len = len2;
3332
3333     /* If both arguments have side effects, we cannot optimize.  */
3334     if (!len || TREE_SIDE_EFFECTS (len))
3335       return 0;
3336
3337     /* If we don't have POINTER_TYPE, call the function.  */
3338     if (arg1_align == 0 || arg2_align == 0)
3339       return 0;
3340
3341     /* Make a place to write the result of the instruction.  */
3342     result = target;
3343     if (! (result != 0
3344            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3345            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3346       result = gen_reg_rtx (insn_mode);
3347
3348     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3349     arg1 = save_expr (arg1);
3350     arg2 = save_expr (arg2);
3351
3352     arg1_rtx = get_memory_rtx (arg1);
3353     arg2_rtx = get_memory_rtx (arg2);
3354     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3355     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3356                          GEN_INT (MIN (arg1_align, arg2_align)));
3357     if (insn)
3358       {
3359         emit_insn (insn);
3360
3361         /* Return the value in the proper mode for this function.  */
3362         mode = TYPE_MODE (TREE_TYPE (exp));
3363         if (GET_MODE (result) == mode)
3364           return result;
3365         if (target == 0)
3366           return convert_to_mode (mode, result, 0);
3367         convert_move (target, result, 0);
3368         return target;
3369       }
3370
3371     /* Expand the library call ourselves using a stabilized argument
3372        list to avoid re-evaluating the function's arguments twice.  */
3373     arglist = build_tree_list (NULL_TREE, arg2);
3374     arglist = tree_cons (NULL_TREE, arg1, arglist);
3375     fndecl = get_callee_fndecl (exp);
3376     exp = build_function_call_expr (fndecl, arglist);
3377     return expand_call (exp, target, target == const0_rtx);
3378   }
3379 #endif
3380   return 0;
3381 }
3382
3383 /* Expand expression EXP, which is a call to the strncmp builtin.  Return 0
3384    if we failed the caller should emit a normal call, otherwise try to get
3385    the result in TARGET, if convenient.  */
3386
3387 static rtx
3388 expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
3389 {
3390   tree arglist = TREE_OPERAND (exp, 1);
3391   tree arg1, arg2, arg3;
3392   const char *p1, *p2;
3393
3394   if (!validate_arglist (arglist,
3395                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3396     return 0;
3397
3398   arg1 = TREE_VALUE (arglist);
3399   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
3400   arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3401
3402   /* If the len parameter is zero, return zero.  */
3403   if (integer_zerop (arg3))
3404     {
3405       /* Evaluate and ignore arg1 and arg2 in case they have
3406          side-effects.  */
3407       expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3408       expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3409       return const0_rtx;
3410     }
3411
3412   /* If arg1 and arg2 are equal (and not volatile), return zero.  */
3413   if (operand_equal_p (arg1, arg2, 0))
3414     {
3415       /* Evaluate and ignore arg3 in case it has side-effects.  */
3416       expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
3417       return const0_rtx;
3418     }
3419
3420   p1 = c_getstr (arg1);
3421   p2 = c_getstr (arg2);
3422
3423   /* If all arguments are constant, evaluate at compile-time.  */
3424   if (host_integerp (arg3, 1) && p1 && p2)
3425     {
3426       const int r = strncmp (p1, p2, tree_low_cst (arg3, 1));
3427       return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
3428     }
3429
3430   /* If len == 1 or (either string parameter is "" and (len >= 1)),
3431       return (*(const u_char*)arg1 - *(const u_char*)arg2).  */
3432   if (host_integerp (arg3, 1)
3433       && (tree_low_cst (arg3, 1) == 1
3434           || (tree_low_cst (arg3, 1) > 1
3435               && ((p1 && *p1 == '\0') || (p2 && *p2 == '\0')))))
3436     {
3437       tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
3438       tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
3439       tree ind1 =
3440         fold (build1 (CONVERT_EXPR, integer_type_node,
3441                       build1 (INDIRECT_REF, cst_uchar_node,
3442                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg1))));
3443       tree ind2 =
3444         fold (build1 (CONVERT_EXPR, integer_type_node,
3445                       build1 (INDIRECT_REF, cst_uchar_node,
3446                               build1 (NOP_EXPR, cst_uchar_ptr_node, arg2))));
3447       tree result = fold (build (MINUS_EXPR, integer_type_node, ind1, ind2));
3448       return expand_expr (result, target, mode, EXPAND_NORMAL);
3449     }
3450
3451   /* If c_strlen can determine an expression for one of the string
3452      lengths, and it doesn't have side effects, then emit cmpstrsi
3453      using length MIN(strlen(string)+1, arg3).  */
3454 #ifdef HAVE_cmpstrsi
3455   if (HAVE_cmpstrsi)
3456   {
3457     tree len, len1, len2;
3458     rtx arg1_rtx, arg2_rtx, arg3_rtx;
3459     rtx result, insn;
3460     tree fndecl;
3461
3462     int arg1_align
3463       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3464     int arg2_align
3465       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
3466     enum machine_mode insn_mode
3467       = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3468
3469     len1 = c_strlen (arg1, 1);
3470     len2 = c_strlen (arg2, 1);
3471
3472     if (len1)
3473       len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
3474     if (len2)
3475       len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
3476
3477     /* If we don't have a constant length for the first, use the length
3478        of the second, if we know it.  We don't require a constant for
3479        this case; some cost analysis could be done if both are available
3480        but neither is constant.  For now, assume they're equally cheap,
3481        unless one has side effects.  If both strings have constant lengths,
3482        use the smaller.  */
3483
3484     if (!len1)
3485       len = len2;
3486     else if (!len2)
3487       len = len1;
3488     else if (TREE_SIDE_EFFECTS (len1))
3489       len = len2;
3490     else if (TREE_SIDE_EFFECTS (len2))
3491       len = len1;
3492     else if (TREE_CODE (len1) != INTEGER_CST)
3493       len = len2;
3494     else if (TREE_CODE (len2) != INTEGER_CST)
3495       len = len1;
3496     else if (tree_int_cst_lt (len1, len2))
3497       len = len1;
3498     else
3499       len = len2;
3500
3501     /* If both arguments have side effects, we cannot optimize.  */
3502     if (!len || TREE_SIDE_EFFECTS (len))
3503       return 0;
3504
3505     /* The actual new length parameter is MIN(len,arg3).  */
3506     len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
3507
3508     /* If we don't have POINTER_TYPE, call the function.  */
3509     if (arg1_align == 0 || arg2_align == 0)
3510       return 0;
3511
3512     /* Make a place to write the result of the instruction.  */
3513     result = target;
3514     if (! (result != 0
3515            && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
3516            && REGNO (result) >= FIRST_PSEUDO_REGISTER))
3517       result = gen_reg_rtx (insn_mode);
3518
3519     /* Stabilize the arguments in case gen_cmpstrsi fails.  */
3520     arg1 = save_expr (arg1);
3521     arg2 = save_expr (arg2);
3522     len = save_expr (len);
3523
3524     arg1_rtx = get_memory_rtx (arg1);
3525     arg2_rtx = get_memory_rtx (arg2);
3526     arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
3527     insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
3528                          GEN_INT (MIN (arg1_align, arg2_align)));
3529     if (insn)
3530       {
3531         emit_insn (insn);
3532
3533         /* Return the value in the proper mode for this function.  */
3534         mode = TYPE_MODE (TREE_TYPE (exp));
3535         if (GET_MODE (result) == mode)
3536           return result;
3537         if (target == 0)
3538           return convert_to_mode (mode, result, 0);
3539         convert_move (target, result, 0);
3540         return target;
3541       }
3542
3543     /* Expand the library call ourselves using a stabilized argument
3544        list to avoid re-evaluating the function's arguments twice.  */
3545     arglist = build_tree_list (NULL_TREE, len);
3546     arglist = tree_cons (NULL_TREE, arg2, arglist);
3547     arglist = tree_cons (NULL_TREE, arg1, arglist);
3548     fndecl = get_callee_fndecl (exp);
3549     exp = build_function_call_expr (fndecl, arglist);
3550     return expand_call (exp, target, target == const0_rtx);
3551   }
3552 #endif
3553   return 0;
3554 }
3555
3556 /* Expand expression EXP, which is a call to the strcat builtin.
3557    Return 0 if we failed the caller should emit a normal call,
3558    otherwise try to get the result in TARGET, if convenient.  */
3559
3560 static rtx
3561 expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
3562 {
3563   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3564     return 0;
3565   else
3566     {
3567       tree dst = TREE_VALUE (arglist),
3568         src = TREE_VALUE (TREE_CHAIN (arglist));
3569       const char *p = c_getstr (src);
3570
3571       if (p)
3572         {
3573           /* If the string length is zero, return the dst parameter.  */
3574           if (*p == '\0')
3575             return expand_expr (dst, target, mode, EXPAND_NORMAL);
3576           else if (!optimize_size)
3577             {
3578               /* Otherwise if !optimize_size, see if we can store by
3579                  pieces into (dst + strlen(dst)).  */
3580               tree newdst, arglist,
3581                 strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3582               
3583               /* This is the length argument.  */
3584               arglist = build_tree_list (NULL_TREE,
3585                                          fold (size_binop (PLUS_EXPR,
3586                                                            c_strlen (src, 0),
3587                                                            ssize_int (1))));
3588               /* Prepend src argument.  */
3589               arglist = tree_cons (NULL_TREE, src, arglist);
3590               
3591               /* We're going to use dst more than once.  */
3592               dst = save_expr (dst);
3593
3594               /* Create strlen (dst).  */
3595               newdst =
3596                 fold (build_function_call_expr (strlen_fn,
3597                                                 build_tree_list (NULL_TREE,
3598                                                                  dst)));
3599               /* Create (dst + strlen (dst)).  */
3600               newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
3601
3602               /* Prepend the new dst argument.  */
3603               arglist = tree_cons (NULL_TREE, newdst, arglist);
3604               
3605               /* We don't want to get turned into a memcpy if the
3606                  target is const0_rtx, i.e. when the return value
3607                  isn't used.  That would produce pessimized code so
3608                  pass in a target of zero, it should never actually be
3609                  used.  If this was successful return the original
3610                  dst, not the result of mempcpy.  */
3611               if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
3612                 return expand_expr (dst, target, mode, EXPAND_NORMAL);
3613               else
3614                 return 0;
3615             }
3616         }
3617
3618       return 0;
3619     }
3620 }
3621
3622 /* Expand expression EXP, which is a call to the strncat builtin.
3623    Return 0 if we failed the caller should emit a normal call,
3624    otherwise try to get the result in TARGET, if convenient.  */
3625
3626 static rtx
3627 expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
3628 {
3629   if (!validate_arglist (arglist,
3630                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
3631     return 0;
3632   else
3633     {
3634       tree dst = TREE_VALUE (arglist),
3635         src = TREE_VALUE (TREE_CHAIN (arglist)),
3636         len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
3637       const char *p = c_getstr (src);
3638
3639       /* If the requested length is zero, or the src parameter string
3640           length is zero, return the dst parameter.  */
3641       if (integer_zerop (len) || (p && *p == '\0'))
3642         {
3643           /* Evaluate and ignore the src and len parameters in case
3644              they have side-effects.  */
3645           expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
3646           expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
3647           return expand_expr (dst, target, mode, EXPAND_NORMAL);
3648         }
3649
3650       /* If the requested len is greater than or equal to the string
3651          length, call strcat.  */
3652       if (TREE_CODE (len) == INTEGER_CST && p
3653           && compare_tree_int (len, strlen (p)) >= 0)
3654         {
3655           tree newarglist
3656             = tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
3657           tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
3658
3659           /* If the replacement _DECL isn't initialized, don't do the
3660              transformation.  */
3661           if (!fn)
3662             return 0;
3663
3664           return expand_expr (build_function_call_expr (fn, newarglist),
3665                               target, mode, EXPAND_NORMAL);
3666         }
3667       return 0;
3668     }
3669 }
3670
3671 /* Expand expression EXP, which is a call to the strspn builtin.
3672    Return 0 if we failed the caller should emit a normal call,
3673    otherwise try to get the result in TARGET, if convenient.  */
3674
3675 static rtx
3676 expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
3677 {
3678   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3679     return 0;
3680   else
3681     {
3682       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3683       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3684
3685       /* If both arguments are constants, evaluate at compile-time.  */
3686       if (p1 && p2)
3687         {
3688           const size_t r = strspn (p1, p2);
3689           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3690         }
3691
3692       /* If either argument is "", return 0.  */
3693       if ((p1 && *p1 == '\0') || (p2 && *p2 == '\0'))
3694         {
3695           /* Evaluate and ignore both arguments in case either one has
3696              side-effects.  */
3697           expand_expr (s1, const0_rtx, VOIDmode, EXPAND_NORMAL);
3698           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3699           return const0_rtx;
3700         }
3701       return 0;
3702     }
3703 }
3704
3705 /* Expand expression EXP, which is a call to the strcspn builtin.
3706    Return 0 if we failed the caller should emit a normal call,
3707    otherwise try to get the result in TARGET, if convenient.  */
3708
3709 static rtx
3710 expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
3711 {
3712   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
3713     return 0;
3714   else
3715     {
3716       tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
3717       const char *p1 = c_getstr (s1), *p2 = c_getstr (s2);
3718
3719       /* If both arguments are constants, evaluate at compile-time.  */
3720       if (p1 && p2)
3721         {
3722           const size_t r = strcspn (p1, p2);
3723           return expand_expr (size_int (r), target, mode, EXPAND_NORMAL);
3724         }
3725
3726       /* If the first argument is "", return 0.  */
3727       if (p1 && *p1 == '\0')
3728         {
3729           /* Evaluate and ignore argument s2 in case it has
3730              side-effects.  */
3731           expand_expr (s2, const0_rtx, VOIDmode, EXPAND_NORMAL);
3732           return const0_rtx;
3733         }
3734
3735       /* If the second argument is "", return __builtin_strlen(s1).  */
3736       if (p2 && *p2 == '\0')
3737         {
3738           tree newarglist = build_tree_list (NULL_TREE, s1),
3739             fn = implicit_built_in_decls[BUILT_IN_STRLEN];
3740
3741           /* If the replacement _DECL isn't initialized, don't do the
3742              transformation.  */
3743           if (!fn)
3744             return 0;
3745
3746           return expand_expr (build_function_call_expr (fn, newarglist),
3747                               target, mode, EXPAND_NORMAL);
3748         }
3749       return 0;
3750     }
3751 }
3752
3753 /* Expand a call to __builtin_saveregs, generating the result in TARGET,
3754    if that's convenient.  */
3755
3756 rtx
3757 expand_builtin_saveregs (void)
3758 {
3759   rtx val, seq;
3760
3761   /* Don't do __builtin_saveregs more than once in a function.
3762      Save the result of the first call and reuse it.  */
3763   if (saveregs_value != 0)
3764     return saveregs_value;
3765
3766   /* When this function is called, it means that registers must be
3767      saved on entry to this function.  So we migrate the call to the
3768      first insn of this function.  */
3769
3770   start_sequence ();
3771
3772   /* Do whatever the machine needs done in this case.  */
3773   val = targetm.calls.expand_builtin_saveregs ();
3774
3775   seq = get_insns ();
3776   end_sequence ();
3777
3778   saveregs_value = val;
3779
3780   /* Put the insns after the NOTE that starts the function.  If this
3781      is inside a start_sequence, make the outer-level insn chain current, so
3782      the code is placed at the start of the function.  */
3783   push_topmost_sequence ();
3784   emit_insn_after (seq, get_insns ());
3785   pop_topmost_sequence ();
3786
3787   return val;
3788 }
3789
3790 /* __builtin_args_info (N) returns word N of the arg space info
3791    for the current function.  The number and meanings of words
3792    is controlled by the definition of CUMULATIVE_ARGS.  */
3793
3794 static rtx
3795 expand_builtin_args_info (tree arglist)
3796 {
3797   int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
3798   int *word_ptr = (int *) &current_function_args_info;
3799
3800   if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
3801     abort ();
3802
3803   if (arglist != 0)
3804     {
3805       if (!host_integerp (TREE_VALUE (arglist), 0))
3806         error ("argument of `__builtin_args_info' must be constant");
3807       else
3808         {
3809           HOST_WIDE_INT wordnum = tree_low_cst (TREE_VALUE (arglist), 0);
3810
3811           if (wordnum < 0 || wordnum >= nwords)
3812             error ("argument of `__builtin_args_info' out of range");
3813           else
3814             return GEN_INT (word_ptr[wordnum]);
3815         }
3816     }
3817   else
3818     error ("missing argument in `__builtin_args_info'");
3819
3820   return const0_rtx;
3821 }
3822
3823 /* Expand ARGLIST, from a call to __builtin_next_arg.  */
3824
3825 static rtx
3826 expand_builtin_next_arg (tree arglist)
3827 {
3828   tree fntype = TREE_TYPE (current_function_decl);
3829
3830   if (TYPE_ARG_TYPES (fntype) == 0
3831       || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3832           == void_type_node))
3833     {
3834       error ("`va_start' used in function with fixed args");
3835       return const0_rtx;
3836     }
3837
3838   if (arglist)
3839     {
3840       tree last_parm = tree_last (DECL_ARGUMENTS (current_function_decl));
3841       tree arg = TREE_VALUE (arglist);
3842
3843       /* Strip off all nops for the sake of the comparison.  This
3844          is not quite the same as STRIP_NOPS.  It does more.
3845          We must also strip off INDIRECT_EXPR for C++ reference
3846          parameters.  */
3847       while (TREE_CODE (arg) == NOP_EXPR
3848              || TREE_CODE (arg) == CONVERT_EXPR
3849              || TREE_CODE (arg) == NON_LVALUE_EXPR
3850              || TREE_CODE (arg) == INDIRECT_REF)
3851         arg = TREE_OPERAND (arg, 0);
3852       if (arg != last_parm)
3853         warning ("second parameter of `va_start' not last named argument");
3854     }
3855   else
3856     /* Evidently an out of date version of <stdarg.h>; can't validate
3857        va_start's second argument, but can still work as intended.  */
3858     warning ("`__builtin_next_arg' called without an argument");
3859
3860   return expand_binop (Pmode, add_optab,
3861                        current_function_internal_arg_pointer,
3862                        current_function_arg_offset_rtx,
3863                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
3864 }
3865
3866 /* Make it easier for the backends by protecting the valist argument
3867    from multiple evaluations.  */
3868
3869 static tree
3870 stabilize_va_list (tree valist, int needs_lvalue)
3871 {
3872   if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
3873     {
3874       if (TREE_SIDE_EFFECTS (valist))
3875         valist = save_expr (valist);
3876
3877       /* For this case, the backends will be expecting a pointer to
3878          TREE_TYPE (va_list_type_node), but it's possible we've
3879          actually been given an array (an actual va_list_type_node).
3880          So fix it.  */
3881       if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
3882         {
3883           tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
3884           tree p2 = build_pointer_type (va_list_type_node);
3885
3886           valist = build1 (ADDR_EXPR, p2, valist);
3887           valist = fold (build1 (NOP_EXPR, p1, valist));
3888         }
3889     }
3890   else
3891     {
3892       tree pt;
3893
3894       if (! needs_lvalue)
3895         {
3896           if (! TREE_SIDE_EFFECTS (valist))
3897             return valist;
3898
3899           pt = build_pointer_type (va_list_type_node);
3900           valist = fold (build1 (ADDR_EXPR, pt, valist));
3901           TREE_SIDE_EFFECTS (valist) = 1;
3902         }
3903
3904       if (TREE_SIDE_EFFECTS (valist))
3905         valist = save_expr (valist);
3906       valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
3907                              valist));
3908     }
3909
3910   return valist;
3911 }
3912
3913 /* The "standard" implementation of va_start: just assign `nextarg' to
3914    the variable.  */
3915
3916 void
3917 std_expand_builtin_va_start (tree valist, rtx nextarg)
3918 {
3919   tree t;
3920
3921   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3922              make_tree (ptr_type_node, nextarg));
3923   TREE_SIDE_EFFECTS (t) = 1;
3924
3925   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3926 }
3927
3928 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3929
3930 static rtx
3931 expand_builtin_va_start (tree arglist)
3932 {
3933   rtx nextarg;
3934   tree chain, valist;
3935
3936   chain = TREE_CHAIN (arglist);
3937
3938   if (TREE_CHAIN (chain))
3939     error ("too many arguments to function `va_start'");
3940
3941   nextarg = expand_builtin_next_arg (chain);
3942   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3943
3944 #ifdef EXPAND_BUILTIN_VA_START
3945   EXPAND_BUILTIN_VA_START (valist, nextarg);
3946 #else
3947   std_expand_builtin_va_start (valist, nextarg);
3948 #endif
3949
3950   return const0_rtx;
3951 }
3952
3953 /* The "standard" implementation of va_arg: read the value from the
3954    current (padded) address and increment by the (padded) size.  */
3955
3956 rtx
3957 std_expand_builtin_va_arg (tree valist, tree type)
3958 {
3959   tree addr_tree, t, type_size = NULL;
3960   tree align, alignm1;
3961   tree rounded_size;
3962   rtx addr;
3963
3964   /* Compute the rounded size of the type.  */
3965   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3966   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3967   if (type == error_mark_node
3968       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3969       || TREE_OVERFLOW (type_size))
3970     rounded_size = size_zero_node;
3971   else
3972     rounded_size = fold (build (MULT_EXPR, sizetype,
3973                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3974                                              fold (build (PLUS_EXPR, sizetype,
3975                                                           type_size, alignm1)),
3976                                              align)),
3977                                 align));
3978
3979   /* Get AP.  */
3980   addr_tree = valist;
3981   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3982     {
3983       /* Small args are padded downward.  */
3984       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3985                                fold (build (COND_EXPR, sizetype,
3986                                             fold (build (GT_EXPR, sizetype,
3987                                                          rounded_size,
3988                                                          align)),
3989                                             size_zero_node,
3990                                             fold (build (MINUS_EXPR, sizetype,
3991                                                          rounded_size,
3992                                                          type_size))))));
3993     }
3994
3995   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
3996   addr = copy_to_reg (addr);
3997
3998   /* Compute new value for AP.  */
3999   if (! integer_zerop (rounded_size))
4000     {
4001       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4002                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
4003                         rounded_size));
4004       TREE_SIDE_EFFECTS (t) = 1;
4005       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4006     }
4007
4008   return addr;
4009 }
4010
4011 /* Expand __builtin_va_arg, which is not really a builtin function, but
4012    a very special sort of operator.  */
4013
4014 rtx
4015 expand_builtin_va_arg (tree valist, tree type)
4016 {
4017   rtx addr, result;
4018   tree promoted_type, want_va_type, have_va_type;
4019
4020   /* Verify that valist is of the proper type.  */
4021
4022   want_va_type = va_list_type_node;
4023   have_va_type = TREE_TYPE (valist);
4024   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4025     {
4026       /* If va_list is an array type, the argument may have decayed
4027          to a pointer type, e.g. by being passed to another function.
4028          In that case, unwrap both types so that we can compare the
4029          underlying records.  */
4030       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4031           || TREE_CODE (have_va_type) == POINTER_TYPE)
4032         {
4033           want_va_type = TREE_TYPE (want_va_type);
4034           have_va_type = TREE_TYPE (have_va_type);
4035         }
4036     }
4037   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4038     {
4039       error ("first argument to `va_arg' not of type `va_list'");
4040       addr = const0_rtx;
4041     }
4042
4043   /* Generate a diagnostic for requesting data of a type that cannot
4044      be passed through `...' due to type promotion at the call site.  */
4045   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4046            != type)
4047     {
4048       const char *name = "<anonymous type>", *pname = 0;
4049       static bool gave_help;
4050
4051       if (TYPE_NAME (type))
4052         {
4053           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4054             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4055           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4056                    && DECL_NAME (TYPE_NAME (type)))
4057             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4058         }
4059       if (TYPE_NAME (promoted_type))
4060         {
4061           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4062             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4063           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4064                    && DECL_NAME (TYPE_NAME (promoted_type)))
4065             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4066         }
4067
4068       /* Unfortunately, this is merely undefined, rather than a constraint
4069          violation, so we cannot make this an error.  If this call is never
4070          executed, the program is still strictly conforming.  */
4071       warning ("`%s' is promoted to `%s' when passed through `...'",
4072                name, pname);
4073       if (! gave_help)
4074         {
4075           gave_help = true;
4076           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4077                    pname, name);
4078         }
4079
4080       /* We can, however, treat "undefined" any way we please.
4081          Call abort to encourage the user to fix the program.  */
4082       expand_builtin_trap ();
4083
4084       /* This is dead code, but go ahead and finish so that the
4085          mode of the result comes out right.  */
4086       addr = const0_rtx;
4087     }
4088   else
4089     {
4090       /* Make it easier for the backends by protecting the valist argument
4091          from multiple evaluations.  */
4092       valist = stabilize_va_list (valist, 0);
4093
4094 #ifdef EXPAND_BUILTIN_VA_ARG
4095       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4096 #else
4097       addr = std_expand_builtin_va_arg (valist, type);
4098 #endif
4099     }
4100
4101   addr = convert_memory_address (Pmode, addr);
4102
4103   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4104   set_mem_alias_set (result, get_varargs_alias_set ());
4105
4106   return result;
4107 }
4108
4109 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4110
4111 static rtx
4112 expand_builtin_va_end (tree arglist)
4113 {
4114   tree valist = TREE_VALUE (arglist);
4115
4116 #ifdef EXPAND_BUILTIN_VA_END
4117   valist = stabilize_va_list (valist, 0);
4118   EXPAND_BUILTIN_VA_END (arglist);
4119 #else
4120   /* Evaluate for side effects, if needed.  I hate macros that don't
4121      do that.  */
4122   if (TREE_SIDE_EFFECTS (valist))
4123     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4124 #endif
4125
4126   return const0_rtx;
4127 }
4128
4129 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4130    builtin rather than just as an assignment in stdarg.h because of the
4131    nastiness of array-type va_list types.  */
4132
4133 static rtx
4134 expand_builtin_va_copy (tree arglist)
4135 {
4136   tree dst, src, t;
4137
4138   dst = TREE_VALUE (arglist);
4139   src = TREE_VALUE (TREE_CHAIN (arglist));
4140
4141   dst = stabilize_va_list (dst, 1);
4142   src = stabilize_va_list (src, 0);
4143
4144   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4145     {
4146       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4147       TREE_SIDE_EFFECTS (t) = 1;
4148       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4149     }
4150   else
4151     {
4152       rtx dstb, srcb, size;
4153
4154       /* Evaluate to pointers.  */
4155       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4156       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4157       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4158                           VOIDmode, EXPAND_NORMAL);
4159
4160       dstb = convert_memory_address (Pmode, dstb);
4161       srcb = convert_memory_address (Pmode, srcb);
4162
4163       /* "Dereference" to BLKmode memories.  */
4164       dstb = gen_rtx_MEM (BLKmode, dstb);
4165       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4166       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4167       srcb = gen_rtx_MEM (BLKmode, srcb);
4168       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4169       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4170
4171       /* Copy.  */
4172       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4173     }
4174
4175   return const0_rtx;
4176 }
4177
4178 /* Expand a call to one of the builtin functions __builtin_frame_address or
4179    __builtin_return_address.  */
4180
4181 static rtx
4182 expand_builtin_frame_address (tree fndecl, tree arglist)
4183 {
4184   /* The argument must be a nonnegative integer constant.
4185      It counts the number of frames to scan up the stack.
4186      The value is the return address saved in that frame.  */
4187   if (arglist == 0)
4188     /* Warning about missing arg was already issued.  */
4189     return const0_rtx;
4190   else if (! host_integerp (TREE_VALUE (arglist), 1))
4191     {
4192       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4193         error ("invalid arg to `__builtin_frame_address'");
4194       else
4195         error ("invalid arg to `__builtin_return_address'");
4196       return const0_rtx;
4197     }
4198   else
4199     {
4200       rtx tem
4201         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4202                                       tree_low_cst (TREE_VALUE (arglist), 1),
4203                                       hard_frame_pointer_rtx);
4204
4205       /* Some ports cannot access arbitrary stack frames.  */
4206       if (tem == NULL)
4207         {
4208           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4209             warning ("unsupported arg to `__builtin_frame_address'");
4210           else
4211             warning ("unsupported arg to `__builtin_return_address'");
4212           return const0_rtx;
4213         }
4214
4215       /* For __builtin_frame_address, return what we've got.  */
4216       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4217         return tem;
4218
4219       if (GET_CODE (tem) != REG
4220           && ! CONSTANT_P (tem))
4221         tem = copy_to_mode_reg (Pmode, tem);
4222       return tem;
4223     }
4224 }
4225
4226 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4227    we failed and the caller should emit a normal call, otherwise try to get
4228    the result in TARGET, if convenient.  */
4229
4230 static rtx
4231 expand_builtin_alloca (tree arglist, rtx target)
4232 {
4233   rtx op0;
4234   rtx result;
4235
4236   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4237     return 0;
4238
4239   /* Compute the argument.  */
4240   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4241
4242   /* Allocate the desired space.  */
4243   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4244   result = convert_memory_address (ptr_mode, result);
4245
4246   return result;
4247 }
4248
4249 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4250    Return 0 if a normal call should be emitted rather than expanding the
4251    function in-line.  If convenient, the result should be placed in TARGET.
4252    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4253
4254 static rtx
4255 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4256                      rtx subtarget, optab op_optab)
4257 {
4258   rtx op0;
4259   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4260     return 0;
4261
4262   /* Compute the argument.  */
4263   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4264   /* Compute op, into TARGET if possible.
4265      Set TARGET to wherever the result comes back.  */
4266   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4267                         op_optab, op0, target, 1);
4268   if (target == 0)
4269     abort ();
4270
4271   return convert_to_mode (target_mode, target, 0);
4272 }
4273
4274 /* If the string passed to fputs is a constant and is one character
4275    long, we attempt to transform this call into __builtin_fputc().  */
4276
4277 static rtx
4278 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4279 {
4280   tree len, fn;
4281   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4282     : implicit_built_in_decls[BUILT_IN_FPUTC];
4283   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4284     : implicit_built_in_decls[BUILT_IN_FWRITE];
4285
4286   /* If the return value is used, or the replacement _DECL isn't
4287      initialized, don't do the transformation.  */
4288   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4289     return 0;
4290
4291   /* Verify the arguments in the original call.  */
4292   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4293     return 0;
4294
4295   /* Get the length of the string passed to fputs.  If the length
4296      can't be determined, punt.  */
4297   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4298       || TREE_CODE (len) != INTEGER_CST)
4299     return 0;
4300
4301   switch (compare_tree_int (len, 1))
4302     {
4303     case -1: /* length is 0, delete the call entirely .  */
4304       {
4305         /* Evaluate and ignore the argument in case it has
4306            side-effects.  */
4307         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4308                      VOIDmode, EXPAND_NORMAL);
4309         return const0_rtx;
4310       }
4311     case 0: /* length is 1, call fputc.  */
4312       {
4313         const char *p = c_getstr (TREE_VALUE (arglist));
4314
4315         if (p != NULL)
4316           {
4317             /* New argument list transforming fputs(string, stream) to
4318                fputc(string[0], stream).  */
4319             arglist =
4320               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4321             arglist =
4322               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4323             fn = fn_fputc;
4324             break;
4325           }
4326       }
4327       /* FALLTHROUGH */
4328     case 1: /* length is greater than 1, call fwrite.  */
4329       {
4330         tree string_arg;
4331
4332         /* If optimizing for size keep fputs.  */
4333         if (optimize_size)
4334           return 0;
4335         string_arg = TREE_VALUE (arglist);
4336         /* New argument list transforming fputs(string, stream) to
4337            fwrite(string, 1, len, stream).  */
4338         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4339         arglist = tree_cons (NULL_TREE, len, arglist);
4340         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4341         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4342         fn = fn_fwrite;
4343         break;
4344       }
4345     default:
4346       abort ();
4347     }
4348
4349   return expand_expr (build_function_call_expr (fn, arglist),
4350                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4351 }
4352
4353 /* Expand a call to __builtin_expect.  We return our argument and emit a
4354    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4355    a non-jump context.  */
4356
4357 static rtx
4358 expand_builtin_expect (tree arglist, rtx target)
4359 {
4360   tree exp, c;
4361   rtx note, rtx_c;
4362
4363   if (arglist == NULL_TREE
4364       || TREE_CHAIN (arglist) == NULL_TREE)
4365     return const0_rtx;
4366   exp = TREE_VALUE (arglist);
4367   c = TREE_VALUE (TREE_CHAIN (arglist));
4368
4369   if (TREE_CODE (c) != INTEGER_CST)
4370     {
4371       error ("second arg to `__builtin_expect' must be a constant");
4372       c = integer_zero_node;
4373     }
4374
4375   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4376
4377   /* Don't bother with expected value notes for integral constants.  */
4378   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4379     {
4380       /* We do need to force this into a register so that we can be
4381          moderately sure to be able to correctly interpret the branch
4382          condition later.  */
4383       target = force_reg (GET_MODE (target), target);
4384
4385       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4386
4387       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4388       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4389     }
4390
4391   return target;
4392 }
4393
4394 /* Like expand_builtin_expect, except do this in a jump context.  This is
4395    called from do_jump if the conditional is a __builtin_expect.  Return either
4396    a list of insns to emit the jump or NULL if we cannot optimize
4397    __builtin_expect.  We need to optimize this at jump time so that machines
4398    like the PowerPC don't turn the test into a SCC operation, and then jump
4399    based on the test being 0/1.  */
4400
4401 rtx
4402 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4403 {
4404   tree arglist = TREE_OPERAND (exp, 1);
4405   tree arg0 = TREE_VALUE (arglist);
4406   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4407   rtx ret = NULL_RTX;
4408
4409   /* Only handle __builtin_expect (test, 0) and
4410      __builtin_expect (test, 1).  */
4411   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4412       && (integer_zerop (arg1) || integer_onep (arg1)))
4413     {
4414       int num_jumps = 0;
4415       int save_pending_stack_adjust = pending_stack_adjust;
4416       rtx insn;
4417
4418       /* If we fail to locate an appropriate conditional jump, we'll
4419          fall back to normal evaluation.  Ensure that the expression
4420          can be re-evaluated.  */
4421       switch (unsafe_for_reeval (arg0))
4422         {
4423         case 0: /* Safe.  */
4424           break;
4425
4426         case 1: /* Mildly unsafe.  */
4427           arg0 = unsave_expr (arg0);
4428           break;
4429
4430         case 2: /* Wildly unsafe.  */
4431           return NULL_RTX;
4432         }
4433
4434       /* Expand the jump insns.  */
4435       start_sequence ();
4436       do_jump (arg0, if_false_label, if_true_label);
4437       ret = get_insns ();
4438       end_sequence ();
4439
4440       /* Now that the __builtin_expect has been validated, go through and add
4441          the expect's to each of the conditional jumps.  If we run into an
4442          error, just give up and generate the 'safe' code of doing a SCC
4443          operation and then doing a branch on that.  */
4444       insn = ret;
4445       while (insn != NULL_RTX)
4446         {
4447           rtx next = NEXT_INSN (insn);
4448
4449           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4450             {
4451               rtx ifelse = SET_SRC (pc_set (insn));
4452               rtx label;
4453               int taken;
4454
4455               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4456                 {
4457                   taken = 1;
4458                   label = XEXP (XEXP (ifelse, 1), 0);
4459                 }
4460               /* An inverted jump reverses the probabilities.  */
4461               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4462                 {
4463                   taken = 0;
4464                   label = XEXP (XEXP (ifelse, 2), 0);
4465                 }
4466               /* We shouldn't have to worry about conditional returns during
4467                  the expansion stage, but handle it gracefully anyway.  */
4468               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4469                 {
4470                   taken = 1;
4471                   label = NULL_RTX;
4472                 }
4473               /* An inverted return reverses the probabilities.  */
4474               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4475                 {
4476                   taken = 0;
4477                   label = NULL_RTX;
4478                 }
4479               else
4480                 goto do_next_insn;
4481
4482               /* If the test is expected to fail, reverse the
4483                  probabilities.  */
4484               if (integer_zerop (arg1))
4485                 taken = 1 - taken;
4486
4487               /* If we are jumping to the false label, reverse the
4488                  probabilities.  */
4489               if (label == NULL_RTX)
4490                 ;               /* conditional return */
4491               else if (label == if_false_label)
4492                 taken = 1 - taken;
4493               else if (label != if_true_label)
4494                 goto do_next_insn;
4495
4496               num_jumps++;
4497               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4498             }
4499
4500         do_next_insn:
4501           insn = next;
4502         }
4503
4504       /* If no jumps were modified, fail and do __builtin_expect the normal
4505          way.  */
4506       if (num_jumps == 0)
4507         {
4508           ret = NULL_RTX;
4509           pending_stack_adjust = save_pending_stack_adjust;
4510         }
4511     }
4512
4513   return ret;
4514 }
4515
4516 void
4517 expand_builtin_trap (void)
4518 {
4519 #ifdef HAVE_trap
4520   if (HAVE_trap)
4521     emit_insn (gen_trap ());
4522   else
4523 #endif
4524     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4525   emit_barrier ();
4526 }
4527
4528 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4529    Return 0 if a normal call should be emitted rather than expanding
4530    the function inline.  If convenient, the result should be placed
4531    in TARGET.  SUBTARGET may be used as the target for computing
4532    the operand.  */
4533
4534 static rtx
4535 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4536 {
4537   enum machine_mode mode;
4538   tree arg;
4539   rtx op0;
4540
4541   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4542     return 0;
4543
4544   arg = TREE_VALUE (arglist);
4545   mode = TYPE_MODE (TREE_TYPE (arg));
4546   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4547   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4548 }
4549
4550 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4551    Return 0 if a normal call should be emitted rather than expanding
4552    the function inline.  If convenient, the result should be placed
4553    in target.  */
4554
4555 static rtx
4556 expand_builtin_cabs (tree arglist, rtx target)
4557 {
4558   enum machine_mode mode;
4559   tree arg;
4560   rtx op0;
4561
4562   if (arglist == 0 || TREE_CHAIN (arglist))
4563     return 0;
4564   arg = TREE_VALUE (arglist);
4565   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4566       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4567     return 0;
4568
4569   mode = TYPE_MODE (TREE_TYPE (arg));
4570   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4571   return expand_complex_abs (mode, op0, target, 0);
4572 }
4573
4574 /* Create a new constant string literal and return a char* pointer to it.
4575    The STRING_CST value is the LEN characters at STR.  */
4576 static tree
4577 build_string_literal (int len, const char *str)
4578 {
4579   tree t, elem, index, type;
4580
4581   t = build_string (len, str);
4582   elem = build_type_variant (char_type_node, 1, 0);
4583   index = build_index_type (build_int_2 (len - 1, 0));
4584   type = build_array_type (elem, index);
4585   TREE_TYPE (t) = type;
4586   TREE_CONSTANT (t) = 1;
4587   TREE_READONLY (t) = 1;
4588   TREE_STATIC (t) = 1;
4589
4590   type = build_pointer_type (type);
4591   t = build1 (ADDR_EXPR, type, t);
4592
4593   type = build_pointer_type (elem);
4594   t = build1 (NOP_EXPR, type, t);
4595   return t;
4596 }
4597
4598 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4599    Return 0 if a normal call should be emitted rather than transforming
4600    the function inline.  If convenient, the result should be placed in
4601    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
4602    call.  */
4603 static rtx
4604 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4605                        bool unlocked)
4606 {
4607   tree fn_putchar = unlocked
4608                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4609                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4610   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4611                           : implicit_built_in_decls[BUILT_IN_PUTS];
4612   const char *fmt_str;
4613   tree fn, fmt, arg;
4614
4615   /* If the return value is used, don't do the transformation.  */
4616   if (target != const0_rtx)
4617     return 0;
4618
4619   /* Verify the required arguments in the original call.  */
4620   if (! arglist)
4621     return 0;
4622   fmt = TREE_VALUE (arglist);
4623   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4624     return 0;
4625   arglist = TREE_CHAIN (arglist);
4626
4627   /* Check whether the format is a literal string constant.  */
4628   fmt_str = c_getstr (fmt);
4629   if (fmt_str == NULL)
4630     return 0;
4631
4632   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4633   if (strcmp (fmt_str, "%s\n") == 0)
4634     {
4635       if (! arglist
4636           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4637           || TREE_CHAIN (arglist))
4638         return 0;
4639       fn = fn_puts;
4640     }
4641   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4642   else if (strcmp (fmt_str, "%c") == 0)
4643     {
4644       if (! arglist
4645           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4646           || TREE_CHAIN (arglist))
4647         return 0;
4648       fn = fn_putchar;
4649     }
4650   else
4651     {
4652       /* We can't handle anything else with % args or %% ... yet.  */
4653       if (strchr (fmt_str, '%'))
4654         return 0;
4655
4656       if (arglist)
4657         return 0;
4658
4659       /* If the format specifier was "", printf does nothing.  */
4660       if (fmt_str[0] == '\0')
4661         return const0_rtx;
4662       /* If the format specifier has length of 1, call putchar.  */
4663       if (fmt_str[1] == '\0')
4664         {
4665           /* Given printf("c"), (where c is any one character,)
4666              convert "c"[0] to an int and pass that to the replacement
4667              function.  */
4668           arg = build_int_2 (fmt_str[0], 0);
4669           arglist = build_tree_list (NULL_TREE, arg);
4670           fn = fn_putchar;
4671         }
4672       else
4673         {
4674           /* If the format specifier was "string\n", call puts("string").  */
4675           size_t len = strlen (fmt_str);
4676           if (fmt_str[len - 1] == '\n')
4677             {
4678               /* Create a NUL-terminated string that's one char shorter
4679                  than the original, stripping off the trailing '\n'.  */
4680               char *newstr = (char *) alloca (len);
4681               memcpy (newstr, fmt_str, len - 1);
4682               newstr[len - 1] = 0;
4683
4684               arg = build_string_literal (len, newstr);
4685               arglist = build_tree_list (NULL_TREE, arg);
4686               fn = fn_puts;
4687             }
4688           else
4689             /* We'd like to arrange to call fputs(string,stdout) here,
4690                but we need stdout and don't have a way to get it yet.  */
4691             return 0;
4692         }
4693     }
4694
4695   if (!fn)
4696     return 0;
4697   return expand_expr (build_function_call_expr (fn, arglist),
4698                       target, mode, EXPAND_NORMAL);
4699 }
4700
4701 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4702    Return 0 if a normal call should be emitted rather than transforming
4703    the function inline.  If convenient, the result should be placed in
4704    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
4705    call.  */
4706 static rtx
4707 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4708                         bool unlocked)
4709 {
4710   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4711                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4712   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4713                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4714   const char *fmt_str;
4715   tree fn, fmt, fp, arg;
4716
4717   /* If the return value is used, don't do the transformation.  */
4718   if (target != const0_rtx)
4719     return 0;
4720
4721   /* Verify the required arguments in the original call.  */
4722   if (! arglist)
4723     return 0;
4724   fp = TREE_VALUE (arglist);
4725   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4726     return 0;
4727   arglist = TREE_CHAIN (arglist);
4728   if (! arglist)
4729     return 0;
4730   fmt = TREE_VALUE (arglist);
4731   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4732     return 0;
4733   arglist = TREE_CHAIN (arglist);
4734
4735   /* Check whether the format is a literal string constant.  */
4736   fmt_str = c_getstr (fmt);
4737   if (fmt_str == NULL)
4738     return 0;
4739
4740   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4741   if (strcmp (fmt_str, "%s") == 0)
4742     {
4743       if (! arglist
4744           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4745           || TREE_CHAIN (arglist))
4746         return 0;
4747       arg = TREE_VALUE (arglist);
4748       arglist = build_tree_list (NULL_TREE, fp);
4749       arglist = tree_cons (NULL_TREE, arg, arglist);
4750       fn = fn_fputs;
4751     }
4752   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4753   else if (strcmp (fmt_str, "%c") == 0)
4754     {
4755       if (! arglist
4756           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_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_fputc;
4763     }
4764   else
4765     {
4766       /* We can't handle anything else with % args or %% ... yet.  */
4767       if (strchr (fmt_str, '%'))
4768         return 0;
4769
4770       if (arglist)
4771         return 0;
4772
4773       /* If the format specifier was "", fprintf does nothing.  */
4774       if (fmt_str[0] == '\0')
4775         {
4776           /* Evaluate and ignore FILE* argument for side-effects.  */
4777           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4778           return const0_rtx;
4779         }
4780
4781       /* When "string" doesn't contain %, replace all cases of
4782          fprintf(stream,string) with fputs(string,stream).  The fputs
4783          builtin will take care of special cases like length == 1.  */
4784       arglist = build_tree_list (NULL_TREE, fp);
4785       arglist = tree_cons (NULL_TREE, fmt, arglist);
4786       fn = fn_fputs;
4787     }
4788
4789   if (!fn)
4790     return 0;
4791   return expand_expr (build_function_call_expr (fn, arglist),
4792                       target, mode, EXPAND_NORMAL);
4793 }
4794
4795 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4796    a normal call should be emitted rather than expanding the function
4797    inline.  If convenient, the result should be placed in TARGET with
4798    mode MODE.  */
4799
4800 static rtx
4801 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4802 {
4803   tree orig_arglist, dest, fmt;
4804   const char *fmt_str;
4805
4806   orig_arglist = arglist;
4807
4808   /* Verify the required arguments in the original call.  */
4809   if (! arglist)
4810     return 0;
4811   dest = TREE_VALUE (arglist);
4812   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4813     return 0;
4814   arglist = TREE_CHAIN (arglist);
4815   if (! arglist)
4816     return 0;
4817   fmt = TREE_VALUE (arglist);
4818   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4819     return 0;
4820   arglist = TREE_CHAIN (arglist);
4821
4822   /* Check whether the format is a literal string constant.  */
4823   fmt_str = c_getstr (fmt);
4824   if (fmt_str == NULL)
4825     return 0;
4826
4827   /* If the format doesn't contain % args or %%, use strcpy.  */
4828   if (strchr (fmt_str, '%') == 0)
4829     {
4830       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4831       tree exp;
4832
4833       if (arglist || ! fn)
4834         return 0;
4835       expand_expr (build_function_call_expr (fn, orig_arglist),
4836                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4837       if (target == const0_rtx)
4838         return const0_rtx;
4839       exp = build_int_2 (strlen (fmt_str), 0);
4840       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4841       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4842     }
4843   /* If the format is "%s", use strcpy if the result isn't used.  */
4844   else if (strcmp (fmt_str, "%s") == 0)
4845     {
4846       tree fn, arg, len;
4847       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4848
4849       if (! fn)
4850         return 0;
4851
4852       if (! arglist || TREE_CHAIN (arglist))
4853         return 0;
4854       arg = TREE_VALUE (arglist);
4855       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4856         return 0;
4857
4858       if (target != const0_rtx)
4859         {
4860           len = c_strlen (arg, 1);
4861           if (! len || TREE_CODE (len) != INTEGER_CST)
4862             return 0;
4863         }
4864       else
4865         len = NULL_TREE;
4866
4867       arglist = build_tree_list (NULL_TREE, arg);
4868       arglist = tree_cons (NULL_TREE, dest, arglist);
4869       expand_expr (build_function_call_expr (fn, arglist),
4870                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4871
4872       if (target == const0_rtx)
4873         return const0_rtx;
4874       return expand_expr (len, target, mode, EXPAND_NORMAL);
4875     }
4876
4877   return 0;
4878 }
4879 \f
4880 /* Expand an expression EXP that calls a built-in function,
4881    with result going to TARGET if that's convenient
4882    (and in mode MODE if that's convenient).
4883    SUBTARGET may be used as the target for computing one of EXP's operands.
4884    IGNORE is nonzero if the value is to be ignored.  */
4885
4886 rtx
4887 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4888                 int ignore)
4889 {
4890   tree fndecl = get_callee_fndecl (exp);
4891   tree arglist = TREE_OPERAND (exp, 1);
4892   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4893   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4894
4895   /* Perform postincrements before expanding builtin functions.  */
4896   emit_queue ();
4897
4898   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4899     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4900
4901   /* When not optimizing, generate calls to library functions for a certain
4902      set of builtins.  */
4903   if (!optimize
4904       && !CALLED_AS_BUILT_IN (fndecl)
4905       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4906       && fcode != BUILT_IN_ALLOCA)
4907     return expand_call (exp, target, ignore);
4908
4909   /* The built-in function expanders test for target == const0_rtx
4910      to determine whether the function's result will be ignored.  */
4911   if (ignore)
4912     target = const0_rtx;
4913
4914   /* If the result of a pure or const built-in function is ignored, and
4915      none of its arguments are volatile, we can avoid expanding the
4916      built-in call and just evaluate the arguments for side-effects.  */
4917   if (target == const0_rtx
4918       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4919     {
4920       bool volatilep = false;
4921       tree arg;
4922
4923       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4924         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4925           {
4926             volatilep = true;
4927             break;
4928           }
4929
4930       if (! volatilep)
4931         {
4932           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4933             expand_expr (TREE_VALUE (arg), const0_rtx,
4934                          VOIDmode, EXPAND_NORMAL);
4935           return const0_rtx;
4936         }
4937     }
4938
4939   switch (fcode)
4940     {
4941     case BUILT_IN_ABS:
4942     case BUILT_IN_LABS:
4943     case BUILT_IN_LLABS:
4944     case BUILT_IN_IMAXABS:
4945       /* build_function_call changes these into ABS_EXPR.  */
4946       abort ();
4947
4948     case BUILT_IN_FABS:
4949     case BUILT_IN_FABSF:
4950     case BUILT_IN_FABSL:
4951       target = expand_builtin_fabs (arglist, target, subtarget);
4952       if (target)
4953         return target;
4954       break;
4955
4956     case BUILT_IN_CABS:
4957     case BUILT_IN_CABSF:
4958     case BUILT_IN_CABSL:
4959       if (flag_unsafe_math_optimizations)
4960         {
4961           target = expand_builtin_cabs (arglist, target);
4962           if (target)
4963             return target;
4964         }
4965       break;
4966
4967     case BUILT_IN_CONJ:
4968     case BUILT_IN_CONJF:
4969     case BUILT_IN_CONJL:
4970     case BUILT_IN_CREAL:
4971     case BUILT_IN_CREALF:
4972     case BUILT_IN_CREALL:
4973     case BUILT_IN_CIMAG:
4974     case BUILT_IN_CIMAGF:
4975     case BUILT_IN_CIMAGL:
4976       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4977          and IMAGPART_EXPR.  */
4978       abort ();
4979
4980     case BUILT_IN_SIN:
4981     case BUILT_IN_SINF:
4982     case BUILT_IN_SINL:
4983     case BUILT_IN_COS:
4984     case BUILT_IN_COSF:
4985     case BUILT_IN_COSL:
4986     case BUILT_IN_EXP:
4987     case BUILT_IN_EXPF:
4988     case BUILT_IN_EXPL:
4989     case BUILT_IN_LOG:
4990     case BUILT_IN_LOGF:
4991     case BUILT_IN_LOGL:
4992     case BUILT_IN_TAN:
4993     case BUILT_IN_TANF:
4994     case BUILT_IN_TANL:
4995     case BUILT_IN_ATAN:
4996     case BUILT_IN_ATANF:
4997     case BUILT_IN_ATANL:
4998       /* Treat these like sqrt only if unsafe math optimizations are allowed,
4999          because of possible accuracy problems.  */
5000       if (! flag_unsafe_math_optimizations)
5001         break;
5002     case BUILT_IN_SQRT:
5003     case BUILT_IN_SQRTF:
5004     case BUILT_IN_SQRTL:
5005     case BUILT_IN_FLOOR:
5006     case BUILT_IN_FLOORF:
5007     case BUILT_IN_FLOORL:
5008     case BUILT_IN_CEIL:
5009     case BUILT_IN_CEILF:
5010     case BUILT_IN_CEILL:
5011     case BUILT_IN_TRUNC:
5012     case BUILT_IN_TRUNCF:
5013     case BUILT_IN_TRUNCL:
5014     case BUILT_IN_ROUND:
5015     case BUILT_IN_ROUNDF:
5016     case BUILT_IN_ROUNDL:
5017     case BUILT_IN_NEARBYINT:
5018     case BUILT_IN_NEARBYINTF:
5019     case BUILT_IN_NEARBYINTL:
5020       target = expand_builtin_mathfn (exp, target, subtarget);
5021       if (target)
5022         return target;
5023       break;
5024
5025     case BUILT_IN_POW:
5026     case BUILT_IN_POWF:
5027     case BUILT_IN_POWL:
5028       if (! flag_unsafe_math_optimizations)
5029         break;
5030       target = expand_builtin_pow (exp, target, subtarget);
5031       if (target)
5032         return target;
5033       break;
5034
5035     case BUILT_IN_ATAN2:
5036     case BUILT_IN_ATAN2F:
5037     case BUILT_IN_ATAN2L:
5038       if (! flag_unsafe_math_optimizations)
5039         break;
5040       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5041       if (target)
5042         return target;
5043       break;
5044
5045     case BUILT_IN_APPLY_ARGS:
5046       return expand_builtin_apply_args ();
5047
5048       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5049          FUNCTION with a copy of the parameters described by
5050          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5051          allocated on the stack into which is stored all the registers
5052          that might possibly be used for returning the result of a
5053          function.  ARGUMENTS is the value returned by
5054          __builtin_apply_args.  ARGSIZE is the number of bytes of
5055          arguments that must be copied.  ??? How should this value be
5056          computed?  We'll also need a safe worst case value for varargs
5057          functions.  */
5058     case BUILT_IN_APPLY:
5059       if (!validate_arglist (arglist, POINTER_TYPE,
5060                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5061           && !validate_arglist (arglist, REFERENCE_TYPE,
5062                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5063         return const0_rtx;
5064       else
5065         {
5066           int i;
5067           tree t;
5068           rtx ops[3];
5069
5070           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5071             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5072
5073           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5074         }
5075
5076       /* __builtin_return (RESULT) causes the function to return the
5077          value described by RESULT.  RESULT is address of the block of
5078          memory returned by __builtin_apply.  */
5079     case BUILT_IN_RETURN:
5080       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5081         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5082                                             NULL_RTX, VOIDmode, 0));
5083       return const0_rtx;
5084
5085     case BUILT_IN_SAVEREGS:
5086       return expand_builtin_saveregs ();
5087
5088     case BUILT_IN_ARGS_INFO:
5089       return expand_builtin_args_info (arglist);
5090
5091       /* Return the address of the first anonymous stack arg.  */
5092     case BUILT_IN_NEXT_ARG:
5093       return expand_builtin_next_arg (arglist);
5094
5095     case BUILT_IN_CLASSIFY_TYPE:
5096       return expand_builtin_classify_type (arglist);
5097
5098     case BUILT_IN_CONSTANT_P:
5099       return expand_builtin_constant_p (arglist, target_mode);
5100
5101     case BUILT_IN_FRAME_ADDRESS:
5102     case BUILT_IN_RETURN_ADDRESS:
5103       return expand_builtin_frame_address (fndecl, arglist);
5104
5105     /* Returns the address of the area where the structure is returned.
5106        0 otherwise.  */
5107     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5108       if (arglist != 0
5109           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5110           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5111         return const0_rtx;
5112       else
5113         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5114
5115     case BUILT_IN_ALLOCA:
5116       target = expand_builtin_alloca (arglist, target);
5117       if (target)
5118         return target;
5119       break;
5120
5121     case BUILT_IN_FFS:
5122     case BUILT_IN_FFSL:
5123     case BUILT_IN_FFSLL:
5124       target = expand_builtin_unop (target_mode, arglist, target,
5125                                     subtarget, ffs_optab);
5126       if (target)
5127         return target;
5128       break;
5129
5130     case BUILT_IN_CLZ:
5131     case BUILT_IN_CLZL:
5132     case BUILT_IN_CLZLL:
5133       target = expand_builtin_unop (target_mode, arglist, target,
5134                                     subtarget, clz_optab);
5135       if (target)
5136         return target;
5137       break;
5138
5139     case BUILT_IN_CTZ:
5140     case BUILT_IN_CTZL:
5141     case BUILT_IN_CTZLL:
5142       target = expand_builtin_unop (target_mode, arglist, target,
5143                                     subtarget, ctz_optab);
5144       if (target)
5145         return target;
5146       break;
5147
5148     case BUILT_IN_POPCOUNT:
5149     case BUILT_IN_POPCOUNTL:
5150     case BUILT_IN_POPCOUNTLL:
5151       target = expand_builtin_unop (target_mode, arglist, target,
5152                                     subtarget, popcount_optab);
5153       if (target)
5154         return target;
5155       break;
5156
5157     case BUILT_IN_PARITY:
5158     case BUILT_IN_PARITYL:
5159     case BUILT_IN_PARITYLL:
5160       target = expand_builtin_unop (target_mode, arglist, target,
5161                                     subtarget, parity_optab);
5162       if (target)
5163         return target;
5164       break;
5165
5166     case BUILT_IN_STRLEN:
5167       target = expand_builtin_strlen (arglist, target, target_mode);
5168       if (target)
5169         return target;
5170       break;
5171
5172     case BUILT_IN_STRCPY:
5173       target = expand_builtin_strcpy (arglist, target, mode);
5174       if (target)
5175         return target;
5176       break;
5177
5178     case BUILT_IN_STRNCPY:
5179       target = expand_builtin_strncpy (arglist, target, mode);
5180       if (target)
5181         return target;
5182       break;
5183
5184     case BUILT_IN_STPCPY:
5185       target = expand_builtin_stpcpy (arglist, target, mode);
5186       if (target)
5187         return target;
5188       break;
5189
5190     case BUILT_IN_STRCAT:
5191       target = expand_builtin_strcat (arglist, target, mode);
5192       if (target)
5193         return target;
5194       break;
5195
5196     case BUILT_IN_STRNCAT:
5197       target = expand_builtin_strncat (arglist, target, mode);
5198       if (target)
5199         return target;
5200       break;
5201
5202     case BUILT_IN_STRSPN:
5203       target = expand_builtin_strspn (arglist, target, mode);
5204       if (target)
5205         return target;
5206       break;
5207
5208     case BUILT_IN_STRCSPN:
5209       target = expand_builtin_strcspn (arglist, target, mode);
5210       if (target)
5211         return target;
5212       break;
5213
5214     case BUILT_IN_STRSTR:
5215       target = expand_builtin_strstr (arglist, target, mode);
5216       if (target)
5217         return target;
5218       break;
5219
5220     case BUILT_IN_STRPBRK:
5221       target = expand_builtin_strpbrk (arglist, target, mode);
5222       if (target)
5223         return target;
5224       break;
5225
5226     case BUILT_IN_INDEX:
5227     case BUILT_IN_STRCHR:
5228       target = expand_builtin_strchr (arglist, target, mode);
5229       if (target)
5230         return target;
5231       break;
5232
5233     case BUILT_IN_RINDEX:
5234     case BUILT_IN_STRRCHR:
5235       target = expand_builtin_strrchr (arglist, target, mode);
5236       if (target)
5237         return target;
5238       break;
5239
5240     case BUILT_IN_MEMCPY:
5241       target = expand_builtin_memcpy (arglist, target, mode);
5242       if (target)
5243         return target;
5244       break;
5245
5246     case BUILT_IN_MEMPCPY:
5247       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5248       if (target)
5249         return target;
5250       break;
5251
5252     case BUILT_IN_MEMMOVE:
5253       target = expand_builtin_memmove (arglist, target, mode);
5254       if (target)
5255         return target;
5256       break;
5257
5258     case BUILT_IN_BCOPY:
5259       target = expand_builtin_bcopy (arglist);
5260       if (target)
5261         return target;
5262       break;
5263
5264     case BUILT_IN_MEMSET:
5265       target = expand_builtin_memset (arglist, target, mode);
5266       if (target)
5267         return target;
5268       break;
5269
5270     case BUILT_IN_BZERO:
5271       target = expand_builtin_bzero (arglist);
5272       if (target)
5273         return target;
5274       break;
5275
5276     case BUILT_IN_STRCMP:
5277       target = expand_builtin_strcmp (exp, target, mode);
5278       if (target)
5279         return target;
5280       break;
5281
5282     case BUILT_IN_STRNCMP:
5283       target = expand_builtin_strncmp (exp, target, mode);
5284       if (target)
5285         return target;
5286       break;
5287
5288     case BUILT_IN_BCMP:
5289     case BUILT_IN_MEMCMP:
5290       target = expand_builtin_memcmp (exp, arglist, target, mode);
5291       if (target)
5292         return target;
5293       break;
5294
5295     case BUILT_IN_SETJMP:
5296       target = expand_builtin_setjmp (arglist, target);
5297       if (target)
5298         return target;
5299       break;
5300
5301       /* __builtin_longjmp is passed a pointer to an array of five words.
5302          It's similar to the C library longjmp function but works with
5303          __builtin_setjmp above.  */
5304     case BUILT_IN_LONGJMP:
5305       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5306         break;
5307       else
5308         {
5309           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5310                                       VOIDmode, 0);
5311           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5312                                    NULL_RTX, VOIDmode, 0);
5313
5314           if (value != const1_rtx)
5315             {
5316               error ("__builtin_longjmp second argument must be 1");
5317               return const0_rtx;
5318             }
5319
5320           expand_builtin_longjmp (buf_addr, value);
5321           return const0_rtx;
5322         }
5323
5324     case BUILT_IN_TRAP:
5325       expand_builtin_trap ();
5326       return const0_rtx;
5327
5328     case BUILT_IN_PRINTF:
5329       target = expand_builtin_printf (arglist, target, mode, false);
5330       if (target)
5331         return target;
5332       break;
5333
5334     case BUILT_IN_PRINTF_UNLOCKED:
5335       target = expand_builtin_printf (arglist, target, mode, true);
5336       if (target)
5337         return target;
5338       break;
5339
5340     case BUILT_IN_FPUTS:
5341       target = expand_builtin_fputs (arglist, target, false);
5342       if (target)
5343         return target;
5344       break;
5345
5346     case BUILT_IN_FPUTS_UNLOCKED:
5347       target = expand_builtin_fputs (arglist, target, true);
5348       if (target)
5349         return target;
5350       break;
5351
5352     case BUILT_IN_FPRINTF:
5353       target = expand_builtin_fprintf (arglist, target, mode, false);
5354       if (target)
5355         return target;
5356       break;
5357
5358     case BUILT_IN_FPRINTF_UNLOCKED:
5359       target = expand_builtin_fprintf (arglist, target, mode, true);
5360       if (target)
5361         return target;
5362       break;
5363
5364     case BUILT_IN_SPRINTF:
5365       target = expand_builtin_sprintf (arglist, target, mode);
5366       if (target)
5367         return target;
5368       break;
5369
5370       /* Various hooks for the DWARF 2 __throw routine.  */
5371     case BUILT_IN_UNWIND_INIT:
5372       expand_builtin_unwind_init ();
5373       return const0_rtx;
5374     case BUILT_IN_DWARF_CFA:
5375       return virtual_cfa_rtx;
5376 #ifdef DWARF2_UNWIND_INFO
5377     case BUILT_IN_DWARF_SP_COLUMN:
5378       return expand_builtin_dwarf_sp_column ();
5379     case BUILT_IN_INIT_DWARF_REG_SIZES:
5380       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5381       return const0_rtx;
5382 #endif
5383     case BUILT_IN_FROB_RETURN_ADDR:
5384       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5385     case BUILT_IN_EXTRACT_RETURN_ADDR:
5386       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5387     case BUILT_IN_EH_RETURN:
5388       expand_builtin_eh_return (TREE_VALUE (arglist),
5389                                 TREE_VALUE (TREE_CHAIN (arglist)));
5390       return const0_rtx;
5391 #ifdef EH_RETURN_DATA_REGNO
5392     case BUILT_IN_EH_RETURN_DATA_REGNO:
5393       return expand_builtin_eh_return_data_regno (arglist);
5394 #endif
5395     case BUILT_IN_VA_START:
5396     case BUILT_IN_STDARG_START:
5397       return expand_builtin_va_start (arglist);
5398     case BUILT_IN_VA_END:
5399       return expand_builtin_va_end (arglist);
5400     case BUILT_IN_VA_COPY:
5401       return expand_builtin_va_copy (arglist);
5402     case BUILT_IN_EXPECT:
5403       return expand_builtin_expect (arglist, target);
5404     case BUILT_IN_PREFETCH:
5405       expand_builtin_prefetch (arglist);
5406       return const0_rtx;
5407
5408
5409     default:    /* just do library call, if unknown builtin */
5410       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5411         error ("built-in function `%s' not currently supported",
5412                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5413     }
5414
5415   /* The switch statement above can drop through to cause the function
5416      to be called normally.  */
5417   return expand_call (exp, target, ignore);
5418 }
5419
5420 /* Determine whether a tree node represents a call to a built-in
5421    function.  If the tree T is a call to a built-in function with
5422    the right number of arguments of the appropriate types, return
5423    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5424    Otherwise the return value is END_BUILTINS.  */
5425
5426 enum built_in_function
5427 builtin_mathfn_code (tree t)
5428 {
5429   tree fndecl, arglist, parmlist;
5430   tree argtype, parmtype;
5431
5432   if (TREE_CODE (t) != CALL_EXPR
5433       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5434     return END_BUILTINS;
5435
5436   fndecl = get_callee_fndecl (t);
5437   if (fndecl == NULL_TREE
5438       || TREE_CODE (fndecl) != FUNCTION_DECL
5439       || ! DECL_BUILT_IN (fndecl)
5440       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5441     return END_BUILTINS;
5442
5443   arglist = TREE_OPERAND (t, 1);
5444   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5445   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5446     {
5447       /* If a function doesn't take a variable number of arguments,
5448          the last element in the list will have type `void'.  */
5449       parmtype = TREE_VALUE (parmlist);
5450       if (VOID_TYPE_P (parmtype))
5451         {
5452           if (arglist)
5453             return END_BUILTINS;
5454           return DECL_FUNCTION_CODE (fndecl);
5455         }
5456
5457       if (! arglist)
5458         return END_BUILTINS;
5459
5460       argtype = TREE_TYPE (TREE_VALUE (arglist));
5461
5462       if (SCALAR_FLOAT_TYPE_P (parmtype))
5463         {
5464           if (! SCALAR_FLOAT_TYPE_P (argtype))
5465             return END_BUILTINS;
5466         }
5467       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5468         {
5469           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5470             return END_BUILTINS;
5471         }
5472       else if (POINTER_TYPE_P (parmtype))
5473         {
5474           if (! POINTER_TYPE_P (argtype))
5475             return END_BUILTINS;
5476         }
5477       else if (INTEGRAL_TYPE_P (parmtype))
5478         {
5479           if (! INTEGRAL_TYPE_P (argtype))
5480             return END_BUILTINS;
5481         }
5482       else
5483         return END_BUILTINS;
5484
5485       arglist = TREE_CHAIN (arglist);
5486     }
5487
5488   /* Variable-length argument list.  */
5489   return DECL_FUNCTION_CODE (fndecl);
5490 }
5491
5492 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5493    constant.  ARGLIST is the argument list of the call.  */
5494
5495 static tree
5496 fold_builtin_constant_p (tree arglist)
5497 {
5498   if (arglist == 0)
5499     return 0;
5500
5501   arglist = TREE_VALUE (arglist);
5502
5503   /* We return 1 for a numeric type that's known to be a constant
5504      value at compile-time or for an aggregate type that's a
5505      literal constant.  */
5506   STRIP_NOPS (arglist);
5507
5508   /* If we know this is a constant, emit the constant of one.  */
5509   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5510       || (TREE_CODE (arglist) == CONSTRUCTOR
5511           && TREE_CONSTANT (arglist))
5512       || (TREE_CODE (arglist) == ADDR_EXPR
5513           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5514     return integer_one_node;
5515
5516   /* If this expression has side effects, show we don't know it to be a
5517      constant.  Likewise if it's a pointer or aggregate type since in
5518      those case we only want literals, since those are only optimized
5519      when generating RTL, not later.
5520      And finally, if we are compiling an initializer, not code, we
5521      need to return a definite result now; there's not going to be any
5522      more optimization done.  */
5523   if (TREE_SIDE_EFFECTS (arglist)
5524       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5525       || POINTER_TYPE_P (TREE_TYPE (arglist))
5526       || cfun == 0)
5527     return integer_zero_node;
5528
5529   return 0;
5530 }
5531
5532 /* Fold a call to __builtin_classify_type.  */
5533
5534 static tree
5535 fold_builtin_classify_type (tree arglist)
5536 {
5537   if (arglist == 0)
5538     return build_int_2 (no_type_class, 0);
5539
5540   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5541 }
5542
5543 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5544
5545 static tree
5546 fold_builtin_inf (tree type, int warn)
5547 {
5548   REAL_VALUE_TYPE real;
5549
5550   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5551     warning ("target format does not support infinity");
5552
5553   real_inf (&real);
5554   return build_real (type, real);
5555 }
5556
5557 /* Fold a call to __builtin_nan or __builtin_nans.  */
5558
5559 static tree
5560 fold_builtin_nan (tree arglist, tree type, int quiet)
5561 {
5562   REAL_VALUE_TYPE real;
5563   const char *str;
5564
5565   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5566     return 0;
5567   str = c_getstr (TREE_VALUE (arglist));
5568   if (!str)
5569     return 0;
5570
5571   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5572     return 0;
5573
5574   return build_real (type, real);
5575 }
5576
5577 /* Return true if the floating point expression T has an integer value.
5578    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5579
5580 static bool
5581 integer_valued_real_p (tree t)
5582 {
5583   switch (TREE_CODE (t))
5584     {
5585     case FLOAT_EXPR:
5586       return true;
5587
5588     case ABS_EXPR:
5589     case SAVE_EXPR:
5590     case NON_LVALUE_EXPR:
5591       return integer_valued_real_p (TREE_OPERAND (t, 0));
5592
5593     case COMPOUND_EXPR:
5594     case MODIFY_EXPR:
5595     case BIND_EXPR:
5596       return integer_valued_real_p (TREE_OPERAND (t, 1));
5597
5598     case PLUS_EXPR:
5599     case MINUS_EXPR:
5600     case MULT_EXPR:
5601     case MIN_EXPR:
5602     case MAX_EXPR:
5603       return integer_valued_real_p (TREE_OPERAND (t, 0))
5604              && integer_valued_real_p (TREE_OPERAND (t, 1));
5605
5606     case COND_EXPR:
5607       return integer_valued_real_p (TREE_OPERAND (t, 1))
5608              && integer_valued_real_p (TREE_OPERAND (t, 2));
5609
5610     case REAL_CST:
5611       if (! TREE_CONSTANT_OVERFLOW (t))
5612       {
5613         REAL_VALUE_TYPE c, cint;
5614
5615         c = TREE_REAL_CST (t);
5616         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5617         return real_identical (&c, &cint);
5618       }
5619
5620     case NOP_EXPR:
5621       {
5622         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5623         if (TREE_CODE (type) == INTEGER_TYPE)
5624           return true;
5625         if (TREE_CODE (type) == REAL_TYPE)
5626           return integer_valued_real_p (TREE_OPERAND (t, 0));
5627         break;
5628       }
5629
5630     case CALL_EXPR:
5631       switch (builtin_mathfn_code (t))
5632         {
5633         case BUILT_IN_CEIL:
5634         case BUILT_IN_CEILF:
5635         case BUILT_IN_CEILL:
5636         case BUILT_IN_FLOOR:
5637         case BUILT_IN_FLOORF:
5638         case BUILT_IN_FLOORL:
5639         case BUILT_IN_NEARBYINT:
5640         case BUILT_IN_NEARBYINTF:
5641         case BUILT_IN_NEARBYINTL:
5642         case BUILT_IN_ROUND:
5643         case BUILT_IN_ROUNDF:
5644         case BUILT_IN_ROUNDL:
5645         case BUILT_IN_TRUNC:
5646         case BUILT_IN_TRUNCF:
5647         case BUILT_IN_TRUNCL:
5648           return true;
5649
5650         default:
5651           break;
5652         }
5653       break;
5654
5655     default:
5656       break;
5657     }
5658   return false;
5659 }
5660
5661 /* EXP is assumed to be builtin call where truncation can be propagated
5662    across (for instance floor((double)f) == (double)floorf (f).
5663    Do the transformation.  */
5664
5665 static tree
5666 fold_trunc_transparent_mathfn (tree exp)
5667 {
5668   tree fndecl = get_callee_fndecl (exp);
5669   tree arglist = TREE_OPERAND (exp, 1);
5670   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5671   tree arg;
5672
5673   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5674     return 0;
5675
5676   arg = TREE_VALUE (arglist);
5677   /* Integer rounding functions are idempotent.  */
5678   if (fcode == builtin_mathfn_code (arg))
5679     return arg;
5680
5681   /* If argument is already integer valued, and we don't need to worry
5682      about setting errno, there's no need to perform rounding.  */
5683   if (! flag_errno_math && integer_valued_real_p (arg))
5684     return arg;
5685
5686   if (optimize)
5687     {
5688       tree arg0 = strip_float_extensions (arg);
5689       tree ftype = TREE_TYPE (exp);
5690       tree newtype = TREE_TYPE (arg0);
5691       tree decl;
5692
5693       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5694           && (decl = mathfn_built_in (newtype, fcode)))
5695         {
5696           arglist =
5697             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5698           return convert (ftype,
5699                           build_function_call_expr (decl, arglist));
5700         }
5701     }
5702   return 0;
5703 }
5704
5705 /* Fold function call to builtin cabs, cabsf or cabsl.  FNDECL is the
5706    function's DECL, ARGLIST is the argument list and TYPE is the return
5707    type.  Return NULL_TREE if no simplification can be made.  */
5708
5709 static tree
5710 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5711 {
5712   tree arg;
5713
5714   if (!arglist || TREE_CHAIN (arglist))
5715     return NULL_TREE;
5716
5717   arg = TREE_VALUE (arglist);
5718   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5719       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5720     return NULL_TREE;
5721
5722   /* Evaluate cabs of a constant at compile-time.  */
5723   if (flag_unsafe_math_optimizations
5724       && TREE_CODE (arg) == COMPLEX_CST
5725       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5726       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5727       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5728       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5729     {
5730       REAL_VALUE_TYPE r, i;
5731
5732       r = TREE_REAL_CST (TREE_REALPART (arg));
5733       i = TREE_REAL_CST (TREE_IMAGPART (arg));
5734
5735       real_arithmetic (&r, MULT_EXPR, &r, &r);
5736       real_arithmetic (&i, MULT_EXPR, &i, &i);
5737       real_arithmetic (&r, PLUS_EXPR, &r, &i);
5738       if (real_sqrt (&r, TYPE_MODE (type), &r)
5739           || ! flag_trapping_math)
5740         return build_real (type, r);
5741     }
5742
5743   /* If either part is zero, cabs is fabs of the other.  */
5744   if (TREE_CODE (arg) == COMPLEX_EXPR
5745       && real_zerop (TREE_OPERAND (arg, 0)))
5746     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5747   if (TREE_CODE (arg) == COMPLEX_EXPR
5748       && real_zerop (TREE_OPERAND (arg, 1)))
5749     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5750
5751   if (flag_unsafe_math_optimizations)
5752     {
5753       enum built_in_function fcode;
5754       tree sqrtfn;
5755
5756       fcode = DECL_FUNCTION_CODE (fndecl);
5757       if (fcode == BUILT_IN_CABS)
5758         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5759       else if (fcode == BUILT_IN_CABSF)
5760         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5761       else if (fcode == BUILT_IN_CABSL)
5762         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5763       else
5764         sqrtfn = NULL_TREE;
5765
5766       if (sqrtfn != NULL_TREE)
5767         {
5768           tree rpart, ipart, result, arglist;
5769
5770           arg = save_expr (arg);
5771
5772           rpart = fold (build1 (REALPART_EXPR, type, arg));
5773           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5774
5775           rpart = save_expr (rpart);
5776           ipart = save_expr (ipart);
5777
5778           result = fold (build (PLUS_EXPR, type,
5779                                 fold (build (MULT_EXPR, type,
5780                                              rpart, rpart)),
5781                                 fold (build (MULT_EXPR, type,
5782                                              ipart, ipart))));
5783
5784           arglist = build_tree_list (NULL_TREE, result);
5785           return build_function_call_expr (sqrtfn, arglist);
5786         }
5787     }
5788
5789   return NULL_TREE;
5790 }
5791
5792 /* Fold function call to builtin trunc, truncf or truncl.  Return
5793    NULL_TREE if no simplification can be made.  */
5794
5795 static tree
5796 fold_builtin_trunc (tree exp)
5797 {
5798   tree arglist = TREE_OPERAND (exp, 1);
5799   tree arg;
5800
5801   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5802     return 0;
5803
5804   /* Optimize trunc of constant value.  */
5805   arg = TREE_VALUE (arglist);
5806   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5807     {
5808       REAL_VALUE_TYPE r, x;
5809       tree type = TREE_TYPE (exp);
5810
5811       x = TREE_REAL_CST (arg);
5812       real_trunc (&r, TYPE_MODE (type), &x);
5813       return build_real (type, r);
5814     }
5815
5816   return fold_trunc_transparent_mathfn (exp);
5817 }
5818
5819 /* Fold function call to builtin floor, floorf or floorl.  Return
5820    NULL_TREE if no simplification can be made.  */
5821
5822 static tree
5823 fold_builtin_floor (tree exp)
5824 {
5825   tree arglist = TREE_OPERAND (exp, 1);
5826   tree arg;
5827
5828   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5829     return 0;
5830
5831   /* Optimize floor of constant value.  */
5832   arg = TREE_VALUE (arglist);
5833   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5834     {
5835       REAL_VALUE_TYPE x;
5836
5837       x = TREE_REAL_CST (arg);
5838       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5839         {
5840           tree type = TREE_TYPE (exp);
5841           REAL_VALUE_TYPE r;
5842
5843           real_floor (&r, TYPE_MODE (type), &x);
5844           return build_real (type, r);
5845         }
5846     }
5847
5848   return fold_trunc_transparent_mathfn (exp);
5849 }
5850
5851 /* Fold function call to builtin ceil, ceilf or ceill.  Return
5852    NULL_TREE if no simplification can be made.  */
5853
5854 static tree
5855 fold_builtin_ceil (tree exp)
5856 {
5857   tree arglist = TREE_OPERAND (exp, 1);
5858   tree arg;
5859
5860   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5861     return 0;
5862
5863   /* Optimize ceil of constant value.  */
5864   arg = TREE_VALUE (arglist);
5865   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5866     {
5867       REAL_VALUE_TYPE x;
5868
5869       x = TREE_REAL_CST (arg);
5870       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5871         {
5872           tree type = TREE_TYPE (exp);
5873           REAL_VALUE_TYPE r;
5874
5875           real_ceil (&r, TYPE_MODE (type), &x);
5876           return build_real (type, r);
5877         }
5878     }
5879
5880   return fold_trunc_transparent_mathfn (exp);
5881 }
5882
5883 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
5884    and their long and long long variants (i.e. ffsl and ffsll).
5885    Return NULL_TREE if no simplification can be made.  */
5886
5887 static tree
5888 fold_builtin_bitop (tree exp)
5889 {
5890   tree fndecl = get_callee_fndecl (exp);
5891   tree arglist = TREE_OPERAND (exp, 1);
5892   tree arg;
5893
5894   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
5895     return NULL_TREE;
5896
5897   /* Optimize for constant argument.  */
5898   arg = TREE_VALUE (arglist);
5899   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5900     {
5901       HOST_WIDE_INT hi, width, result;
5902       unsigned HOST_WIDE_INT lo;
5903       tree type, t;
5904
5905       type = TREE_TYPE (arg);
5906       width = TYPE_PRECISION (type);
5907       lo = TREE_INT_CST_LOW (arg);
5908
5909       /* Clear all the bits that are beyond the type's precision.  */
5910       if (width > HOST_BITS_PER_WIDE_INT)
5911         {
5912           hi = TREE_INT_CST_HIGH (arg);
5913           if (width < 2 * HOST_BITS_PER_WIDE_INT)
5914             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
5915         }
5916       else
5917         {
5918           hi = 0;
5919           if (width < HOST_BITS_PER_WIDE_INT)
5920             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
5921         }
5922
5923       switch (DECL_FUNCTION_CODE (fndecl))
5924         {
5925         case BUILT_IN_FFS:
5926         case BUILT_IN_FFSL:
5927         case BUILT_IN_FFSLL:
5928           if (lo != 0)
5929             result = exact_log2 (lo & -lo) + 1;
5930           else if (hi != 0)
5931             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
5932           else
5933             result = 0;
5934           break;
5935
5936         case BUILT_IN_CLZ:
5937         case BUILT_IN_CLZL:
5938         case BUILT_IN_CLZLL:
5939           if (hi != 0)
5940             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
5941           else if (lo != 0)
5942             result = width - floor_log2 (lo) - 1;
5943           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5944             result = width;
5945           break;
5946
5947         case BUILT_IN_CTZ:
5948         case BUILT_IN_CTZL:
5949         case BUILT_IN_CTZLL:
5950           if (lo != 0)
5951             result = exact_log2 (lo & -lo);
5952           else if (hi != 0)
5953             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
5954           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5955             result = width;
5956           break;
5957
5958         case BUILT_IN_POPCOUNT:
5959         case BUILT_IN_POPCOUNTL:
5960         case BUILT_IN_POPCOUNTLL:
5961           result = 0;
5962           while (lo)
5963             result++, lo &= lo - 1;
5964           while (hi)
5965             result++, hi &= hi - 1;
5966           break;
5967
5968         case BUILT_IN_PARITY:
5969         case BUILT_IN_PARITYL:
5970         case BUILT_IN_PARITYLL:
5971           result = 0;
5972           while (lo)
5973             result++, lo &= lo - 1;
5974           while (hi)
5975             result++, hi &= hi - 1;
5976           result &= 1;
5977           break;
5978
5979         default:
5980           abort();
5981         }
5982
5983       t = build_int_2 (result, 0);
5984       TREE_TYPE (t) = TREE_TYPE (exp);
5985       return t;
5986     }
5987
5988   return NULL_TREE;
5989 }
5990
5991 /* Return true if EXPR is the real constant contained in VALUE.  */
5992
5993 static bool
5994 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
5995 {
5996   STRIP_NOPS (expr);
5997
5998   return ((TREE_CODE (expr) == REAL_CST
5999            && ! TREE_CONSTANT_OVERFLOW (expr)
6000            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6001           || (TREE_CODE (expr) == COMPLEX_CST
6002               && real_dconstp (TREE_REALPART (expr), value)
6003               && real_zerop (TREE_IMAGPART (expr))));
6004 }
6005
6006 /* A subroutine of fold_builtin to fold the various logarithmic
6007    functions.  EXP is the CALL_EXPR of a call to a builtin log*
6008    function.  VALUE is the base of the log* function.  */
6009
6010 static tree
6011 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6012 {
6013   tree arglist = TREE_OPERAND (exp, 1);
6014
6015   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6016     {
6017       tree fndecl = get_callee_fndecl (exp);
6018       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6019       tree arg = TREE_VALUE (arglist);
6020       const enum built_in_function fcode = builtin_mathfn_code (arg);
6021         
6022       /* Optimize log*(1.0) = 0.0.  */
6023       if (real_onep (arg))
6024         return build_real (type, dconst0);
6025
6026       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6027          exactly, then only do this if flag_unsafe_math_optimizations.  */
6028       if (exact_real_truncate (TYPE_MODE (type), value)
6029           || flag_unsafe_math_optimizations)
6030         {
6031           const REAL_VALUE_TYPE value_truncate =
6032             real_value_truncate (TYPE_MODE (type), *value);
6033           if (real_dconstp (arg, &value_truncate))
6034             return build_real (type, dconst1);
6035         }
6036       
6037       /* Special case, optimize logN(expN(x)) = x.  */
6038       if (flag_unsafe_math_optimizations
6039           && ((value == &dconste
6040                && (fcode == BUILT_IN_EXP
6041                    || fcode == BUILT_IN_EXPF
6042                    || fcode == BUILT_IN_EXPL))
6043               || (value == &dconst2
6044                   && (fcode == BUILT_IN_EXP2
6045                       || fcode == BUILT_IN_EXP2F
6046                       || fcode == BUILT_IN_EXP2L))
6047               || (value == &dconst10
6048                   && (fcode == BUILT_IN_EXP10
6049                       || fcode == BUILT_IN_EXP10F
6050                       || fcode == BUILT_IN_EXP10L))))
6051         return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6052
6053       /* Optimize log*(func()) for various exponential functions.  We
6054          want to determine the value "x" and the power "exponent" in
6055          order to transform logN(x**exponent) into exponent*logN(x).  */
6056       if (flag_unsafe_math_optimizations)
6057         {
6058           tree exponent = 0, x = 0;
6059           
6060           switch (fcode)
6061           {
6062           case BUILT_IN_EXP:
6063           case BUILT_IN_EXPF:
6064           case BUILT_IN_EXPL:
6065             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6066             x = build_real (type,
6067                             real_value_truncate (TYPE_MODE (type), dconste));
6068             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6069             break;
6070           case BUILT_IN_EXP2:
6071           case BUILT_IN_EXP2F:
6072           case BUILT_IN_EXP2L:
6073             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6074             x = build_real (type, dconst2);
6075             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6076             break;
6077           case BUILT_IN_EXP10:
6078           case BUILT_IN_EXP10F:
6079           case BUILT_IN_EXP10L:
6080           case BUILT_IN_POW10:
6081           case BUILT_IN_POW10F:
6082           case BUILT_IN_POW10L:
6083             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6084             x = build_real (type, dconst10);
6085             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6086             break;
6087           case BUILT_IN_SQRT:
6088           case BUILT_IN_SQRTF:
6089           case BUILT_IN_SQRTL:
6090             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6091             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6092             exponent = build_real (type, dconsthalf);
6093             break;
6094           case BUILT_IN_CBRT:
6095           case BUILT_IN_CBRTF:
6096           case BUILT_IN_CBRTL:
6097             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6098             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6099             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6100                                                               dconstthird));
6101             break;
6102           case BUILT_IN_POW:
6103           case BUILT_IN_POWF:
6104           case BUILT_IN_POWL:
6105             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6106             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6107             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6108             break;
6109           default:
6110             break;
6111           }
6112
6113           /* Now perform the optimization.  */
6114           if (x && exponent)
6115             {
6116               tree logfn;
6117               arglist = build_tree_list (NULL_TREE, x);
6118               logfn = build_function_call_expr (fndecl, arglist);
6119               return fold (build (MULT_EXPR, type, exponent, logfn));
6120             }
6121         }
6122     }
6123
6124   return 0;
6125 }
6126           
6127 /* A subroutine of fold_builtin to fold the various exponent
6128    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6129    VALUE is the value which will be raised to a power.  */
6130
6131 static tree
6132 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6133 {
6134   tree arglist = TREE_OPERAND (exp, 1);
6135
6136   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6137     {
6138       tree fndecl = get_callee_fndecl (exp);
6139       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6140       tree arg = TREE_VALUE (arglist);
6141
6142       /* Optimize exp*(0.0) = 1.0.  */
6143       if (real_zerop (arg))
6144         return build_real (type, dconst1);
6145
6146       /* Optimize expN(1.0) = N.  */
6147       if (real_onep (arg))
6148         {
6149           REAL_VALUE_TYPE cst;
6150
6151           real_convert (&cst, TYPE_MODE (type), value);
6152           return build_real (type, cst);
6153         }
6154
6155       /* Attempt to evaluate expN(integer) at compile-time.  */
6156       if (flag_unsafe_math_optimizations
6157           && TREE_CODE (arg) == REAL_CST
6158           && ! TREE_CONSTANT_OVERFLOW (arg))
6159         {
6160           REAL_VALUE_TYPE cint;
6161           REAL_VALUE_TYPE c;
6162           HOST_WIDE_INT n;
6163
6164           c = TREE_REAL_CST (arg);
6165           n = real_to_integer (&c);
6166           real_from_integer (&cint, VOIDmode, n,
6167                              n < 0 ? -1 : 0, 0);
6168           if (real_identical (&c, &cint))
6169             {
6170               REAL_VALUE_TYPE x;
6171
6172               real_powi (&x, TYPE_MODE (type), value, n);
6173               return build_real (type, x);
6174             }
6175         }
6176
6177       /* Optimize expN(logN(x)) = x.  */
6178       if (flag_unsafe_math_optimizations)
6179         {
6180           const enum built_in_function fcode = builtin_mathfn_code (arg);
6181
6182           if ((value == &dconste
6183                && (fcode == BUILT_IN_LOG
6184                    || fcode == BUILT_IN_LOGF
6185                    || fcode == BUILT_IN_LOGL))
6186               || (value == &dconst2
6187                   && (fcode == BUILT_IN_LOG2
6188                       || fcode == BUILT_IN_LOG2F
6189                       || fcode == BUILT_IN_LOG2L))
6190               || (value == &dconst10
6191                   && (fcode == BUILT_IN_LOG10
6192                       || fcode == BUILT_IN_LOG10F
6193                       || fcode == BUILT_IN_LOG10L)))
6194             return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6195         }
6196     }
6197
6198   return 0;
6199 }
6200
6201 /* Fold function call to builtin memcpy.  Return
6202    NULL_TREE if no simplification can be made.  */
6203
6204 static tree
6205 fold_builtin_memcpy (tree exp)
6206 {
6207   tree arglist = TREE_OPERAND (exp, 1);
6208   tree dest, src, len;
6209
6210   if (!validate_arglist (arglist,
6211                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6212     return 0;
6213
6214   dest = TREE_VALUE (arglist);
6215   src = TREE_VALUE (TREE_CHAIN (arglist));
6216   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6217
6218   /* If the LEN parameter is zero, return DEST.  */
6219   if (integer_zerop (len))
6220     return omit_one_operand (TREE_TYPE (exp), dest, src);
6221
6222   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6223   if (operand_equal_p (src, dest, 0))
6224     return omit_one_operand (TREE_TYPE (exp), dest, len);
6225
6226   return 0;
6227 }
6228
6229 /* Fold function call to builtin mempcpy.  Return
6230    NULL_TREE if no simplification can be made.  */
6231
6232 static tree
6233 fold_builtin_mempcpy (tree exp)
6234 {
6235   tree arglist = TREE_OPERAND (exp, 1);
6236   tree dest, src, len;
6237
6238   if (!validate_arglist (arglist,
6239                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6240     return 0;
6241
6242   dest = TREE_VALUE (arglist);
6243   src = TREE_VALUE (TREE_CHAIN (arglist));
6244   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6245
6246   /* If the LEN parameter is zero, return DEST.  */
6247   if (integer_zerop (len))
6248     return omit_one_operand (TREE_TYPE (exp), dest, src);
6249
6250   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6251   if (operand_equal_p (src, dest, 0))
6252     {
6253       tree temp = convert (TREE_TYPE (dest), len);
6254       temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6255       return convert (TREE_TYPE (exp), temp);
6256     }
6257
6258   return 0;
6259 }
6260
6261 /* Fold function call to builtin memmove.  Return
6262    NULL_TREE if no simplification can be made.  */
6263
6264 static tree
6265 fold_builtin_memmove (tree exp)
6266 {
6267   tree arglist = TREE_OPERAND (exp, 1);
6268   tree dest, src, len;
6269
6270   if (!validate_arglist (arglist,
6271                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6272     return 0;
6273
6274   dest = TREE_VALUE (arglist);
6275   src = TREE_VALUE (TREE_CHAIN (arglist));
6276   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6277
6278   /* If the LEN parameter is zero, return DEST.  */
6279   if (integer_zerop (len))
6280     return omit_one_operand (TREE_TYPE (exp), dest, src);
6281
6282   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6283   if (operand_equal_p (src, dest, 0))
6284     return omit_one_operand (TREE_TYPE (exp), dest, len);
6285
6286   return 0;
6287 }
6288
6289 /* Fold function call to builtin strcpy.  Return
6290    NULL_TREE if no simplification can be made.  */
6291
6292 static tree
6293 fold_builtin_strcpy (tree exp)
6294 {
6295   tree arglist = TREE_OPERAND (exp, 1);
6296   tree dest, src;
6297
6298   if (!validate_arglist (arglist,
6299                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6300     return 0;
6301
6302   dest = TREE_VALUE (arglist);
6303   src = TREE_VALUE (TREE_CHAIN (arglist));
6304
6305   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6306   if (operand_equal_p (src, dest, 0))
6307     return convert (TREE_TYPE (exp), dest);
6308
6309   return 0;
6310 }
6311
6312 /* Fold function call to builtin strncpy.  Return
6313    NULL_TREE if no simplification can be made.  */
6314
6315 static tree
6316 fold_builtin_strncpy (tree exp)
6317 {
6318   tree arglist = TREE_OPERAND (exp, 1);
6319   tree dest, src, len;
6320
6321   if (!validate_arglist (arglist,
6322                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6323     return 0;
6324
6325   dest = TREE_VALUE (arglist);
6326   src = TREE_VALUE (TREE_CHAIN (arglist));
6327   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6328
6329   /* If the LEN parameter is zero, return DEST.  */
6330   if (integer_zerop (len))
6331     return omit_one_operand (TREE_TYPE (exp), dest, src);
6332
6333   return 0;
6334 }
6335
6336 /* Fold function call to builtin memcmp.  Return
6337    NULL_TREE if no simplification can be made.  */
6338
6339 static tree
6340 fold_builtin_memcmp (tree exp)
6341 {
6342   tree arglist = TREE_OPERAND (exp, 1);
6343   tree arg1, arg2, len;
6344
6345   if (!validate_arglist (arglist,
6346                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6347     return 0;
6348
6349   arg1 = TREE_VALUE (arglist);
6350   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6351   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6352
6353   /* If the LEN parameter is zero, return zero.  */
6354   if (integer_zerop (len))
6355     {
6356       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6357       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6358     }
6359
6360   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6361   if (operand_equal_p (arg1, arg2, 0))
6362     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6363
6364   return 0;
6365 }
6366
6367 /* Fold function call to builtin strcmp.  Return
6368    NULL_TREE if no simplification can be made.  */
6369
6370 static tree
6371 fold_builtin_strcmp (tree exp)
6372 {
6373   tree arglist = TREE_OPERAND (exp, 1);
6374   tree arg1, arg2;
6375   const char *p1, *p2;
6376
6377   if (!validate_arglist (arglist,
6378                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6379     return 0;
6380
6381   arg1 = TREE_VALUE (arglist);
6382   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6383
6384   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6385   if (operand_equal_p (arg1, arg2, 0))
6386     return convert (TREE_TYPE (exp), integer_zero_node);
6387
6388   p1 = c_getstr (arg1);
6389   p2 = c_getstr (arg2);
6390
6391   if (p1 && p2)
6392     {
6393       tree temp;
6394       const int i = strcmp (p1, p2);
6395       if (i < 0)
6396         temp = integer_minus_one_node;
6397       else if (i > 0)
6398         temp = integer_one_node;
6399       else
6400         temp = integer_zero_node;
6401       return convert (TREE_TYPE (exp), temp);
6402     }
6403
6404   return 0;
6405 }
6406
6407 /* Fold function call to builtin strncmp.  Return
6408    NULL_TREE if no simplification can be made.  */
6409
6410 static tree
6411 fold_builtin_strncmp (tree exp)
6412 {
6413   tree arglist = TREE_OPERAND (exp, 1);
6414   tree arg1, arg2, len;
6415   const char *p1, *p2;
6416
6417   if (!validate_arglist (arglist,
6418                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6419     return 0;
6420
6421   arg1 = TREE_VALUE (arglist);
6422   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6423   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6424
6425   /* If the LEN parameter is zero, return zero.  */
6426   if (integer_zerop (len))
6427     {
6428       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6429       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6430     }
6431
6432   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6433   if (operand_equal_p (arg1, arg2, 0))
6434     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6435
6436   p1 = c_getstr (arg1);
6437   p2 = c_getstr (arg2);
6438
6439   if (host_integerp (len, 1) && p1 && p2)
6440     {
6441       tree temp;
6442       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6443       if (i < 0)
6444         temp = integer_minus_one_node;
6445       else if (i > 0)
6446         temp = integer_one_node;
6447       else
6448         temp = integer_zero_node;
6449       return convert (TREE_TYPE (exp), temp);
6450     }
6451
6452   return 0;
6453 }
6454
6455 /* Used by constant folding to eliminate some builtin calls early.  EXP is
6456    the CALL_EXPR of a call to a builtin function.  */
6457
6458 tree
6459 fold_builtin (tree exp)
6460 {
6461   tree fndecl = get_callee_fndecl (exp);
6462   tree arglist = TREE_OPERAND (exp, 1);
6463   tree type = TREE_TYPE (TREE_TYPE (fndecl));
6464
6465   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6466     return 0;
6467
6468   switch (DECL_FUNCTION_CODE (fndecl))
6469     {
6470     case BUILT_IN_CONSTANT_P:
6471       return fold_builtin_constant_p (arglist);
6472
6473     case BUILT_IN_CLASSIFY_TYPE:
6474       return fold_builtin_classify_type (arglist);
6475
6476     case BUILT_IN_STRLEN:
6477       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6478         {
6479           tree len = c_strlen (TREE_VALUE (arglist), 0);
6480           if (len)
6481             {
6482               /* Convert from the internal "sizetype" type to "size_t".  */
6483               if (size_type_node)
6484                 len = convert (size_type_node, len);
6485               return len;
6486             }
6487         }
6488       break;
6489
6490     case BUILT_IN_FABS:
6491     case BUILT_IN_FABSF:
6492     case BUILT_IN_FABSL:
6493       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6494         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6495       break;
6496
6497     case BUILT_IN_CABS:
6498     case BUILT_IN_CABSF:
6499     case BUILT_IN_CABSL:
6500       return fold_builtin_cabs (fndecl, arglist, type);
6501
6502     case BUILT_IN_SQRT:
6503     case BUILT_IN_SQRTF:
6504     case BUILT_IN_SQRTL:
6505       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6506         {
6507           enum built_in_function fcode;
6508           tree arg = TREE_VALUE (arglist);
6509
6510           /* Optimize sqrt of constant value.  */
6511           if (TREE_CODE (arg) == REAL_CST
6512               && ! TREE_CONSTANT_OVERFLOW (arg))
6513             {
6514               REAL_VALUE_TYPE r, x;
6515
6516               x = TREE_REAL_CST (arg);
6517               if (real_sqrt (&r, TYPE_MODE (type), &x)
6518                   || (!flag_trapping_math && !flag_errno_math))
6519                 return build_real (type, r);
6520             }
6521
6522           /* Optimize sqrt(exp(x)) = exp(x*0.5).  */
6523           fcode = builtin_mathfn_code (arg);
6524           if (flag_unsafe_math_optimizations
6525               && (fcode == BUILT_IN_EXP
6526                   || fcode == BUILT_IN_EXPF
6527                   || fcode == BUILT_IN_EXPL))
6528             {
6529               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6530               arg = fold (build (MULT_EXPR, type,
6531                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
6532                                  build_real (type, dconsthalf)));
6533               arglist = build_tree_list (NULL_TREE, arg);
6534               return build_function_call_expr (expfn, arglist);
6535             }
6536
6537           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6538           if (flag_unsafe_math_optimizations
6539               && (fcode == BUILT_IN_POW
6540                   || fcode == BUILT_IN_POWF
6541                   || fcode == BUILT_IN_POWL))
6542             {
6543               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6544               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6545               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6546               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6547                                         build_real (type, dconsthalf)));
6548               arglist = tree_cons (NULL_TREE, arg0,
6549                                    build_tree_list (NULL_TREE, narg1));
6550               return build_function_call_expr (powfn, arglist);
6551             }
6552         }
6553       break;
6554
6555     case BUILT_IN_SIN:
6556     case BUILT_IN_SINF:
6557     case BUILT_IN_SINL:
6558       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6559         {
6560           tree arg = TREE_VALUE (arglist);
6561
6562           /* Optimize sin(0.0) = 0.0.  */
6563           if (real_zerop (arg))
6564             return arg;
6565         }
6566       break;
6567
6568     case BUILT_IN_COS:
6569     case BUILT_IN_COSF:
6570     case BUILT_IN_COSL:
6571       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6572         {
6573           tree arg = TREE_VALUE (arglist);
6574
6575           /* Optimize cos(0.0) = 1.0.  */
6576           if (real_zerop (arg))
6577             return build_real (type, dconst1);
6578
6579           /* Optimize cos(-x) into cos(x).  */
6580           if (TREE_CODE (arg) == NEGATE_EXPR)
6581             {
6582               tree arglist = build_tree_list (NULL_TREE,
6583                                               TREE_OPERAND (arg, 0));
6584               return build_function_call_expr (fndecl, arglist);
6585             }
6586         }
6587       break;
6588
6589     case BUILT_IN_EXP:
6590     case BUILT_IN_EXPF:
6591     case BUILT_IN_EXPL:
6592       return fold_builtin_exponent (exp, &dconste);
6593     case BUILT_IN_EXP2:
6594     case BUILT_IN_EXP2F:
6595     case BUILT_IN_EXP2L:
6596       return fold_builtin_exponent (exp, &dconst2);
6597     case BUILT_IN_EXP10:
6598     case BUILT_IN_EXP10F:
6599     case BUILT_IN_EXP10L:
6600     case BUILT_IN_POW10:
6601     case BUILT_IN_POW10F:
6602     case BUILT_IN_POW10L:
6603       return fold_builtin_exponent (exp, &dconst10);
6604     case BUILT_IN_LOG:
6605     case BUILT_IN_LOGF:
6606     case BUILT_IN_LOGL:
6607       return fold_builtin_logarithm (exp, &dconste);
6608       break;
6609     case BUILT_IN_LOG2:
6610     case BUILT_IN_LOG2F:
6611     case BUILT_IN_LOG2L:
6612       return fold_builtin_logarithm (exp, &dconst2);
6613       break;
6614     case BUILT_IN_LOG10:
6615     case BUILT_IN_LOG10F:
6616     case BUILT_IN_LOG10L:
6617       return fold_builtin_logarithm (exp, &dconst10);
6618       break;
6619
6620     case BUILT_IN_TAN:
6621     case BUILT_IN_TANF:
6622     case BUILT_IN_TANL:
6623       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6624         {
6625           enum built_in_function fcode;
6626           tree arg = TREE_VALUE (arglist);
6627
6628           /* Optimize tan(0.0) = 0.0.  */
6629           if (real_zerop (arg))
6630             return arg;
6631
6632           /* Optimize tan(atan(x)) = x.  */
6633           fcode = builtin_mathfn_code (arg);
6634           if (flag_unsafe_math_optimizations
6635               && (fcode == BUILT_IN_ATAN
6636                   || fcode == BUILT_IN_ATANF
6637                   || fcode == BUILT_IN_ATANL))
6638             return TREE_VALUE (TREE_OPERAND (arg, 1));
6639         }
6640       break;
6641
6642     case BUILT_IN_ATAN:
6643     case BUILT_IN_ATANF:
6644     case BUILT_IN_ATANL:
6645       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6646         {
6647           tree arg = TREE_VALUE (arglist);
6648
6649           /* Optimize atan(0.0) = 0.0.  */
6650           if (real_zerop (arg))
6651             return arg;
6652
6653           /* Optimize atan(1.0) = pi/4.  */
6654           if (real_onep (arg))
6655             {
6656               REAL_VALUE_TYPE cst;
6657
6658               real_convert (&cst, TYPE_MODE (type), &dconstpi);
6659               cst.exp -= 2;
6660               return build_real (type, cst);
6661             }
6662         }
6663       break;
6664
6665     case BUILT_IN_POW:
6666     case BUILT_IN_POWF:
6667     case BUILT_IN_POWL:
6668       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6669         {
6670           enum built_in_function fcode;
6671           tree arg0 = TREE_VALUE (arglist);
6672           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6673
6674           /* Optimize pow(1.0,y) = 1.0.  */
6675           if (real_onep (arg0))
6676             return omit_one_operand (type, build_real (type, dconst1), arg1);
6677
6678           if (TREE_CODE (arg1) == REAL_CST
6679               && ! TREE_CONSTANT_OVERFLOW (arg1))
6680             {
6681               REAL_VALUE_TYPE c;
6682               c = TREE_REAL_CST (arg1);
6683
6684               /* Optimize pow(x,0.0) = 1.0.  */
6685               if (REAL_VALUES_EQUAL (c, dconst0))
6686                 return omit_one_operand (type, build_real (type, dconst1),
6687                                          arg0);
6688
6689               /* Optimize pow(x,1.0) = x.  */
6690               if (REAL_VALUES_EQUAL (c, dconst1))
6691                 return arg0;
6692
6693               /* Optimize pow(x,-1.0) = 1.0/x.  */
6694               if (REAL_VALUES_EQUAL (c, dconstm1))
6695                 return fold (build (RDIV_EXPR, type,
6696                                     build_real (type, dconst1),
6697                                     arg0));
6698
6699               /* Optimize pow(x,0.5) = sqrt(x).  */
6700               if (flag_unsafe_math_optimizations
6701                   && REAL_VALUES_EQUAL (c, dconsthalf))
6702                 {
6703                   tree sqrtfn;
6704
6705                   fcode = DECL_FUNCTION_CODE (fndecl);
6706                   if (fcode == BUILT_IN_POW)
6707                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6708                   else if (fcode == BUILT_IN_POWF)
6709                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6710                   else if (fcode == BUILT_IN_POWL)
6711                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6712                   else
6713                     sqrtfn = NULL_TREE;
6714
6715                   if (sqrtfn != NULL_TREE)
6716                     {
6717                       tree arglist = build_tree_list (NULL_TREE, arg0);
6718                       return build_function_call_expr (sqrtfn, arglist);
6719                     }
6720                 }
6721
6722               /* Attempt to evaluate pow at compile-time.  */
6723               if (TREE_CODE (arg0) == REAL_CST
6724                   && ! TREE_CONSTANT_OVERFLOW (arg0))
6725                 {
6726                   REAL_VALUE_TYPE cint;
6727                   HOST_WIDE_INT n;
6728
6729                   n = real_to_integer (&c);
6730                   real_from_integer (&cint, VOIDmode, n,
6731                                      n < 0 ? -1 : 0, 0);
6732                   if (real_identical (&c, &cint))
6733                     {
6734                       REAL_VALUE_TYPE x;
6735                       bool inexact;
6736
6737                       x = TREE_REAL_CST (arg0);
6738                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6739                       if (flag_unsafe_math_optimizations || !inexact)
6740                         return build_real (type, x);
6741                     }
6742                 }
6743             }
6744
6745           /* Optimize pow(exp(x),y) = exp(x*y).  */
6746           fcode = builtin_mathfn_code (arg0);
6747           if (flag_unsafe_math_optimizations
6748               && (fcode == BUILT_IN_EXP
6749                   || fcode == BUILT_IN_EXPF
6750                   || fcode == BUILT_IN_EXPL))
6751             {
6752               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6753               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6754               arg = fold (build (MULT_EXPR, type, arg, arg1));
6755               arglist = build_tree_list (NULL_TREE, arg);
6756               return build_function_call_expr (expfn, arglist);
6757             }
6758
6759           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6760           if (flag_unsafe_math_optimizations
6761               && (fcode == BUILT_IN_SQRT
6762                   || fcode == BUILT_IN_SQRTF
6763                   || fcode == BUILT_IN_SQRTL))
6764             {
6765               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6766               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6767                                         build_real (type, dconsthalf)));
6768
6769               arglist = tree_cons (NULL_TREE, narg0,
6770                                    build_tree_list (NULL_TREE, narg1));
6771               return build_function_call_expr (fndecl, arglist);
6772             }
6773
6774           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6775           if (flag_unsafe_math_optimizations
6776               && (fcode == BUILT_IN_POW
6777                   || fcode == BUILT_IN_POWF
6778                   || fcode == BUILT_IN_POWL))
6779             {
6780               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6781               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6782               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6783               arglist = tree_cons (NULL_TREE, arg00,
6784                                    build_tree_list (NULL_TREE, narg1));
6785               return build_function_call_expr (fndecl, arglist);
6786             }
6787         }
6788       break;
6789
6790     case BUILT_IN_INF:
6791     case BUILT_IN_INFF:
6792     case BUILT_IN_INFL:
6793       return fold_builtin_inf (type, true);
6794
6795     case BUILT_IN_HUGE_VAL:
6796     case BUILT_IN_HUGE_VALF:
6797     case BUILT_IN_HUGE_VALL:
6798       return fold_builtin_inf (type, false);
6799
6800     case BUILT_IN_NAN:
6801     case BUILT_IN_NANF:
6802     case BUILT_IN_NANL:
6803       return fold_builtin_nan (arglist, type, true);
6804
6805     case BUILT_IN_NANS:
6806     case BUILT_IN_NANSF:
6807     case BUILT_IN_NANSL:
6808       return fold_builtin_nan (arglist, type, false);
6809
6810     case BUILT_IN_FLOOR:
6811     case BUILT_IN_FLOORF:
6812     case BUILT_IN_FLOORL:
6813       return fold_builtin_floor (exp);
6814
6815     case BUILT_IN_CEIL:
6816     case BUILT_IN_CEILF:
6817     case BUILT_IN_CEILL:
6818       return fold_builtin_ceil (exp);
6819
6820     case BUILT_IN_TRUNC:
6821     case BUILT_IN_TRUNCF:
6822     case BUILT_IN_TRUNCL:
6823       return fold_builtin_trunc (exp);
6824
6825     case BUILT_IN_ROUND:
6826     case BUILT_IN_ROUNDF:
6827     case BUILT_IN_ROUNDL:
6828     case BUILT_IN_NEARBYINT:
6829     case BUILT_IN_NEARBYINTF:
6830     case BUILT_IN_NEARBYINTL:
6831       return fold_trunc_transparent_mathfn (exp);
6832
6833     case BUILT_IN_FFS:
6834     case BUILT_IN_FFSL:
6835     case BUILT_IN_FFSLL:
6836     case BUILT_IN_CLZ:
6837     case BUILT_IN_CLZL:
6838     case BUILT_IN_CLZLL:
6839     case BUILT_IN_CTZ:
6840     case BUILT_IN_CTZL:
6841     case BUILT_IN_CTZLL:
6842     case BUILT_IN_POPCOUNT:
6843     case BUILT_IN_POPCOUNTL:
6844     case BUILT_IN_POPCOUNTLL:
6845     case BUILT_IN_PARITY:
6846     case BUILT_IN_PARITYL:
6847     case BUILT_IN_PARITYLL:
6848       return fold_builtin_bitop (exp);
6849
6850     case BUILT_IN_MEMCPY:
6851       return fold_builtin_memcpy (exp);
6852
6853     case BUILT_IN_MEMPCPY:
6854       return fold_builtin_mempcpy (exp);
6855
6856     case BUILT_IN_MEMMOVE:
6857       return fold_builtin_memmove (exp);
6858
6859     case BUILT_IN_STRCPY:
6860       return fold_builtin_strcpy (exp);
6861
6862     case BUILT_IN_STRNCPY:
6863       return fold_builtin_strncpy (exp);
6864
6865     case BUILT_IN_MEMCMP:
6866       return fold_builtin_memcmp (exp);
6867
6868     case BUILT_IN_STRCMP:
6869       return fold_builtin_strcmp (exp);
6870
6871     case BUILT_IN_STRNCMP:
6872       return fold_builtin_strncmp (exp);
6873
6874     default:
6875       break;
6876     }
6877
6878   return 0;
6879 }
6880
6881 /* Conveniently construct a function call expression.  */
6882
6883 tree
6884 build_function_call_expr (tree fn, tree arglist)
6885 {
6886   tree call_expr;
6887
6888   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6889   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6890                      call_expr, arglist);
6891   return fold (call_expr);
6892 }
6893
6894 /* This function validates the types of a function call argument list
6895    represented as a tree chain of parameters against a specified list
6896    of tree_codes.  If the last specifier is a 0, that represents an
6897    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
6898
6899 static int
6900 validate_arglist (tree arglist, ...)
6901 {
6902   enum tree_code code;
6903   int res = 0;
6904   va_list ap;
6905
6906   va_start (ap, arglist);
6907
6908   do
6909     {
6910       code = va_arg (ap, enum tree_code);
6911       switch (code)
6912         {
6913         case 0:
6914           /* This signifies an ellipses, any further arguments are all ok.  */
6915           res = 1;
6916           goto end;
6917         case VOID_TYPE:
6918           /* This signifies an endlink, if no arguments remain, return
6919              true, otherwise return false.  */
6920           res = arglist == 0;
6921           goto end;
6922         default:
6923           /* If no parameters remain or the parameter's code does not
6924              match the specified code, return false.  Otherwise continue
6925              checking any remaining arguments.  */
6926           if (arglist == 0
6927               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6928             goto end;
6929           break;
6930         }
6931       arglist = TREE_CHAIN (arglist);
6932     }
6933   while (1);
6934
6935   /* We need gotos here since we can only have one VA_CLOSE in a
6936      function.  */
6937  end: ;
6938   va_end (ap);
6939
6940   return res;
6941 }
6942
6943 /* Default target-specific builtin expander that does nothing.  */
6944
6945 rtx
6946 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6947                         rtx target ATTRIBUTE_UNUSED,
6948                         rtx subtarget ATTRIBUTE_UNUSED,
6949                         enum machine_mode mode ATTRIBUTE_UNUSED,
6950                         int ignore ATTRIBUTE_UNUSED)
6951 {
6952   return NULL_RTX;
6953 }
6954
6955 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
6956
6957 void
6958 purge_builtin_constant_p (void)
6959 {
6960   rtx insn, set, arg, new, note;
6961
6962   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6963     if (INSN_P (insn)
6964         && (set = single_set (insn)) != NULL_RTX
6965         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6966             || (GET_CODE (arg) == SUBREG
6967                 && (GET_CODE (arg = SUBREG_REG (arg))
6968                     == CONSTANT_P_RTX))))
6969       {
6970         arg = XEXP (arg, 0);
6971         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6972         validate_change (insn, &SET_SRC (set), new, 0);
6973
6974         /* Remove the REG_EQUAL note from the insn.  */
6975         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6976           remove_note (insn, note);
6977       }
6978 }
6979
6980 /* Returns true is EXP represents data that would potentially reside
6981    in a readonly section.  */
6982
6983 static bool
6984 readonly_data_expr (tree exp)
6985 {
6986   STRIP_NOPS (exp);
6987
6988   if (TREE_CODE (exp) == ADDR_EXPR)
6989     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6990   else
6991     return false;
6992 }