OSDN Git Service

* postreload.c (reload_combine): Check that REGY doesn't die in an
[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" definition of va_list is void*.  */
3914
3915 tree
3916 std_build_builtin_va_list (void)
3917 {
3918   return ptr_type_node;
3919 }
3920
3921 /* The "standard" implementation of va_start: just assign `nextarg' to
3922    the variable.  */
3923
3924 void
3925 std_expand_builtin_va_start (tree valist, rtx nextarg)
3926 {
3927   tree t;
3928
3929   t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
3930              make_tree (ptr_type_node, nextarg));
3931   TREE_SIDE_EFFECTS (t) = 1;
3932
3933   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3934 }
3935
3936 /* Expand ARGLIST, from a call to __builtin_va_start.  */
3937
3938 static rtx
3939 expand_builtin_va_start (tree arglist)
3940 {
3941   rtx nextarg;
3942   tree chain, valist;
3943
3944   chain = TREE_CHAIN (arglist);
3945
3946   if (TREE_CHAIN (chain))
3947     error ("too many arguments to function `va_start'");
3948
3949   nextarg = expand_builtin_next_arg (chain);
3950   valist = stabilize_va_list (TREE_VALUE (arglist), 1);
3951
3952 #ifdef EXPAND_BUILTIN_VA_START
3953   EXPAND_BUILTIN_VA_START (valist, nextarg);
3954 #else
3955   std_expand_builtin_va_start (valist, nextarg);
3956 #endif
3957
3958   return const0_rtx;
3959 }
3960
3961 /* The "standard" implementation of va_arg: read the value from the
3962    current (padded) address and increment by the (padded) size.  */
3963
3964 rtx
3965 std_expand_builtin_va_arg (tree valist, tree type)
3966 {
3967   tree addr_tree, t, type_size = NULL;
3968   tree align, alignm1;
3969   tree rounded_size;
3970   rtx addr;
3971
3972   /* Compute the rounded size of the type.  */
3973   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
3974   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
3975   if (type == error_mark_node
3976       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
3977       || TREE_OVERFLOW (type_size))
3978     rounded_size = size_zero_node;
3979   else
3980     rounded_size = fold (build (MULT_EXPR, sizetype,
3981                                 fold (build (TRUNC_DIV_EXPR, sizetype,
3982                                              fold (build (PLUS_EXPR, sizetype,
3983                                                           type_size, alignm1)),
3984                                              align)),
3985                                 align));
3986
3987   /* Get AP.  */
3988   addr_tree = valist;
3989   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
3990     {
3991       /* Small args are padded downward.  */
3992       addr_tree = fold (build (PLUS_EXPR, TREE_TYPE (addr_tree), addr_tree,
3993                                fold (build (COND_EXPR, sizetype,
3994                                             fold (build (GT_EXPR, sizetype,
3995                                                          rounded_size,
3996                                                          align)),
3997                                             size_zero_node,
3998                                             fold (build (MINUS_EXPR, sizetype,
3999                                                          rounded_size,
4000                                                          type_size))))));
4001     }
4002
4003   addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
4004   addr = copy_to_reg (addr);
4005
4006   /* Compute new value for AP.  */
4007   if (! integer_zerop (rounded_size))
4008     {
4009       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
4010                  build (PLUS_EXPR, TREE_TYPE (valist), valist,
4011                         rounded_size));
4012       TREE_SIDE_EFFECTS (t) = 1;
4013       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4014     }
4015
4016   return addr;
4017 }
4018
4019 /* Expand __builtin_va_arg, which is not really a builtin function, but
4020    a very special sort of operator.  */
4021
4022 rtx
4023 expand_builtin_va_arg (tree valist, tree type)
4024 {
4025   rtx addr, result;
4026   tree promoted_type, want_va_type, have_va_type;
4027
4028   /* Verify that valist is of the proper type.  */
4029
4030   want_va_type = va_list_type_node;
4031   have_va_type = TREE_TYPE (valist);
4032   if (TREE_CODE (want_va_type) == ARRAY_TYPE)
4033     {
4034       /* If va_list is an array type, the argument may have decayed
4035          to a pointer type, e.g. by being passed to another function.
4036          In that case, unwrap both types so that we can compare the
4037          underlying records.  */
4038       if (TREE_CODE (have_va_type) == ARRAY_TYPE
4039           || TREE_CODE (have_va_type) == POINTER_TYPE)
4040         {
4041           want_va_type = TREE_TYPE (want_va_type);
4042           have_va_type = TREE_TYPE (have_va_type);
4043         }
4044     }
4045   if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type))
4046     {
4047       error ("first argument to `va_arg' not of type `va_list'");
4048       addr = const0_rtx;
4049     }
4050
4051   /* Generate a diagnostic for requesting data of a type that cannot
4052      be passed through `...' due to type promotion at the call site.  */
4053   else if ((promoted_type = (*lang_hooks.types.type_promotes_to) (type))
4054            != type)
4055     {
4056       const char *name = "<anonymous type>", *pname = 0;
4057       static bool gave_help;
4058
4059       if (TYPE_NAME (type))
4060         {
4061           if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
4062             name = IDENTIFIER_POINTER (TYPE_NAME (type));
4063           else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
4064                    && DECL_NAME (TYPE_NAME (type)))
4065             name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
4066         }
4067       if (TYPE_NAME (promoted_type))
4068         {
4069           if (TREE_CODE (TYPE_NAME (promoted_type)) == IDENTIFIER_NODE)
4070             pname = IDENTIFIER_POINTER (TYPE_NAME (promoted_type));
4071           else if (TREE_CODE (TYPE_NAME (promoted_type)) == TYPE_DECL
4072                    && DECL_NAME (TYPE_NAME (promoted_type)))
4073             pname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (promoted_type)));
4074         }
4075
4076       /* Unfortunately, this is merely undefined, rather than a constraint
4077          violation, so we cannot make this an error.  If this call is never
4078          executed, the program is still strictly conforming.  */
4079       warning ("`%s' is promoted to `%s' when passed through `...'",
4080                name, pname);
4081       if (! gave_help)
4082         {
4083           gave_help = true;
4084           warning ("(so you should pass `%s' not `%s' to `va_arg')",
4085                    pname, name);
4086         }
4087
4088       /* We can, however, treat "undefined" any way we please.
4089          Call abort to encourage the user to fix the program.  */
4090       expand_builtin_trap ();
4091
4092       /* This is dead code, but go ahead and finish so that the
4093          mode of the result comes out right.  */
4094       addr = const0_rtx;
4095     }
4096   else
4097     {
4098       /* Make it easier for the backends by protecting the valist argument
4099          from multiple evaluations.  */
4100       valist = stabilize_va_list (valist, 0);
4101
4102 #ifdef EXPAND_BUILTIN_VA_ARG
4103       addr = EXPAND_BUILTIN_VA_ARG (valist, type);
4104 #else
4105       addr = std_expand_builtin_va_arg (valist, type);
4106 #endif
4107     }
4108
4109   addr = convert_memory_address (Pmode, addr);
4110
4111   result = gen_rtx_MEM (TYPE_MODE (type), addr);
4112   set_mem_alias_set (result, get_varargs_alias_set ());
4113
4114   return result;
4115 }
4116
4117 /* Expand ARGLIST, from a call to __builtin_va_end.  */
4118
4119 static rtx
4120 expand_builtin_va_end (tree arglist)
4121 {
4122   tree valist = TREE_VALUE (arglist);
4123
4124 #ifdef EXPAND_BUILTIN_VA_END
4125   valist = stabilize_va_list (valist, 0);
4126   EXPAND_BUILTIN_VA_END (arglist);
4127 #else
4128   /* Evaluate for side effects, if needed.  I hate macros that don't
4129      do that.  */
4130   if (TREE_SIDE_EFFECTS (valist))
4131     expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
4132 #endif
4133
4134   return const0_rtx;
4135 }
4136
4137 /* Expand ARGLIST, from a call to __builtin_va_copy.  We do this as a
4138    builtin rather than just as an assignment in stdarg.h because of the
4139    nastiness of array-type va_list types.  */
4140
4141 static rtx
4142 expand_builtin_va_copy (tree arglist)
4143 {
4144   tree dst, src, t;
4145
4146   dst = TREE_VALUE (arglist);
4147   src = TREE_VALUE (TREE_CHAIN (arglist));
4148
4149   dst = stabilize_va_list (dst, 1);
4150   src = stabilize_va_list (src, 0);
4151
4152   if (TREE_CODE (va_list_type_node) != ARRAY_TYPE)
4153     {
4154       t = build (MODIFY_EXPR, va_list_type_node, dst, src);
4155       TREE_SIDE_EFFECTS (t) = 1;
4156       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
4157     }
4158   else
4159     {
4160       rtx dstb, srcb, size;
4161
4162       /* Evaluate to pointers.  */
4163       dstb = expand_expr (dst, NULL_RTX, Pmode, EXPAND_NORMAL);
4164       srcb = expand_expr (src, NULL_RTX, Pmode, EXPAND_NORMAL);
4165       size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
4166                           VOIDmode, EXPAND_NORMAL);
4167
4168       dstb = convert_memory_address (Pmode, dstb);
4169       srcb = convert_memory_address (Pmode, srcb);
4170
4171       /* "Dereference" to BLKmode memories.  */
4172       dstb = gen_rtx_MEM (BLKmode, dstb);
4173       set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst))));
4174       set_mem_align (dstb, TYPE_ALIGN (va_list_type_node));
4175       srcb = gen_rtx_MEM (BLKmode, srcb);
4176       set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src))));
4177       set_mem_align (srcb, TYPE_ALIGN (va_list_type_node));
4178
4179       /* Copy.  */
4180       emit_block_move (dstb, srcb, size, BLOCK_OP_NORMAL);
4181     }
4182
4183   return const0_rtx;
4184 }
4185
4186 /* Expand a call to one of the builtin functions __builtin_frame_address or
4187    __builtin_return_address.  */
4188
4189 static rtx
4190 expand_builtin_frame_address (tree fndecl, tree arglist)
4191 {
4192   /* The argument must be a nonnegative integer constant.
4193      It counts the number of frames to scan up the stack.
4194      The value is the return address saved in that frame.  */
4195   if (arglist == 0)
4196     /* Warning about missing arg was already issued.  */
4197     return const0_rtx;
4198   else if (! host_integerp (TREE_VALUE (arglist), 1))
4199     {
4200       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4201         error ("invalid arg to `__builtin_frame_address'");
4202       else
4203         error ("invalid arg to `__builtin_return_address'");
4204       return const0_rtx;
4205     }
4206   else
4207     {
4208       rtx tem
4209         = expand_builtin_return_addr (DECL_FUNCTION_CODE (fndecl),
4210                                       tree_low_cst (TREE_VALUE (arglist), 1),
4211                                       hard_frame_pointer_rtx);
4212
4213       /* Some ports cannot access arbitrary stack frames.  */
4214       if (tem == NULL)
4215         {
4216           if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4217             warning ("unsupported arg to `__builtin_frame_address'");
4218           else
4219             warning ("unsupported arg to `__builtin_return_address'");
4220           return const0_rtx;
4221         }
4222
4223       /* For __builtin_frame_address, return what we've got.  */
4224       if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_FRAME_ADDRESS)
4225         return tem;
4226
4227       if (GET_CODE (tem) != REG
4228           && ! CONSTANT_P (tem))
4229         tem = copy_to_mode_reg (Pmode, tem);
4230       return tem;
4231     }
4232 }
4233
4234 /* Expand a call to the alloca builtin, with arguments ARGLIST.  Return 0 if
4235    we failed and the caller should emit a normal call, otherwise try to get
4236    the result in TARGET, if convenient.  */
4237
4238 static rtx
4239 expand_builtin_alloca (tree arglist, rtx target)
4240 {
4241   rtx op0;
4242   rtx result;
4243
4244   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4245     return 0;
4246
4247   /* Compute the argument.  */
4248   op0 = expand_expr (TREE_VALUE (arglist), NULL_RTX, VOIDmode, 0);
4249
4250   /* Allocate the desired space.  */
4251   result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
4252   result = convert_memory_address (ptr_mode, result);
4253
4254   return result;
4255 }
4256
4257 /* Expand a call to a unary builtin.  The arguments are in ARGLIST.
4258    Return 0 if a normal call should be emitted rather than expanding the
4259    function in-line.  If convenient, the result should be placed in TARGET.
4260    SUBTARGET may be used as the target for computing one of EXP's operands.  */
4261
4262 static rtx
4263 expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
4264                      rtx subtarget, optab op_optab)
4265 {
4266   rtx op0;
4267   if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
4268     return 0;
4269
4270   /* Compute the argument.  */
4271   op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
4272   /* Compute op, into TARGET if possible.
4273      Set TARGET to wherever the result comes back.  */
4274   target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
4275                         op_optab, op0, target, 1);
4276   if (target == 0)
4277     abort ();
4278
4279   return convert_to_mode (target_mode, target, 0);
4280 }
4281
4282 /* If the string passed to fputs is a constant and is one character
4283    long, we attempt to transform this call into __builtin_fputc().  */
4284
4285 static rtx
4286 expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
4287 {
4288   tree len, fn;
4289   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4290     : implicit_built_in_decls[BUILT_IN_FPUTC];
4291   tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
4292     : implicit_built_in_decls[BUILT_IN_FWRITE];
4293
4294   /* If the return value is used, or the replacement _DECL isn't
4295      initialized, don't do the transformation.  */
4296   if (target != const0_rtx || !fn_fputc || !fn_fwrite)
4297     return 0;
4298
4299   /* Verify the arguments in the original call.  */
4300   if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
4301     return 0;
4302
4303   /* Get the length of the string passed to fputs.  If the length
4304      can't be determined, punt.  */
4305   if (!(len = c_strlen (TREE_VALUE (arglist), 1))
4306       || TREE_CODE (len) != INTEGER_CST)
4307     return 0;
4308
4309   switch (compare_tree_int (len, 1))
4310     {
4311     case -1: /* length is 0, delete the call entirely .  */
4312       {
4313         /* Evaluate and ignore the argument in case it has
4314            side-effects.  */
4315         expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
4316                      VOIDmode, EXPAND_NORMAL);
4317         return const0_rtx;
4318       }
4319     case 0: /* length is 1, call fputc.  */
4320       {
4321         const char *p = c_getstr (TREE_VALUE (arglist));
4322
4323         if (p != NULL)
4324           {
4325             /* New argument list transforming fputs(string, stream) to
4326                fputc(string[0], stream).  */
4327             arglist =
4328               build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4329             arglist =
4330               tree_cons (NULL_TREE, build_int_2 (p[0], 0), arglist);
4331             fn = fn_fputc;
4332             break;
4333           }
4334       }
4335       /* FALLTHROUGH */
4336     case 1: /* length is greater than 1, call fwrite.  */
4337       {
4338         tree string_arg;
4339
4340         /* If optimizing for size keep fputs.  */
4341         if (optimize_size)
4342           return 0;
4343         string_arg = TREE_VALUE (arglist);
4344         /* New argument list transforming fputs(string, stream) to
4345            fwrite(string, 1, len, stream).  */
4346         arglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
4347         arglist = tree_cons (NULL_TREE, len, arglist);
4348         arglist = tree_cons (NULL_TREE, size_one_node, arglist);
4349         arglist = tree_cons (NULL_TREE, string_arg, arglist);
4350         fn = fn_fwrite;
4351         break;
4352       }
4353     default:
4354       abort ();
4355     }
4356
4357   return expand_expr (build_function_call_expr (fn, arglist),
4358                       const0_rtx, VOIDmode, EXPAND_NORMAL);
4359 }
4360
4361 /* Expand a call to __builtin_expect.  We return our argument and emit a
4362    NOTE_INSN_EXPECTED_VALUE note.  This is the expansion of __builtin_expect in
4363    a non-jump context.  */
4364
4365 static rtx
4366 expand_builtin_expect (tree arglist, rtx target)
4367 {
4368   tree exp, c;
4369   rtx note, rtx_c;
4370
4371   if (arglist == NULL_TREE
4372       || TREE_CHAIN (arglist) == NULL_TREE)
4373     return const0_rtx;
4374   exp = TREE_VALUE (arglist);
4375   c = TREE_VALUE (TREE_CHAIN (arglist));
4376
4377   if (TREE_CODE (c) != INTEGER_CST)
4378     {
4379       error ("second arg to `__builtin_expect' must be a constant");
4380       c = integer_zero_node;
4381     }
4382
4383   target = expand_expr (exp, target, VOIDmode, EXPAND_NORMAL);
4384
4385   /* Don't bother with expected value notes for integral constants.  */
4386   if (flag_guess_branch_prob && GET_CODE (target) != CONST_INT)
4387     {
4388       /* We do need to force this into a register so that we can be
4389          moderately sure to be able to correctly interpret the branch
4390          condition later.  */
4391       target = force_reg (GET_MODE (target), target);
4392
4393       rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
4394
4395       note = emit_note (NOTE_INSN_EXPECTED_VALUE);
4396       NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
4397     }
4398
4399   return target;
4400 }
4401
4402 /* Like expand_builtin_expect, except do this in a jump context.  This is
4403    called from do_jump if the conditional is a __builtin_expect.  Return either
4404    a list of insns to emit the jump or NULL if we cannot optimize
4405    __builtin_expect.  We need to optimize this at jump time so that machines
4406    like the PowerPC don't turn the test into a SCC operation, and then jump
4407    based on the test being 0/1.  */
4408
4409 rtx
4410 expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
4411 {
4412   tree arglist = TREE_OPERAND (exp, 1);
4413   tree arg0 = TREE_VALUE (arglist);
4414   tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4415   rtx ret = NULL_RTX;
4416
4417   /* Only handle __builtin_expect (test, 0) and
4418      __builtin_expect (test, 1).  */
4419   if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
4420       && (integer_zerop (arg1) || integer_onep (arg1)))
4421     {
4422       int num_jumps = 0;
4423       int save_pending_stack_adjust = pending_stack_adjust;
4424       rtx insn;
4425
4426       /* If we fail to locate an appropriate conditional jump, we'll
4427          fall back to normal evaluation.  Ensure that the expression
4428          can be re-evaluated.  */
4429       switch (unsafe_for_reeval (arg0))
4430         {
4431         case 0: /* Safe.  */
4432           break;
4433
4434         case 1: /* Mildly unsafe.  */
4435           arg0 = unsave_expr (arg0);
4436           break;
4437
4438         case 2: /* Wildly unsafe.  */
4439           return NULL_RTX;
4440         }
4441
4442       /* Expand the jump insns.  */
4443       start_sequence ();
4444       do_jump (arg0, if_false_label, if_true_label);
4445       ret = get_insns ();
4446       end_sequence ();
4447
4448       /* Now that the __builtin_expect has been validated, go through and add
4449          the expect's to each of the conditional jumps.  If we run into an
4450          error, just give up and generate the 'safe' code of doing a SCC
4451          operation and then doing a branch on that.  */
4452       insn = ret;
4453       while (insn != NULL_RTX)
4454         {
4455           rtx next = NEXT_INSN (insn);
4456
4457           if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
4458             {
4459               rtx ifelse = SET_SRC (pc_set (insn));
4460               rtx label;
4461               int taken;
4462
4463               if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
4464                 {
4465                   taken = 1;
4466                   label = XEXP (XEXP (ifelse, 1), 0);
4467                 }
4468               /* An inverted jump reverses the probabilities.  */
4469               else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
4470                 {
4471                   taken = 0;
4472                   label = XEXP (XEXP (ifelse, 2), 0);
4473                 }
4474               /* We shouldn't have to worry about conditional returns during
4475                  the expansion stage, but handle it gracefully anyway.  */
4476               else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
4477                 {
4478                   taken = 1;
4479                   label = NULL_RTX;
4480                 }
4481               /* An inverted return reverses the probabilities.  */
4482               else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
4483                 {
4484                   taken = 0;
4485                   label = NULL_RTX;
4486                 }
4487               else
4488                 goto do_next_insn;
4489
4490               /* If the test is expected to fail, reverse the
4491                  probabilities.  */
4492               if (integer_zerop (arg1))
4493                 taken = 1 - taken;
4494
4495               /* If we are jumping to the false label, reverse the
4496                  probabilities.  */
4497               if (label == NULL_RTX)
4498                 ;               /* conditional return */
4499               else if (label == if_false_label)
4500                 taken = 1 - taken;
4501               else if (label != if_true_label)
4502                 goto do_next_insn;
4503
4504               num_jumps++;
4505               predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
4506             }
4507
4508         do_next_insn:
4509           insn = next;
4510         }
4511
4512       /* If no jumps were modified, fail and do __builtin_expect the normal
4513          way.  */
4514       if (num_jumps == 0)
4515         {
4516           ret = NULL_RTX;
4517           pending_stack_adjust = save_pending_stack_adjust;
4518         }
4519     }
4520
4521   return ret;
4522 }
4523
4524 void
4525 expand_builtin_trap (void)
4526 {
4527 #ifdef HAVE_trap
4528   if (HAVE_trap)
4529     emit_insn (gen_trap ());
4530   else
4531 #endif
4532     emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
4533   emit_barrier ();
4534 }
4535
4536 /* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
4537    Return 0 if a normal call should be emitted rather than expanding
4538    the function inline.  If convenient, the result should be placed
4539    in TARGET.  SUBTARGET may be used as the target for computing
4540    the operand.  */
4541
4542 static rtx
4543 expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
4544 {
4545   enum machine_mode mode;
4546   tree arg;
4547   rtx op0;
4548
4549   if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
4550     return 0;
4551
4552   arg = TREE_VALUE (arglist);
4553   mode = TYPE_MODE (TREE_TYPE (arg));
4554   op0 = expand_expr (arg, subtarget, VOIDmode, 0);
4555   return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
4556 }
4557
4558 /* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
4559    Return 0 if a normal call should be emitted rather than expanding
4560    the function inline.  If convenient, the result should be placed
4561    in target.  */
4562
4563 static rtx
4564 expand_builtin_cabs (tree arglist, rtx target)
4565 {
4566   enum machine_mode mode;
4567   tree arg;
4568   rtx op0;
4569
4570   if (arglist == 0 || TREE_CHAIN (arglist))
4571     return 0;
4572   arg = TREE_VALUE (arglist);
4573   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
4574       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
4575     return 0;
4576
4577   mode = TYPE_MODE (TREE_TYPE (arg));
4578   op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
4579   return expand_complex_abs (mode, op0, target, 0);
4580 }
4581
4582 /* Create a new constant string literal and return a char* pointer to it.
4583    The STRING_CST value is the LEN characters at STR.  */
4584 static tree
4585 build_string_literal (int len, const char *str)
4586 {
4587   tree t, elem, index, type;
4588
4589   t = build_string (len, str);
4590   elem = build_type_variant (char_type_node, 1, 0);
4591   index = build_index_type (build_int_2 (len - 1, 0));
4592   type = build_array_type (elem, index);
4593   TREE_TYPE (t) = type;
4594   TREE_CONSTANT (t) = 1;
4595   TREE_READONLY (t) = 1;
4596   TREE_STATIC (t) = 1;
4597
4598   type = build_pointer_type (type);
4599   t = build1 (ADDR_EXPR, type, t);
4600
4601   type = build_pointer_type (elem);
4602   t = build1 (NOP_EXPR, type, t);
4603   return t;
4604 }
4605
4606 /* Expand a call to printf or printf_unlocked with argument list ARGLIST.
4607    Return 0 if a normal call should be emitted rather than transforming
4608    the function inline.  If convenient, the result should be placed in
4609    TARGET with mode MODE.  UNLOCKED indicates this is a printf_unlocked 
4610    call.  */
4611 static rtx
4612 expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
4613                        bool unlocked)
4614 {
4615   tree fn_putchar = unlocked
4616                     ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
4617                     : implicit_built_in_decls[BUILT_IN_PUTCHAR];
4618   tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
4619                           : implicit_built_in_decls[BUILT_IN_PUTS];
4620   const char *fmt_str;
4621   tree fn, fmt, arg;
4622
4623   /* If the return value is used, don't do the transformation.  */
4624   if (target != const0_rtx)
4625     return 0;
4626
4627   /* Verify the required arguments in the original call.  */
4628   if (! arglist)
4629     return 0;
4630   fmt = TREE_VALUE (arglist);
4631   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4632     return 0;
4633   arglist = TREE_CHAIN (arglist);
4634
4635   /* Check whether the format is a literal string constant.  */
4636   fmt_str = c_getstr (fmt);
4637   if (fmt_str == NULL)
4638     return 0;
4639
4640   /* If the format specifier was "%s\n", call __builtin_puts(arg).  */
4641   if (strcmp (fmt_str, "%s\n") == 0)
4642     {
4643       if (! arglist
4644           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4645           || TREE_CHAIN (arglist))
4646         return 0;
4647       fn = fn_puts;
4648     }
4649   /* If the format specifier was "%c", call __builtin_putchar(arg).  */
4650   else if (strcmp (fmt_str, "%c") == 0)
4651     {
4652       if (! arglist
4653           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4654           || TREE_CHAIN (arglist))
4655         return 0;
4656       fn = fn_putchar;
4657     }
4658   else
4659     {
4660       /* We can't handle anything else with % args or %% ... yet.  */
4661       if (strchr (fmt_str, '%'))
4662         return 0;
4663
4664       if (arglist)
4665         return 0;
4666
4667       /* If the format specifier was "", printf does nothing.  */
4668       if (fmt_str[0] == '\0')
4669         return const0_rtx;
4670       /* If the format specifier has length of 1, call putchar.  */
4671       if (fmt_str[1] == '\0')
4672         {
4673           /* Given printf("c"), (where c is any one character,)
4674              convert "c"[0] to an int and pass that to the replacement
4675              function.  */
4676           arg = build_int_2 (fmt_str[0], 0);
4677           arglist = build_tree_list (NULL_TREE, arg);
4678           fn = fn_putchar;
4679         }
4680       else
4681         {
4682           /* If the format specifier was "string\n", call puts("string").  */
4683           size_t len = strlen (fmt_str);
4684           if (fmt_str[len - 1] == '\n')
4685             {
4686               /* Create a NUL-terminated string that's one char shorter
4687                  than the original, stripping off the trailing '\n'.  */
4688               char *newstr = (char *) alloca (len);
4689               memcpy (newstr, fmt_str, len - 1);
4690               newstr[len - 1] = 0;
4691
4692               arg = build_string_literal (len, newstr);
4693               arglist = build_tree_list (NULL_TREE, arg);
4694               fn = fn_puts;
4695             }
4696           else
4697             /* We'd like to arrange to call fputs(string,stdout) here,
4698                but we need stdout and don't have a way to get it yet.  */
4699             return 0;
4700         }
4701     }
4702
4703   if (!fn)
4704     return 0;
4705   return expand_expr (build_function_call_expr (fn, arglist),
4706                       target, mode, EXPAND_NORMAL);
4707 }
4708
4709 /* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
4710    Return 0 if a normal call should be emitted rather than transforming
4711    the function inline.  If convenient, the result should be placed in
4712    TARGET with mode MODE.  UNLOCKED indicates this is a fprintf_unlocked 
4713    call.  */
4714 static rtx
4715 expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
4716                         bool unlocked)
4717 {
4718   tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
4719                            : implicit_built_in_decls[BUILT_IN_FPUTC];
4720   tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
4721                            : implicit_built_in_decls[BUILT_IN_FPUTS];
4722   const char *fmt_str;
4723   tree fn, fmt, fp, arg;
4724
4725   /* If the return value is used, don't do the transformation.  */
4726   if (target != const0_rtx)
4727     return 0;
4728
4729   /* Verify the required arguments in the original call.  */
4730   if (! arglist)
4731     return 0;
4732   fp = TREE_VALUE (arglist);
4733   if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
4734     return 0;
4735   arglist = TREE_CHAIN (arglist);
4736   if (! arglist)
4737     return 0;
4738   fmt = TREE_VALUE (arglist);
4739   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4740     return 0;
4741   arglist = TREE_CHAIN (arglist);
4742
4743   /* Check whether the format is a literal string constant.  */
4744   fmt_str = c_getstr (fmt);
4745   if (fmt_str == NULL)
4746     return 0;
4747
4748   /* If the format specifier was "%s", call __builtin_fputs(arg,fp).  */
4749   if (strcmp (fmt_str, "%s") == 0)
4750     {
4751       if (! arglist
4752           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
4753           || TREE_CHAIN (arglist))
4754         return 0;
4755       arg = TREE_VALUE (arglist);
4756       arglist = build_tree_list (NULL_TREE, fp);
4757       arglist = tree_cons (NULL_TREE, arg, arglist);
4758       fn = fn_fputs;
4759     }
4760   /* If the format specifier was "%c", call __builtin_fputc(arg,fp).  */
4761   else if (strcmp (fmt_str, "%c") == 0)
4762     {
4763       if (! arglist
4764           || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
4765           || TREE_CHAIN (arglist))
4766         return 0;
4767       arg = TREE_VALUE (arglist);
4768       arglist = build_tree_list (NULL_TREE, fp);
4769       arglist = tree_cons (NULL_TREE, arg, arglist);
4770       fn = fn_fputc;
4771     }
4772   else
4773     {
4774       /* We can't handle anything else with % args or %% ... yet.  */
4775       if (strchr (fmt_str, '%'))
4776         return 0;
4777
4778       if (arglist)
4779         return 0;
4780
4781       /* If the format specifier was "", fprintf does nothing.  */
4782       if (fmt_str[0] == '\0')
4783         {
4784           /* Evaluate and ignore FILE* argument for side-effects.  */
4785           expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
4786           return const0_rtx;
4787         }
4788
4789       /* When "string" doesn't contain %, replace all cases of
4790          fprintf(stream,string) with fputs(string,stream).  The fputs
4791          builtin will take care of special cases like length == 1.  */
4792       arglist = build_tree_list (NULL_TREE, fp);
4793       arglist = tree_cons (NULL_TREE, fmt, arglist);
4794       fn = fn_fputs;
4795     }
4796
4797   if (!fn)
4798     return 0;
4799   return expand_expr (build_function_call_expr (fn, arglist),
4800                       target, mode, EXPAND_NORMAL);
4801 }
4802
4803 /* Expand a call to sprintf with argument list ARGLIST.  Return 0 if
4804    a normal call should be emitted rather than expanding the function
4805    inline.  If convenient, the result should be placed in TARGET with
4806    mode MODE.  */
4807
4808 static rtx
4809 expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
4810 {
4811   tree orig_arglist, dest, fmt;
4812   const char *fmt_str;
4813
4814   orig_arglist = arglist;
4815
4816   /* Verify the required arguments in the original call.  */
4817   if (! arglist)
4818     return 0;
4819   dest = TREE_VALUE (arglist);
4820   if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
4821     return 0;
4822   arglist = TREE_CHAIN (arglist);
4823   if (! arglist)
4824     return 0;
4825   fmt = TREE_VALUE (arglist);
4826   if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
4827     return 0;
4828   arglist = TREE_CHAIN (arglist);
4829
4830   /* Check whether the format is a literal string constant.  */
4831   fmt_str = c_getstr (fmt);
4832   if (fmt_str == NULL)
4833     return 0;
4834
4835   /* If the format doesn't contain % args or %%, use strcpy.  */
4836   if (strchr (fmt_str, '%') == 0)
4837     {
4838       tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4839       tree exp;
4840
4841       if (arglist || ! fn)
4842         return 0;
4843       expand_expr (build_function_call_expr (fn, orig_arglist),
4844                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4845       if (target == const0_rtx)
4846         return const0_rtx;
4847       exp = build_int_2 (strlen (fmt_str), 0);
4848       exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
4849       return expand_expr (exp, target, mode, EXPAND_NORMAL);
4850     }
4851   /* If the format is "%s", use strcpy if the result isn't used.  */
4852   else if (strcmp (fmt_str, "%s") == 0)
4853     {
4854       tree fn, arg, len;
4855       fn = implicit_built_in_decls[BUILT_IN_STRCPY];
4856
4857       if (! fn)
4858         return 0;
4859
4860       if (! arglist || TREE_CHAIN (arglist))
4861         return 0;
4862       arg = TREE_VALUE (arglist);
4863       if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
4864         return 0;
4865
4866       if (target != const0_rtx)
4867         {
4868           len = c_strlen (arg, 1);
4869           if (! len || TREE_CODE (len) != INTEGER_CST)
4870             return 0;
4871         }
4872       else
4873         len = NULL_TREE;
4874
4875       arglist = build_tree_list (NULL_TREE, arg);
4876       arglist = tree_cons (NULL_TREE, dest, arglist);
4877       expand_expr (build_function_call_expr (fn, arglist),
4878                    const0_rtx, VOIDmode, EXPAND_NORMAL);
4879
4880       if (target == const0_rtx)
4881         return const0_rtx;
4882       return expand_expr (len, target, mode, EXPAND_NORMAL);
4883     }
4884
4885   return 0;
4886 }
4887 \f
4888 /* Expand an expression EXP that calls a built-in function,
4889    with result going to TARGET if that's convenient
4890    (and in mode MODE if that's convenient).
4891    SUBTARGET may be used as the target for computing one of EXP's operands.
4892    IGNORE is nonzero if the value is to be ignored.  */
4893
4894 rtx
4895 expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
4896                 int ignore)
4897 {
4898   tree fndecl = get_callee_fndecl (exp);
4899   tree arglist = TREE_OPERAND (exp, 1);
4900   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
4901   enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
4902
4903   /* Perform postincrements before expanding builtin functions.  */
4904   emit_queue ();
4905
4906   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
4907     return (*targetm.expand_builtin) (exp, target, subtarget, mode, ignore);
4908
4909   /* When not optimizing, generate calls to library functions for a certain
4910      set of builtins.  */
4911   if (!optimize
4912       && !CALLED_AS_BUILT_IN (fndecl)
4913       && DECL_ASSEMBLER_NAME_SET_P (fndecl)
4914       && fcode != BUILT_IN_ALLOCA)
4915     return expand_call (exp, target, ignore);
4916
4917   /* The built-in function expanders test for target == const0_rtx
4918      to determine whether the function's result will be ignored.  */
4919   if (ignore)
4920     target = const0_rtx;
4921
4922   /* If the result of a pure or const built-in function is ignored, and
4923      none of its arguments are volatile, we can avoid expanding the
4924      built-in call and just evaluate the arguments for side-effects.  */
4925   if (target == const0_rtx
4926       && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
4927     {
4928       bool volatilep = false;
4929       tree arg;
4930
4931       for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4932         if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
4933           {
4934             volatilep = true;
4935             break;
4936           }
4937
4938       if (! volatilep)
4939         {
4940           for (arg = arglist; arg; arg = TREE_CHAIN (arg))
4941             expand_expr (TREE_VALUE (arg), const0_rtx,
4942                          VOIDmode, EXPAND_NORMAL);
4943           return const0_rtx;
4944         }
4945     }
4946
4947   switch (fcode)
4948     {
4949     case BUILT_IN_ABS:
4950     case BUILT_IN_LABS:
4951     case BUILT_IN_LLABS:
4952     case BUILT_IN_IMAXABS:
4953       /* build_function_call changes these into ABS_EXPR.  */
4954       abort ();
4955
4956     case BUILT_IN_FABS:
4957     case BUILT_IN_FABSF:
4958     case BUILT_IN_FABSL:
4959       target = expand_builtin_fabs (arglist, target, subtarget);
4960       if (target)
4961         return target;
4962       break;
4963
4964     case BUILT_IN_CABS:
4965     case BUILT_IN_CABSF:
4966     case BUILT_IN_CABSL:
4967       if (flag_unsafe_math_optimizations)
4968         {
4969           target = expand_builtin_cabs (arglist, target);
4970           if (target)
4971             return target;
4972         }
4973       break;
4974
4975     case BUILT_IN_CONJ:
4976     case BUILT_IN_CONJF:
4977     case BUILT_IN_CONJL:
4978     case BUILT_IN_CREAL:
4979     case BUILT_IN_CREALF:
4980     case BUILT_IN_CREALL:
4981     case BUILT_IN_CIMAG:
4982     case BUILT_IN_CIMAGF:
4983     case BUILT_IN_CIMAGL:
4984       /* expand_tree_builtin changes these into CONJ_EXPR, REALPART_EXPR
4985          and IMAGPART_EXPR.  */
4986       abort ();
4987
4988     case BUILT_IN_SIN:
4989     case BUILT_IN_SINF:
4990     case BUILT_IN_SINL:
4991     case BUILT_IN_COS:
4992     case BUILT_IN_COSF:
4993     case BUILT_IN_COSL:
4994     case BUILT_IN_EXP:
4995     case BUILT_IN_EXPF:
4996     case BUILT_IN_EXPL:
4997     case BUILT_IN_LOG:
4998     case BUILT_IN_LOGF:
4999     case BUILT_IN_LOGL:
5000     case BUILT_IN_TAN:
5001     case BUILT_IN_TANF:
5002     case BUILT_IN_TANL:
5003     case BUILT_IN_ATAN:
5004     case BUILT_IN_ATANF:
5005     case BUILT_IN_ATANL:
5006       /* Treat these like sqrt only if unsafe math optimizations are allowed,
5007          because of possible accuracy problems.  */
5008       if (! flag_unsafe_math_optimizations)
5009         break;
5010     case BUILT_IN_SQRT:
5011     case BUILT_IN_SQRTF:
5012     case BUILT_IN_SQRTL:
5013     case BUILT_IN_FLOOR:
5014     case BUILT_IN_FLOORF:
5015     case BUILT_IN_FLOORL:
5016     case BUILT_IN_CEIL:
5017     case BUILT_IN_CEILF:
5018     case BUILT_IN_CEILL:
5019     case BUILT_IN_TRUNC:
5020     case BUILT_IN_TRUNCF:
5021     case BUILT_IN_TRUNCL:
5022     case BUILT_IN_ROUND:
5023     case BUILT_IN_ROUNDF:
5024     case BUILT_IN_ROUNDL:
5025     case BUILT_IN_NEARBYINT:
5026     case BUILT_IN_NEARBYINTF:
5027     case BUILT_IN_NEARBYINTL:
5028       target = expand_builtin_mathfn (exp, target, subtarget);
5029       if (target)
5030         return target;
5031       break;
5032
5033     case BUILT_IN_POW:
5034     case BUILT_IN_POWF:
5035     case BUILT_IN_POWL:
5036       if (! flag_unsafe_math_optimizations)
5037         break;
5038       target = expand_builtin_pow (exp, target, subtarget);
5039       if (target)
5040         return target;
5041       break;
5042
5043     case BUILT_IN_ATAN2:
5044     case BUILT_IN_ATAN2F:
5045     case BUILT_IN_ATAN2L:
5046       if (! flag_unsafe_math_optimizations)
5047         break;
5048       target = expand_builtin_mathfn_2 (exp, target, subtarget);
5049       if (target)
5050         return target;
5051       break;
5052
5053     case BUILT_IN_APPLY_ARGS:
5054       return expand_builtin_apply_args ();
5055
5056       /* __builtin_apply (FUNCTION, ARGUMENTS, ARGSIZE) invokes
5057          FUNCTION with a copy of the parameters described by
5058          ARGUMENTS, and ARGSIZE.  It returns a block of memory
5059          allocated on the stack into which is stored all the registers
5060          that might possibly be used for returning the result of a
5061          function.  ARGUMENTS is the value returned by
5062          __builtin_apply_args.  ARGSIZE is the number of bytes of
5063          arguments that must be copied.  ??? How should this value be
5064          computed?  We'll also need a safe worst case value for varargs
5065          functions.  */
5066     case BUILT_IN_APPLY:
5067       if (!validate_arglist (arglist, POINTER_TYPE,
5068                              POINTER_TYPE, INTEGER_TYPE, VOID_TYPE)
5069           && !validate_arglist (arglist, REFERENCE_TYPE,
5070                                 POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5071         return const0_rtx;
5072       else
5073         {
5074           int i;
5075           tree t;
5076           rtx ops[3];
5077
5078           for (t = arglist, i = 0; t; t = TREE_CHAIN (t), i++)
5079             ops[i] = expand_expr (TREE_VALUE (t), NULL_RTX, VOIDmode, 0);
5080
5081           return expand_builtin_apply (ops[0], ops[1], ops[2]);
5082         }
5083
5084       /* __builtin_return (RESULT) causes the function to return the
5085          value described by RESULT.  RESULT is address of the block of
5086          memory returned by __builtin_apply.  */
5087     case BUILT_IN_RETURN:
5088       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5089         expand_builtin_return (expand_expr (TREE_VALUE (arglist),
5090                                             NULL_RTX, VOIDmode, 0));
5091       return const0_rtx;
5092
5093     case BUILT_IN_SAVEREGS:
5094       return expand_builtin_saveregs ();
5095
5096     case BUILT_IN_ARGS_INFO:
5097       return expand_builtin_args_info (arglist);
5098
5099       /* Return the address of the first anonymous stack arg.  */
5100     case BUILT_IN_NEXT_ARG:
5101       return expand_builtin_next_arg (arglist);
5102
5103     case BUILT_IN_CLASSIFY_TYPE:
5104       return expand_builtin_classify_type (arglist);
5105
5106     case BUILT_IN_CONSTANT_P:
5107       return expand_builtin_constant_p (arglist, target_mode);
5108
5109     case BUILT_IN_FRAME_ADDRESS:
5110     case BUILT_IN_RETURN_ADDRESS:
5111       return expand_builtin_frame_address (fndecl, arglist);
5112
5113     /* Returns the address of the area where the structure is returned.
5114        0 otherwise.  */
5115     case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
5116       if (arglist != 0
5117           || ! AGGREGATE_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
5118           || GET_CODE (DECL_RTL (DECL_RESULT (current_function_decl))) != MEM)
5119         return const0_rtx;
5120       else
5121         return XEXP (DECL_RTL (DECL_RESULT (current_function_decl)), 0);
5122
5123     case BUILT_IN_ALLOCA:
5124       target = expand_builtin_alloca (arglist, target);
5125       if (target)
5126         return target;
5127       break;
5128
5129     case BUILT_IN_FFS:
5130     case BUILT_IN_FFSL:
5131     case BUILT_IN_FFSLL:
5132       target = expand_builtin_unop (target_mode, arglist, target,
5133                                     subtarget, ffs_optab);
5134       if (target)
5135         return target;
5136       break;
5137
5138     case BUILT_IN_CLZ:
5139     case BUILT_IN_CLZL:
5140     case BUILT_IN_CLZLL:
5141       target = expand_builtin_unop (target_mode, arglist, target,
5142                                     subtarget, clz_optab);
5143       if (target)
5144         return target;
5145       break;
5146
5147     case BUILT_IN_CTZ:
5148     case BUILT_IN_CTZL:
5149     case BUILT_IN_CTZLL:
5150       target = expand_builtin_unop (target_mode, arglist, target,
5151                                     subtarget, ctz_optab);
5152       if (target)
5153         return target;
5154       break;
5155
5156     case BUILT_IN_POPCOUNT:
5157     case BUILT_IN_POPCOUNTL:
5158     case BUILT_IN_POPCOUNTLL:
5159       target = expand_builtin_unop (target_mode, arglist, target,
5160                                     subtarget, popcount_optab);
5161       if (target)
5162         return target;
5163       break;
5164
5165     case BUILT_IN_PARITY:
5166     case BUILT_IN_PARITYL:
5167     case BUILT_IN_PARITYLL:
5168       target = expand_builtin_unop (target_mode, arglist, target,
5169                                     subtarget, parity_optab);
5170       if (target)
5171         return target;
5172       break;
5173
5174     case BUILT_IN_STRLEN:
5175       target = expand_builtin_strlen (arglist, target, target_mode);
5176       if (target)
5177         return target;
5178       break;
5179
5180     case BUILT_IN_STRCPY:
5181       target = expand_builtin_strcpy (arglist, target, mode);
5182       if (target)
5183         return target;
5184       break;
5185
5186     case BUILT_IN_STRNCPY:
5187       target = expand_builtin_strncpy (arglist, target, mode);
5188       if (target)
5189         return target;
5190       break;
5191
5192     case BUILT_IN_STPCPY:
5193       target = expand_builtin_stpcpy (arglist, target, mode);
5194       if (target)
5195         return target;
5196       break;
5197
5198     case BUILT_IN_STRCAT:
5199       target = expand_builtin_strcat (arglist, target, mode);
5200       if (target)
5201         return target;
5202       break;
5203
5204     case BUILT_IN_STRNCAT:
5205       target = expand_builtin_strncat (arglist, target, mode);
5206       if (target)
5207         return target;
5208       break;
5209
5210     case BUILT_IN_STRSPN:
5211       target = expand_builtin_strspn (arglist, target, mode);
5212       if (target)
5213         return target;
5214       break;
5215
5216     case BUILT_IN_STRCSPN:
5217       target = expand_builtin_strcspn (arglist, target, mode);
5218       if (target)
5219         return target;
5220       break;
5221
5222     case BUILT_IN_STRSTR:
5223       target = expand_builtin_strstr (arglist, target, mode);
5224       if (target)
5225         return target;
5226       break;
5227
5228     case BUILT_IN_STRPBRK:
5229       target = expand_builtin_strpbrk (arglist, target, mode);
5230       if (target)
5231         return target;
5232       break;
5233
5234     case BUILT_IN_INDEX:
5235     case BUILT_IN_STRCHR:
5236       target = expand_builtin_strchr (arglist, target, mode);
5237       if (target)
5238         return target;
5239       break;
5240
5241     case BUILT_IN_RINDEX:
5242     case BUILT_IN_STRRCHR:
5243       target = expand_builtin_strrchr (arglist, target, mode);
5244       if (target)
5245         return target;
5246       break;
5247
5248     case BUILT_IN_MEMCPY:
5249       target = expand_builtin_memcpy (arglist, target, mode);
5250       if (target)
5251         return target;
5252       break;
5253
5254     case BUILT_IN_MEMPCPY:
5255       target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
5256       if (target)
5257         return target;
5258       break;
5259
5260     case BUILT_IN_MEMMOVE:
5261       target = expand_builtin_memmove (arglist, target, mode);
5262       if (target)
5263         return target;
5264       break;
5265
5266     case BUILT_IN_BCOPY:
5267       target = expand_builtin_bcopy (arglist);
5268       if (target)
5269         return target;
5270       break;
5271
5272     case BUILT_IN_MEMSET:
5273       target = expand_builtin_memset (arglist, target, mode);
5274       if (target)
5275         return target;
5276       break;
5277
5278     case BUILT_IN_BZERO:
5279       target = expand_builtin_bzero (arglist);
5280       if (target)
5281         return target;
5282       break;
5283
5284     case BUILT_IN_STRCMP:
5285       target = expand_builtin_strcmp (exp, target, mode);
5286       if (target)
5287         return target;
5288       break;
5289
5290     case BUILT_IN_STRNCMP:
5291       target = expand_builtin_strncmp (exp, target, mode);
5292       if (target)
5293         return target;
5294       break;
5295
5296     case BUILT_IN_BCMP:
5297     case BUILT_IN_MEMCMP:
5298       target = expand_builtin_memcmp (exp, arglist, target, mode);
5299       if (target)
5300         return target;
5301       break;
5302
5303     case BUILT_IN_SETJMP:
5304       target = expand_builtin_setjmp (arglist, target);
5305       if (target)
5306         return target;
5307       break;
5308
5309       /* __builtin_longjmp is passed a pointer to an array of five words.
5310          It's similar to the C library longjmp function but works with
5311          __builtin_setjmp above.  */
5312     case BUILT_IN_LONGJMP:
5313       if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
5314         break;
5315       else
5316         {
5317           rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
5318                                       VOIDmode, 0);
5319           rtx value = expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
5320                                    NULL_RTX, VOIDmode, 0);
5321
5322           if (value != const1_rtx)
5323             {
5324               error ("__builtin_longjmp second argument must be 1");
5325               return const0_rtx;
5326             }
5327
5328           expand_builtin_longjmp (buf_addr, value);
5329           return const0_rtx;
5330         }
5331
5332     case BUILT_IN_TRAP:
5333       expand_builtin_trap ();
5334       return const0_rtx;
5335
5336     case BUILT_IN_PRINTF:
5337       target = expand_builtin_printf (arglist, target, mode, false);
5338       if (target)
5339         return target;
5340       break;
5341
5342     case BUILT_IN_PRINTF_UNLOCKED:
5343       target = expand_builtin_printf (arglist, target, mode, true);
5344       if (target)
5345         return target;
5346       break;
5347
5348     case BUILT_IN_FPUTS:
5349       target = expand_builtin_fputs (arglist, target, false);
5350       if (target)
5351         return target;
5352       break;
5353
5354     case BUILT_IN_FPUTS_UNLOCKED:
5355       target = expand_builtin_fputs (arglist, target, true);
5356       if (target)
5357         return target;
5358       break;
5359
5360     case BUILT_IN_FPRINTF:
5361       target = expand_builtin_fprintf (arglist, target, mode, false);
5362       if (target)
5363         return target;
5364       break;
5365
5366     case BUILT_IN_FPRINTF_UNLOCKED:
5367       target = expand_builtin_fprintf (arglist, target, mode, true);
5368       if (target)
5369         return target;
5370       break;
5371
5372     case BUILT_IN_SPRINTF:
5373       target = expand_builtin_sprintf (arglist, target, mode);
5374       if (target)
5375         return target;
5376       break;
5377
5378       /* Various hooks for the DWARF 2 __throw routine.  */
5379     case BUILT_IN_UNWIND_INIT:
5380       expand_builtin_unwind_init ();
5381       return const0_rtx;
5382     case BUILT_IN_DWARF_CFA:
5383       return virtual_cfa_rtx;
5384 #ifdef DWARF2_UNWIND_INFO
5385     case BUILT_IN_DWARF_SP_COLUMN:
5386       return expand_builtin_dwarf_sp_column ();
5387     case BUILT_IN_INIT_DWARF_REG_SIZES:
5388       expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
5389       return const0_rtx;
5390 #endif
5391     case BUILT_IN_FROB_RETURN_ADDR:
5392       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
5393     case BUILT_IN_EXTRACT_RETURN_ADDR:
5394       return expand_builtin_extract_return_addr (TREE_VALUE (arglist));
5395     case BUILT_IN_EH_RETURN:
5396       expand_builtin_eh_return (TREE_VALUE (arglist),
5397                                 TREE_VALUE (TREE_CHAIN (arglist)));
5398       return const0_rtx;
5399 #ifdef EH_RETURN_DATA_REGNO
5400     case BUILT_IN_EH_RETURN_DATA_REGNO:
5401       return expand_builtin_eh_return_data_regno (arglist);
5402 #endif
5403     case BUILT_IN_VA_START:
5404     case BUILT_IN_STDARG_START:
5405       return expand_builtin_va_start (arglist);
5406     case BUILT_IN_VA_END:
5407       return expand_builtin_va_end (arglist);
5408     case BUILT_IN_VA_COPY:
5409       return expand_builtin_va_copy (arglist);
5410     case BUILT_IN_EXPECT:
5411       return expand_builtin_expect (arglist, target);
5412     case BUILT_IN_PREFETCH:
5413       expand_builtin_prefetch (arglist);
5414       return const0_rtx;
5415
5416
5417     default:    /* just do library call, if unknown builtin */
5418       if (!DECL_ASSEMBLER_NAME_SET_P (fndecl))
5419         error ("built-in function `%s' not currently supported",
5420                IDENTIFIER_POINTER (DECL_NAME (fndecl)));
5421     }
5422
5423   /* The switch statement above can drop through to cause the function
5424      to be called normally.  */
5425   return expand_call (exp, target, ignore);
5426 }
5427
5428 /* Determine whether a tree node represents a call to a built-in
5429    function.  If the tree T is a call to a built-in function with
5430    the right number of arguments of the appropriate types, return
5431    the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
5432    Otherwise the return value is END_BUILTINS.  */
5433
5434 enum built_in_function
5435 builtin_mathfn_code (tree t)
5436 {
5437   tree fndecl, arglist, parmlist;
5438   tree argtype, parmtype;
5439
5440   if (TREE_CODE (t) != CALL_EXPR
5441       || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
5442     return END_BUILTINS;
5443
5444   fndecl = get_callee_fndecl (t);
5445   if (fndecl == NULL_TREE
5446       || TREE_CODE (fndecl) != FUNCTION_DECL
5447       || ! DECL_BUILT_IN (fndecl)
5448       || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
5449     return END_BUILTINS;
5450
5451   arglist = TREE_OPERAND (t, 1);
5452   parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
5453   for (; parmlist; parmlist = TREE_CHAIN (parmlist))
5454     {
5455       /* If a function doesn't take a variable number of arguments,
5456          the last element in the list will have type `void'.  */
5457       parmtype = TREE_VALUE (parmlist);
5458       if (VOID_TYPE_P (parmtype))
5459         {
5460           if (arglist)
5461             return END_BUILTINS;
5462           return DECL_FUNCTION_CODE (fndecl);
5463         }
5464
5465       if (! arglist)
5466         return END_BUILTINS;
5467
5468       argtype = TREE_TYPE (TREE_VALUE (arglist));
5469
5470       if (SCALAR_FLOAT_TYPE_P (parmtype))
5471         {
5472           if (! SCALAR_FLOAT_TYPE_P (argtype))
5473             return END_BUILTINS;
5474         }
5475       else if (COMPLEX_FLOAT_TYPE_P (parmtype))
5476         {
5477           if (! COMPLEX_FLOAT_TYPE_P (argtype))
5478             return END_BUILTINS;
5479         }
5480       else if (POINTER_TYPE_P (parmtype))
5481         {
5482           if (! POINTER_TYPE_P (argtype))
5483             return END_BUILTINS;
5484         }
5485       else if (INTEGRAL_TYPE_P (parmtype))
5486         {
5487           if (! INTEGRAL_TYPE_P (argtype))
5488             return END_BUILTINS;
5489         }
5490       else
5491         return END_BUILTINS;
5492
5493       arglist = TREE_CHAIN (arglist);
5494     }
5495
5496   /* Variable-length argument list.  */
5497   return DECL_FUNCTION_CODE (fndecl);
5498 }
5499
5500 /* Fold a call to __builtin_constant_p, if we know it will evaluate to a
5501    constant.  ARGLIST is the argument list of the call.  */
5502
5503 static tree
5504 fold_builtin_constant_p (tree arglist)
5505 {
5506   if (arglist == 0)
5507     return 0;
5508
5509   arglist = TREE_VALUE (arglist);
5510
5511   /* We return 1 for a numeric type that's known to be a constant
5512      value at compile-time or for an aggregate type that's a
5513      literal constant.  */
5514   STRIP_NOPS (arglist);
5515
5516   /* If we know this is a constant, emit the constant of one.  */
5517   if (TREE_CODE_CLASS (TREE_CODE (arglist)) == 'c'
5518       || (TREE_CODE (arglist) == CONSTRUCTOR
5519           && TREE_CONSTANT (arglist))
5520       || (TREE_CODE (arglist) == ADDR_EXPR
5521           && TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
5522     return integer_one_node;
5523
5524   /* If this expression has side effects, show we don't know it to be a
5525      constant.  Likewise if it's a pointer or aggregate type since in
5526      those case we only want literals, since those are only optimized
5527      when generating RTL, not later.
5528      And finally, if we are compiling an initializer, not code, we
5529      need to return a definite result now; there's not going to be any
5530      more optimization done.  */
5531   if (TREE_SIDE_EFFECTS (arglist)
5532       || AGGREGATE_TYPE_P (TREE_TYPE (arglist))
5533       || POINTER_TYPE_P (TREE_TYPE (arglist))
5534       || cfun == 0)
5535     return integer_zero_node;
5536
5537   return 0;
5538 }
5539
5540 /* Fold a call to __builtin_classify_type.  */
5541
5542 static tree
5543 fold_builtin_classify_type (tree arglist)
5544 {
5545   if (arglist == 0)
5546     return build_int_2 (no_type_class, 0);
5547
5548   return build_int_2 (type_to_class (TREE_TYPE (TREE_VALUE (arglist))), 0);
5549 }
5550
5551 /* Fold a call to __builtin_inf or __builtin_huge_val.  */
5552
5553 static tree
5554 fold_builtin_inf (tree type, int warn)
5555 {
5556   REAL_VALUE_TYPE real;
5557
5558   if (!MODE_HAS_INFINITIES (TYPE_MODE (type)) && warn)
5559     warning ("target format does not support infinity");
5560
5561   real_inf (&real);
5562   return build_real (type, real);
5563 }
5564
5565 /* Fold a call to __builtin_nan or __builtin_nans.  */
5566
5567 static tree
5568 fold_builtin_nan (tree arglist, tree type, int quiet)
5569 {
5570   REAL_VALUE_TYPE real;
5571   const char *str;
5572
5573   if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
5574     return 0;
5575   str = c_getstr (TREE_VALUE (arglist));
5576   if (!str)
5577     return 0;
5578
5579   if (!real_nan (&real, str, quiet, TYPE_MODE (type)))
5580     return 0;
5581
5582   return build_real (type, real);
5583 }
5584
5585 /* Return true if the floating point expression T has an integer value.
5586    We also allow +Inf, -Inf and NaN to be considered integer values.  */
5587
5588 static bool
5589 integer_valued_real_p (tree t)
5590 {
5591   switch (TREE_CODE (t))
5592     {
5593     case FLOAT_EXPR:
5594       return true;
5595
5596     case ABS_EXPR:
5597     case SAVE_EXPR:
5598     case NON_LVALUE_EXPR:
5599       return integer_valued_real_p (TREE_OPERAND (t, 0));
5600
5601     case COMPOUND_EXPR:
5602     case MODIFY_EXPR:
5603     case BIND_EXPR:
5604       return integer_valued_real_p (TREE_OPERAND (t, 1));
5605
5606     case PLUS_EXPR:
5607     case MINUS_EXPR:
5608     case MULT_EXPR:
5609     case MIN_EXPR:
5610     case MAX_EXPR:
5611       return integer_valued_real_p (TREE_OPERAND (t, 0))
5612              && integer_valued_real_p (TREE_OPERAND (t, 1));
5613
5614     case COND_EXPR:
5615       return integer_valued_real_p (TREE_OPERAND (t, 1))
5616              && integer_valued_real_p (TREE_OPERAND (t, 2));
5617
5618     case REAL_CST:
5619       if (! TREE_CONSTANT_OVERFLOW (t))
5620       {
5621         REAL_VALUE_TYPE c, cint;
5622
5623         c = TREE_REAL_CST (t);
5624         real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
5625         return real_identical (&c, &cint);
5626       }
5627
5628     case NOP_EXPR:
5629       {
5630         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
5631         if (TREE_CODE (type) == INTEGER_TYPE)
5632           return true;
5633         if (TREE_CODE (type) == REAL_TYPE)
5634           return integer_valued_real_p (TREE_OPERAND (t, 0));
5635         break;
5636       }
5637
5638     case CALL_EXPR:
5639       switch (builtin_mathfn_code (t))
5640         {
5641         case BUILT_IN_CEIL:
5642         case BUILT_IN_CEILF:
5643         case BUILT_IN_CEILL:
5644         case BUILT_IN_FLOOR:
5645         case BUILT_IN_FLOORF:
5646         case BUILT_IN_FLOORL:
5647         case BUILT_IN_NEARBYINT:
5648         case BUILT_IN_NEARBYINTF:
5649         case BUILT_IN_NEARBYINTL:
5650         case BUILT_IN_ROUND:
5651         case BUILT_IN_ROUNDF:
5652         case BUILT_IN_ROUNDL:
5653         case BUILT_IN_TRUNC:
5654         case BUILT_IN_TRUNCF:
5655         case BUILT_IN_TRUNCL:
5656           return true;
5657
5658         default:
5659           break;
5660         }
5661       break;
5662
5663     default:
5664       break;
5665     }
5666   return false;
5667 }
5668
5669 /* EXP is assumed to be builtin call where truncation can be propagated
5670    across (for instance floor((double)f) == (double)floorf (f).
5671    Do the transformation.  */
5672
5673 static tree
5674 fold_trunc_transparent_mathfn (tree exp)
5675 {
5676   tree fndecl = get_callee_fndecl (exp);
5677   tree arglist = TREE_OPERAND (exp, 1);
5678   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
5679   tree arg;
5680
5681   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5682     return 0;
5683
5684   arg = TREE_VALUE (arglist);
5685   /* Integer rounding functions are idempotent.  */
5686   if (fcode == builtin_mathfn_code (arg))
5687     return arg;
5688
5689   /* If argument is already integer valued, and we don't need to worry
5690      about setting errno, there's no need to perform rounding.  */
5691   if (! flag_errno_math && integer_valued_real_p (arg))
5692     return arg;
5693
5694   if (optimize)
5695     {
5696       tree arg0 = strip_float_extensions (arg);
5697       tree ftype = TREE_TYPE (exp);
5698       tree newtype = TREE_TYPE (arg0);
5699       tree decl;
5700
5701       if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
5702           && (decl = mathfn_built_in (newtype, fcode)))
5703         {
5704           arglist =
5705             build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
5706           return convert (ftype,
5707                           build_function_call_expr (decl, arglist));
5708         }
5709     }
5710   return 0;
5711 }
5712
5713 /* Fold function call to builtin cabs, cabsf or cabsl.  FNDECL is the
5714    function's DECL, ARGLIST is the argument list and TYPE is the return
5715    type.  Return NULL_TREE if no simplification can be made.  */
5716
5717 static tree
5718 fold_builtin_cabs (tree fndecl, tree arglist, tree type)
5719 {
5720   tree arg;
5721
5722   if (!arglist || TREE_CHAIN (arglist))
5723     return NULL_TREE;
5724
5725   arg = TREE_VALUE (arglist);
5726   if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
5727       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
5728     return NULL_TREE;
5729
5730   /* Evaluate cabs of a constant at compile-time.  */
5731   if (flag_unsafe_math_optimizations
5732       && TREE_CODE (arg) == COMPLEX_CST
5733       && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
5734       && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
5735       && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
5736       && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
5737     {
5738       REAL_VALUE_TYPE r, i;
5739
5740       r = TREE_REAL_CST (TREE_REALPART (arg));
5741       i = TREE_REAL_CST (TREE_IMAGPART (arg));
5742
5743       real_arithmetic (&r, MULT_EXPR, &r, &r);
5744       real_arithmetic (&i, MULT_EXPR, &i, &i);
5745       real_arithmetic (&r, PLUS_EXPR, &r, &i);
5746       if (real_sqrt (&r, TYPE_MODE (type), &r)
5747           || ! flag_trapping_math)
5748         return build_real (type, r);
5749     }
5750
5751   /* If either part is zero, cabs is fabs of the other.  */
5752   if (TREE_CODE (arg) == COMPLEX_EXPR
5753       && real_zerop (TREE_OPERAND (arg, 0)))
5754     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
5755   if (TREE_CODE (arg) == COMPLEX_EXPR
5756       && real_zerop (TREE_OPERAND (arg, 1)))
5757     return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
5758
5759   if (flag_unsafe_math_optimizations)
5760     {
5761       enum built_in_function fcode;
5762       tree sqrtfn;
5763
5764       fcode = DECL_FUNCTION_CODE (fndecl);
5765       if (fcode == BUILT_IN_CABS)
5766         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
5767       else if (fcode == BUILT_IN_CABSF)
5768         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
5769       else if (fcode == BUILT_IN_CABSL)
5770         sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
5771       else
5772         sqrtfn = NULL_TREE;
5773
5774       if (sqrtfn != NULL_TREE)
5775         {
5776           tree rpart, ipart, result, arglist;
5777
5778           arg = save_expr (arg);
5779
5780           rpart = fold (build1 (REALPART_EXPR, type, arg));
5781           ipart = fold (build1 (IMAGPART_EXPR, type, arg));
5782
5783           rpart = save_expr (rpart);
5784           ipart = save_expr (ipart);
5785
5786           result = fold (build (PLUS_EXPR, type,
5787                                 fold (build (MULT_EXPR, type,
5788                                              rpart, rpart)),
5789                                 fold (build (MULT_EXPR, type,
5790                                              ipart, ipart))));
5791
5792           arglist = build_tree_list (NULL_TREE, result);
5793           return build_function_call_expr (sqrtfn, arglist);
5794         }
5795     }
5796
5797   return NULL_TREE;
5798 }
5799
5800 /* Fold function call to builtin trunc, truncf or truncl.  Return
5801    NULL_TREE if no simplification can be made.  */
5802
5803 static tree
5804 fold_builtin_trunc (tree exp)
5805 {
5806   tree arglist = TREE_OPERAND (exp, 1);
5807   tree arg;
5808
5809   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5810     return 0;
5811
5812   /* Optimize trunc of constant value.  */
5813   arg = TREE_VALUE (arglist);
5814   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5815     {
5816       REAL_VALUE_TYPE r, x;
5817       tree type = TREE_TYPE (exp);
5818
5819       x = TREE_REAL_CST (arg);
5820       real_trunc (&r, TYPE_MODE (type), &x);
5821       return build_real (type, r);
5822     }
5823
5824   return fold_trunc_transparent_mathfn (exp);
5825 }
5826
5827 /* Fold function call to builtin floor, floorf or floorl.  Return
5828    NULL_TREE if no simplification can be made.  */
5829
5830 static tree
5831 fold_builtin_floor (tree exp)
5832 {
5833   tree arglist = TREE_OPERAND (exp, 1);
5834   tree arg;
5835
5836   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5837     return 0;
5838
5839   /* Optimize floor of constant value.  */
5840   arg = TREE_VALUE (arglist);
5841   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5842     {
5843       REAL_VALUE_TYPE x;
5844
5845       x = TREE_REAL_CST (arg);
5846       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5847         {
5848           tree type = TREE_TYPE (exp);
5849           REAL_VALUE_TYPE r;
5850
5851           real_floor (&r, TYPE_MODE (type), &x);
5852           return build_real (type, r);
5853         }
5854     }
5855
5856   return fold_trunc_transparent_mathfn (exp);
5857 }
5858
5859 /* Fold function call to builtin ceil, ceilf or ceill.  Return
5860    NULL_TREE if no simplification can be made.  */
5861
5862 static tree
5863 fold_builtin_ceil (tree exp)
5864 {
5865   tree arglist = TREE_OPERAND (exp, 1);
5866   tree arg;
5867
5868   if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
5869     return 0;
5870
5871   /* Optimize ceil of constant value.  */
5872   arg = TREE_VALUE (arglist);
5873   if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5874     {
5875       REAL_VALUE_TYPE x;
5876
5877       x = TREE_REAL_CST (arg);
5878       if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
5879         {
5880           tree type = TREE_TYPE (exp);
5881           REAL_VALUE_TYPE r;
5882
5883           real_ceil (&r, TYPE_MODE (type), &x);
5884           return build_real (type, r);
5885         }
5886     }
5887
5888   return fold_trunc_transparent_mathfn (exp);
5889 }
5890
5891 /* Fold function call to builtin ffs, clz, ctz, popcount and parity
5892    and their long and long long variants (i.e. ffsl and ffsll).
5893    Return NULL_TREE if no simplification can be made.  */
5894
5895 static tree
5896 fold_builtin_bitop (tree exp)
5897 {
5898   tree fndecl = get_callee_fndecl (exp);
5899   tree arglist = TREE_OPERAND (exp, 1);
5900   tree arg;
5901
5902   if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
5903     return NULL_TREE;
5904
5905   /* Optimize for constant argument.  */
5906   arg = TREE_VALUE (arglist);
5907   if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
5908     {
5909       HOST_WIDE_INT hi, width, result;
5910       unsigned HOST_WIDE_INT lo;
5911       tree type, t;
5912
5913       type = TREE_TYPE (arg);
5914       width = TYPE_PRECISION (type);
5915       lo = TREE_INT_CST_LOW (arg);
5916
5917       /* Clear all the bits that are beyond the type's precision.  */
5918       if (width > HOST_BITS_PER_WIDE_INT)
5919         {
5920           hi = TREE_INT_CST_HIGH (arg);
5921           if (width < 2 * HOST_BITS_PER_WIDE_INT)
5922             hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
5923         }
5924       else
5925         {
5926           hi = 0;
5927           if (width < HOST_BITS_PER_WIDE_INT)
5928             lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
5929         }
5930
5931       switch (DECL_FUNCTION_CODE (fndecl))
5932         {
5933         case BUILT_IN_FFS:
5934         case BUILT_IN_FFSL:
5935         case BUILT_IN_FFSLL:
5936           if (lo != 0)
5937             result = exact_log2 (lo & -lo) + 1;
5938           else if (hi != 0)
5939             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
5940           else
5941             result = 0;
5942           break;
5943
5944         case BUILT_IN_CLZ:
5945         case BUILT_IN_CLZL:
5946         case BUILT_IN_CLZLL:
5947           if (hi != 0)
5948             result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
5949           else if (lo != 0)
5950             result = width - floor_log2 (lo) - 1;
5951           else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5952             result = width;
5953           break;
5954
5955         case BUILT_IN_CTZ:
5956         case BUILT_IN_CTZL:
5957         case BUILT_IN_CTZLL:
5958           if (lo != 0)
5959             result = exact_log2 (lo & -lo);
5960           else if (hi != 0)
5961             result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
5962           else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
5963             result = width;
5964           break;
5965
5966         case BUILT_IN_POPCOUNT:
5967         case BUILT_IN_POPCOUNTL:
5968         case BUILT_IN_POPCOUNTLL:
5969           result = 0;
5970           while (lo)
5971             result++, lo &= lo - 1;
5972           while (hi)
5973             result++, hi &= hi - 1;
5974           break;
5975
5976         case BUILT_IN_PARITY:
5977         case BUILT_IN_PARITYL:
5978         case BUILT_IN_PARITYLL:
5979           result = 0;
5980           while (lo)
5981             result++, lo &= lo - 1;
5982           while (hi)
5983             result++, hi &= hi - 1;
5984           result &= 1;
5985           break;
5986
5987         default:
5988           abort();
5989         }
5990
5991       t = build_int_2 (result, 0);
5992       TREE_TYPE (t) = TREE_TYPE (exp);
5993       return t;
5994     }
5995
5996   return NULL_TREE;
5997 }
5998
5999 /* Return true if EXPR is the real constant contained in VALUE.  */
6000
6001 static bool
6002 real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
6003 {
6004   STRIP_NOPS (expr);
6005
6006   return ((TREE_CODE (expr) == REAL_CST
6007            && ! TREE_CONSTANT_OVERFLOW (expr)
6008            && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
6009           || (TREE_CODE (expr) == COMPLEX_CST
6010               && real_dconstp (TREE_REALPART (expr), value)
6011               && real_zerop (TREE_IMAGPART (expr))));
6012 }
6013
6014 /* A subroutine of fold_builtin to fold the various logarithmic
6015    functions.  EXP is the CALL_EXPR of a call to a builtin log*
6016    function.  VALUE is the base of the log* function.  */
6017
6018 static tree
6019 fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
6020 {
6021   tree arglist = TREE_OPERAND (exp, 1);
6022
6023   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6024     {
6025       tree fndecl = get_callee_fndecl (exp);
6026       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6027       tree arg = TREE_VALUE (arglist);
6028       const enum built_in_function fcode = builtin_mathfn_code (arg);
6029         
6030       /* Optimize log*(1.0) = 0.0.  */
6031       if (real_onep (arg))
6032         return build_real (type, dconst0);
6033
6034       /* Optimize logN(N) = 1.0.  If N can't be truncated to MODE
6035          exactly, then only do this if flag_unsafe_math_optimizations.  */
6036       if (exact_real_truncate (TYPE_MODE (type), value)
6037           || flag_unsafe_math_optimizations)
6038         {
6039           const REAL_VALUE_TYPE value_truncate =
6040             real_value_truncate (TYPE_MODE (type), *value);
6041           if (real_dconstp (arg, &value_truncate))
6042             return build_real (type, dconst1);
6043         }
6044       
6045       /* Special case, optimize logN(expN(x)) = x.  */
6046       if (flag_unsafe_math_optimizations
6047           && ((value == &dconste
6048                && (fcode == BUILT_IN_EXP
6049                    || fcode == BUILT_IN_EXPF
6050                    || fcode == BUILT_IN_EXPL))
6051               || (value == &dconst2
6052                   && (fcode == BUILT_IN_EXP2
6053                       || fcode == BUILT_IN_EXP2F
6054                       || fcode == BUILT_IN_EXP2L))
6055               || (value == &dconst10
6056                   && (fcode == BUILT_IN_EXP10
6057                       || fcode == BUILT_IN_EXP10F
6058                       || fcode == BUILT_IN_EXP10L))))
6059         return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6060
6061       /* Optimize log*(func()) for various exponential functions.  We
6062          want to determine the value "x" and the power "exponent" in
6063          order to transform logN(x**exponent) into exponent*logN(x).  */
6064       if (flag_unsafe_math_optimizations)
6065         {
6066           tree exponent = 0, x = 0;
6067           
6068           switch (fcode)
6069           {
6070           case BUILT_IN_EXP:
6071           case BUILT_IN_EXPF:
6072           case BUILT_IN_EXPL:
6073             /* Prepare to do logN(exp(exponent) -> exponent*logN(e).  */
6074             x = build_real (type,
6075                             real_value_truncate (TYPE_MODE (type), dconste));
6076             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6077             break;
6078           case BUILT_IN_EXP2:
6079           case BUILT_IN_EXP2F:
6080           case BUILT_IN_EXP2L:
6081             /* Prepare to do logN(exp2(exponent) -> exponent*logN(2).  */
6082             x = build_real (type, dconst2);
6083             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6084             break;
6085           case BUILT_IN_EXP10:
6086           case BUILT_IN_EXP10F:
6087           case BUILT_IN_EXP10L:
6088           case BUILT_IN_POW10:
6089           case BUILT_IN_POW10F:
6090           case BUILT_IN_POW10L:
6091             /* Prepare to do logN(exp10(exponent) -> exponent*logN(10).  */
6092             x = build_real (type, dconst10);
6093             exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
6094             break;
6095           case BUILT_IN_SQRT:
6096           case BUILT_IN_SQRTF:
6097           case BUILT_IN_SQRTL:
6098             /* Prepare to do logN(sqrt(x) -> 0.5*logN(x).  */
6099             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6100             exponent = build_real (type, dconsthalf);
6101             break;
6102           case BUILT_IN_CBRT:
6103           case BUILT_IN_CBRTF:
6104           case BUILT_IN_CBRTL:
6105             /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x).  */
6106             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6107             exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
6108                                                               dconstthird));
6109             break;
6110           case BUILT_IN_POW:
6111           case BUILT_IN_POWF:
6112           case BUILT_IN_POWL:
6113             /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x).  */
6114             x = TREE_VALUE (TREE_OPERAND (arg, 1));
6115             exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6116             break;
6117           default:
6118             break;
6119           }
6120
6121           /* Now perform the optimization.  */
6122           if (x && exponent)
6123             {
6124               tree logfn;
6125               arglist = build_tree_list (NULL_TREE, x);
6126               logfn = build_function_call_expr (fndecl, arglist);
6127               return fold (build (MULT_EXPR, type, exponent, logfn));
6128             }
6129         }
6130     }
6131
6132   return 0;
6133 }
6134           
6135 /* A subroutine of fold_builtin to fold the various exponent
6136    functions.  EXP is the CALL_EXPR of a call to a builtin function.
6137    VALUE is the value which will be raised to a power.  */
6138
6139 static tree
6140 fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
6141 {
6142   tree arglist = TREE_OPERAND (exp, 1);
6143
6144   if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6145     {
6146       tree fndecl = get_callee_fndecl (exp);
6147       tree type = TREE_TYPE (TREE_TYPE (fndecl));
6148       tree arg = TREE_VALUE (arglist);
6149
6150       /* Optimize exp*(0.0) = 1.0.  */
6151       if (real_zerop (arg))
6152         return build_real (type, dconst1);
6153
6154       /* Optimize expN(1.0) = N.  */
6155       if (real_onep (arg))
6156         {
6157           REAL_VALUE_TYPE cst;
6158
6159           real_convert (&cst, TYPE_MODE (type), value);
6160           return build_real (type, cst);
6161         }
6162
6163       /* Attempt to evaluate expN(integer) at compile-time.  */
6164       if (flag_unsafe_math_optimizations
6165           && TREE_CODE (arg) == REAL_CST
6166           && ! TREE_CONSTANT_OVERFLOW (arg))
6167         {
6168           REAL_VALUE_TYPE cint;
6169           REAL_VALUE_TYPE c;
6170           HOST_WIDE_INT n;
6171
6172           c = TREE_REAL_CST (arg);
6173           n = real_to_integer (&c);
6174           real_from_integer (&cint, VOIDmode, n,
6175                              n < 0 ? -1 : 0, 0);
6176           if (real_identical (&c, &cint))
6177             {
6178               REAL_VALUE_TYPE x;
6179
6180               real_powi (&x, TYPE_MODE (type), value, n);
6181               return build_real (type, x);
6182             }
6183         }
6184
6185       /* Optimize expN(logN(x)) = x.  */
6186       if (flag_unsafe_math_optimizations)
6187         {
6188           const enum built_in_function fcode = builtin_mathfn_code (arg);
6189
6190           if ((value == &dconste
6191                && (fcode == BUILT_IN_LOG
6192                    || fcode == BUILT_IN_LOGF
6193                    || fcode == BUILT_IN_LOGL))
6194               || (value == &dconst2
6195                   && (fcode == BUILT_IN_LOG2
6196                       || fcode == BUILT_IN_LOG2F
6197                       || fcode == BUILT_IN_LOG2L))
6198               || (value == &dconst10
6199                   && (fcode == BUILT_IN_LOG10
6200                       || fcode == BUILT_IN_LOG10F
6201                       || fcode == BUILT_IN_LOG10L)))
6202             return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
6203         }
6204     }
6205
6206   return 0;
6207 }
6208
6209 /* Fold function call to builtin memcpy.  Return
6210    NULL_TREE if no simplification can be made.  */
6211
6212 static tree
6213 fold_builtin_memcpy (tree exp)
6214 {
6215   tree arglist = TREE_OPERAND (exp, 1);
6216   tree dest, src, len;
6217
6218   if (!validate_arglist (arglist,
6219                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6220     return 0;
6221
6222   dest = TREE_VALUE (arglist);
6223   src = TREE_VALUE (TREE_CHAIN (arglist));
6224   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6225
6226   /* If the LEN parameter is zero, return DEST.  */
6227   if (integer_zerop (len))
6228     return omit_one_operand (TREE_TYPE (exp), dest, src);
6229
6230   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6231   if (operand_equal_p (src, dest, 0))
6232     return omit_one_operand (TREE_TYPE (exp), dest, len);
6233
6234   return 0;
6235 }
6236
6237 /* Fold function call to builtin mempcpy.  Return
6238    NULL_TREE if no simplification can be made.  */
6239
6240 static tree
6241 fold_builtin_mempcpy (tree exp)
6242 {
6243   tree arglist = TREE_OPERAND (exp, 1);
6244   tree dest, src, len;
6245
6246   if (!validate_arglist (arglist,
6247                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6248     return 0;
6249
6250   dest = TREE_VALUE (arglist);
6251   src = TREE_VALUE (TREE_CHAIN (arglist));
6252   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6253
6254   /* If the LEN parameter is zero, return DEST.  */
6255   if (integer_zerop (len))
6256     return omit_one_operand (TREE_TYPE (exp), dest, src);
6257
6258   /* If SRC and DEST are the same (and not volatile), return DEST+LEN.  */
6259   if (operand_equal_p (src, dest, 0))
6260     {
6261       tree temp = convert (TREE_TYPE (dest), len);
6262       temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
6263       return convert (TREE_TYPE (exp), temp);
6264     }
6265
6266   return 0;
6267 }
6268
6269 /* Fold function call to builtin memmove.  Return
6270    NULL_TREE if no simplification can be made.  */
6271
6272 static tree
6273 fold_builtin_memmove (tree exp)
6274 {
6275   tree arglist = TREE_OPERAND (exp, 1);
6276   tree dest, src, len;
6277
6278   if (!validate_arglist (arglist,
6279                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6280     return 0;
6281
6282   dest = TREE_VALUE (arglist);
6283   src = TREE_VALUE (TREE_CHAIN (arglist));
6284   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6285
6286   /* If the LEN parameter is zero, return DEST.  */
6287   if (integer_zerop (len))
6288     return omit_one_operand (TREE_TYPE (exp), dest, src);
6289
6290   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6291   if (operand_equal_p (src, dest, 0))
6292     return omit_one_operand (TREE_TYPE (exp), dest, len);
6293
6294   return 0;
6295 }
6296
6297 /* Fold function call to builtin strcpy.  Return
6298    NULL_TREE if no simplification can be made.  */
6299
6300 static tree
6301 fold_builtin_strcpy (tree exp)
6302 {
6303   tree arglist = TREE_OPERAND (exp, 1);
6304   tree dest, src;
6305
6306   if (!validate_arglist (arglist,
6307                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6308     return 0;
6309
6310   dest = TREE_VALUE (arglist);
6311   src = TREE_VALUE (TREE_CHAIN (arglist));
6312
6313   /* If SRC and DEST are the same (and not volatile), return DEST.  */
6314   if (operand_equal_p (src, dest, 0))
6315     return convert (TREE_TYPE (exp), dest);
6316
6317   return 0;
6318 }
6319
6320 /* Fold function call to builtin strncpy.  Return
6321    NULL_TREE if no simplification can be made.  */
6322
6323 static tree
6324 fold_builtin_strncpy (tree exp)
6325 {
6326   tree arglist = TREE_OPERAND (exp, 1);
6327   tree dest, src, len;
6328
6329   if (!validate_arglist (arglist,
6330                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6331     return 0;
6332
6333   dest = TREE_VALUE (arglist);
6334   src = TREE_VALUE (TREE_CHAIN (arglist));
6335   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6336
6337   /* If the LEN parameter is zero, return DEST.  */
6338   if (integer_zerop (len))
6339     return omit_one_operand (TREE_TYPE (exp), dest, src);
6340
6341   return 0;
6342 }
6343
6344 /* Fold function call to builtin memcmp.  Return
6345    NULL_TREE if no simplification can be made.  */
6346
6347 static tree
6348 fold_builtin_memcmp (tree exp)
6349 {
6350   tree arglist = TREE_OPERAND (exp, 1);
6351   tree arg1, arg2, len;
6352
6353   if (!validate_arglist (arglist,
6354                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6355     return 0;
6356
6357   arg1 = TREE_VALUE (arglist);
6358   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6359   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6360
6361   /* If the LEN parameter is zero, return zero.  */
6362   if (integer_zerop (len))
6363     {
6364       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6365       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6366     }
6367
6368   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6369   if (operand_equal_p (arg1, arg2, 0))
6370     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6371
6372   return 0;
6373 }
6374
6375 /* Fold function call to builtin strcmp.  Return
6376    NULL_TREE if no simplification can be made.  */
6377
6378 static tree
6379 fold_builtin_strcmp (tree exp)
6380 {
6381   tree arglist = TREE_OPERAND (exp, 1);
6382   tree arg1, arg2;
6383   const char *p1, *p2;
6384
6385   if (!validate_arglist (arglist,
6386                          POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
6387     return 0;
6388
6389   arg1 = TREE_VALUE (arglist);
6390   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6391
6392   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6393   if (operand_equal_p (arg1, arg2, 0))
6394     return convert (TREE_TYPE (exp), integer_zero_node);
6395
6396   p1 = c_getstr (arg1);
6397   p2 = c_getstr (arg2);
6398
6399   if (p1 && p2)
6400     {
6401       tree temp;
6402       const int i = strcmp (p1, p2);
6403       if (i < 0)
6404         temp = integer_minus_one_node;
6405       else if (i > 0)
6406         temp = integer_one_node;
6407       else
6408         temp = integer_zero_node;
6409       return convert (TREE_TYPE (exp), temp);
6410     }
6411
6412   return 0;
6413 }
6414
6415 /* Fold function call to builtin strncmp.  Return
6416    NULL_TREE if no simplification can be made.  */
6417
6418 static tree
6419 fold_builtin_strncmp (tree exp)
6420 {
6421   tree arglist = TREE_OPERAND (exp, 1);
6422   tree arg1, arg2, len;
6423   const char *p1, *p2;
6424
6425   if (!validate_arglist (arglist,
6426                          POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
6427     return 0;
6428
6429   arg1 = TREE_VALUE (arglist);
6430   arg2 = TREE_VALUE (TREE_CHAIN (arglist));
6431   len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
6432
6433   /* If the LEN parameter is zero, return zero.  */
6434   if (integer_zerop (len))
6435     {
6436       tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
6437       return omit_one_operand (TREE_TYPE (exp), temp, arg1);
6438     }
6439
6440   /* If ARG1 and ARG2 are the same (and not volatile), return zero.  */
6441   if (operand_equal_p (arg1, arg2, 0))
6442     return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
6443
6444   p1 = c_getstr (arg1);
6445   p2 = c_getstr (arg2);
6446
6447   if (host_integerp (len, 1) && p1 && p2)
6448     {
6449       tree temp;
6450       const int i = strncmp (p1, p2, tree_low_cst (len, 1));
6451       if (i < 0)
6452         temp = integer_minus_one_node;
6453       else if (i > 0)
6454         temp = integer_one_node;
6455       else
6456         temp = integer_zero_node;
6457       return convert (TREE_TYPE (exp), temp);
6458     }
6459
6460   return 0;
6461 }
6462
6463 /* Used by constant folding to eliminate some builtin calls early.  EXP is
6464    the CALL_EXPR of a call to a builtin function.  */
6465
6466 tree
6467 fold_builtin (tree exp)
6468 {
6469   tree fndecl = get_callee_fndecl (exp);
6470   tree arglist = TREE_OPERAND (exp, 1);
6471   tree type = TREE_TYPE (TREE_TYPE (fndecl));
6472
6473   if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
6474     return 0;
6475
6476   switch (DECL_FUNCTION_CODE (fndecl))
6477     {
6478     case BUILT_IN_CONSTANT_P:
6479       return fold_builtin_constant_p (arglist);
6480
6481     case BUILT_IN_CLASSIFY_TYPE:
6482       return fold_builtin_classify_type (arglist);
6483
6484     case BUILT_IN_STRLEN:
6485       if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
6486         {
6487           tree len = c_strlen (TREE_VALUE (arglist), 0);
6488           if (len)
6489             {
6490               /* Convert from the internal "sizetype" type to "size_t".  */
6491               if (size_type_node)
6492                 len = convert (size_type_node, len);
6493               return len;
6494             }
6495         }
6496       break;
6497
6498     case BUILT_IN_FABS:
6499     case BUILT_IN_FABSF:
6500     case BUILT_IN_FABSL:
6501       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6502         return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
6503       break;
6504
6505     case BUILT_IN_CABS:
6506     case BUILT_IN_CABSF:
6507     case BUILT_IN_CABSL:
6508       return fold_builtin_cabs (fndecl, arglist, type);
6509
6510     case BUILT_IN_SQRT:
6511     case BUILT_IN_SQRTF:
6512     case BUILT_IN_SQRTL:
6513       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6514         {
6515           enum built_in_function fcode;
6516           tree arg = TREE_VALUE (arglist);
6517
6518           /* Optimize sqrt of constant value.  */
6519           if (TREE_CODE (arg) == REAL_CST
6520               && ! TREE_CONSTANT_OVERFLOW (arg))
6521             {
6522               REAL_VALUE_TYPE r, x;
6523
6524               x = TREE_REAL_CST (arg);
6525               if (real_sqrt (&r, TYPE_MODE (type), &x)
6526                   || (!flag_trapping_math && !flag_errno_math))
6527                 return build_real (type, r);
6528             }
6529
6530           /* Optimize sqrt(exp(x)) = exp(x*0.5).  */
6531           fcode = builtin_mathfn_code (arg);
6532           if (flag_unsafe_math_optimizations
6533               && (fcode == BUILT_IN_EXP
6534                   || fcode == BUILT_IN_EXPF
6535                   || fcode == BUILT_IN_EXPL))
6536             {
6537               tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6538               arg = fold (build (MULT_EXPR, type,
6539                                  TREE_VALUE (TREE_OPERAND (arg, 1)),
6540                                  build_real (type, dconsthalf)));
6541               arglist = build_tree_list (NULL_TREE, arg);
6542               return build_function_call_expr (expfn, arglist);
6543             }
6544
6545           /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5).  */
6546           if (flag_unsafe_math_optimizations
6547               && (fcode == BUILT_IN_POW
6548                   || fcode == BUILT_IN_POWF
6549                   || fcode == BUILT_IN_POWL))
6550             {
6551               tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
6552               tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
6553               tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
6554               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6555                                         build_real (type, dconsthalf)));
6556               arglist = tree_cons (NULL_TREE, arg0,
6557                                    build_tree_list (NULL_TREE, narg1));
6558               return build_function_call_expr (powfn, arglist);
6559             }
6560         }
6561       break;
6562
6563     case BUILT_IN_SIN:
6564     case BUILT_IN_SINF:
6565     case BUILT_IN_SINL:
6566       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6567         {
6568           tree arg = TREE_VALUE (arglist);
6569
6570           /* Optimize sin(0.0) = 0.0.  */
6571           if (real_zerop (arg))
6572             return arg;
6573         }
6574       break;
6575
6576     case BUILT_IN_COS:
6577     case BUILT_IN_COSF:
6578     case BUILT_IN_COSL:
6579       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6580         {
6581           tree arg = TREE_VALUE (arglist);
6582
6583           /* Optimize cos(0.0) = 1.0.  */
6584           if (real_zerop (arg))
6585             return build_real (type, dconst1);
6586
6587           /* Optimize cos(-x) into cos(x).  */
6588           if (TREE_CODE (arg) == NEGATE_EXPR)
6589             {
6590               tree arglist = build_tree_list (NULL_TREE,
6591                                               TREE_OPERAND (arg, 0));
6592               return build_function_call_expr (fndecl, arglist);
6593             }
6594         }
6595       break;
6596
6597     case BUILT_IN_EXP:
6598     case BUILT_IN_EXPF:
6599     case BUILT_IN_EXPL:
6600       return fold_builtin_exponent (exp, &dconste);
6601     case BUILT_IN_EXP2:
6602     case BUILT_IN_EXP2F:
6603     case BUILT_IN_EXP2L:
6604       return fold_builtin_exponent (exp, &dconst2);
6605     case BUILT_IN_EXP10:
6606     case BUILT_IN_EXP10F:
6607     case BUILT_IN_EXP10L:
6608     case BUILT_IN_POW10:
6609     case BUILT_IN_POW10F:
6610     case BUILT_IN_POW10L:
6611       return fold_builtin_exponent (exp, &dconst10);
6612     case BUILT_IN_LOG:
6613     case BUILT_IN_LOGF:
6614     case BUILT_IN_LOGL:
6615       return fold_builtin_logarithm (exp, &dconste);
6616       break;
6617     case BUILT_IN_LOG2:
6618     case BUILT_IN_LOG2F:
6619     case BUILT_IN_LOG2L:
6620       return fold_builtin_logarithm (exp, &dconst2);
6621       break;
6622     case BUILT_IN_LOG10:
6623     case BUILT_IN_LOG10F:
6624     case BUILT_IN_LOG10L:
6625       return fold_builtin_logarithm (exp, &dconst10);
6626       break;
6627
6628     case BUILT_IN_TAN:
6629     case BUILT_IN_TANF:
6630     case BUILT_IN_TANL:
6631       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6632         {
6633           enum built_in_function fcode;
6634           tree arg = TREE_VALUE (arglist);
6635
6636           /* Optimize tan(0.0) = 0.0.  */
6637           if (real_zerop (arg))
6638             return arg;
6639
6640           /* Optimize tan(atan(x)) = x.  */
6641           fcode = builtin_mathfn_code (arg);
6642           if (flag_unsafe_math_optimizations
6643               && (fcode == BUILT_IN_ATAN
6644                   || fcode == BUILT_IN_ATANF
6645                   || fcode == BUILT_IN_ATANL))
6646             return TREE_VALUE (TREE_OPERAND (arg, 1));
6647         }
6648       break;
6649
6650     case BUILT_IN_ATAN:
6651     case BUILT_IN_ATANF:
6652     case BUILT_IN_ATANL:
6653       if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
6654         {
6655           tree arg = TREE_VALUE (arglist);
6656
6657           /* Optimize atan(0.0) = 0.0.  */
6658           if (real_zerop (arg))
6659             return arg;
6660
6661           /* Optimize atan(1.0) = pi/4.  */
6662           if (real_onep (arg))
6663             {
6664               REAL_VALUE_TYPE cst;
6665
6666               real_convert (&cst, TYPE_MODE (type), &dconstpi);
6667               cst.exp -= 2;
6668               return build_real (type, cst);
6669             }
6670         }
6671       break;
6672
6673     case BUILT_IN_POW:
6674     case BUILT_IN_POWF:
6675     case BUILT_IN_POWL:
6676       if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
6677         {
6678           enum built_in_function fcode;
6679           tree arg0 = TREE_VALUE (arglist);
6680           tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6681
6682           /* Optimize pow(1.0,y) = 1.0.  */
6683           if (real_onep (arg0))
6684             return omit_one_operand (type, build_real (type, dconst1), arg1);
6685
6686           if (TREE_CODE (arg1) == REAL_CST
6687               && ! TREE_CONSTANT_OVERFLOW (arg1))
6688             {
6689               REAL_VALUE_TYPE c;
6690               c = TREE_REAL_CST (arg1);
6691
6692               /* Optimize pow(x,0.0) = 1.0.  */
6693               if (REAL_VALUES_EQUAL (c, dconst0))
6694                 return omit_one_operand (type, build_real (type, dconst1),
6695                                          arg0);
6696
6697               /* Optimize pow(x,1.0) = x.  */
6698               if (REAL_VALUES_EQUAL (c, dconst1))
6699                 return arg0;
6700
6701               /* Optimize pow(x,-1.0) = 1.0/x.  */
6702               if (REAL_VALUES_EQUAL (c, dconstm1))
6703                 return fold (build (RDIV_EXPR, type,
6704                                     build_real (type, dconst1),
6705                                     arg0));
6706
6707               /* Optimize pow(x,0.5) = sqrt(x).  */
6708               if (flag_unsafe_math_optimizations
6709                   && REAL_VALUES_EQUAL (c, dconsthalf))
6710                 {
6711                   tree sqrtfn;
6712
6713                   fcode = DECL_FUNCTION_CODE (fndecl);
6714                   if (fcode == BUILT_IN_POW)
6715                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
6716                   else if (fcode == BUILT_IN_POWF)
6717                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
6718                   else if (fcode == BUILT_IN_POWL)
6719                     sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
6720                   else
6721                     sqrtfn = NULL_TREE;
6722
6723                   if (sqrtfn != NULL_TREE)
6724                     {
6725                       tree arglist = build_tree_list (NULL_TREE, arg0);
6726                       return build_function_call_expr (sqrtfn, arglist);
6727                     }
6728                 }
6729
6730               /* Attempt to evaluate pow at compile-time.  */
6731               if (TREE_CODE (arg0) == REAL_CST
6732                   && ! TREE_CONSTANT_OVERFLOW (arg0))
6733                 {
6734                   REAL_VALUE_TYPE cint;
6735                   HOST_WIDE_INT n;
6736
6737                   n = real_to_integer (&c);
6738                   real_from_integer (&cint, VOIDmode, n,
6739                                      n < 0 ? -1 : 0, 0);
6740                   if (real_identical (&c, &cint))
6741                     {
6742                       REAL_VALUE_TYPE x;
6743                       bool inexact;
6744
6745                       x = TREE_REAL_CST (arg0);
6746                       inexact = real_powi (&x, TYPE_MODE (type), &x, n);
6747                       if (flag_unsafe_math_optimizations || !inexact)
6748                         return build_real (type, x);
6749                     }
6750                 }
6751             }
6752
6753           /* Optimize pow(exp(x),y) = exp(x*y).  */
6754           fcode = builtin_mathfn_code (arg0);
6755           if (flag_unsafe_math_optimizations
6756               && (fcode == BUILT_IN_EXP
6757                   || fcode == BUILT_IN_EXPF
6758                   || fcode == BUILT_IN_EXPL))
6759             {
6760               tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
6761               tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
6762               arg = fold (build (MULT_EXPR, type, arg, arg1));
6763               arglist = build_tree_list (NULL_TREE, arg);
6764               return build_function_call_expr (expfn, arglist);
6765             }
6766
6767           /* Optimize pow(sqrt(x),y) = pow(x,y*0.5).  */
6768           if (flag_unsafe_math_optimizations
6769               && (fcode == BUILT_IN_SQRT
6770                   || fcode == BUILT_IN_SQRTF
6771                   || fcode == BUILT_IN_SQRTL))
6772             {
6773               tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6774               tree narg1 = fold (build (MULT_EXPR, type, arg1,
6775                                         build_real (type, dconsthalf)));
6776
6777               arglist = tree_cons (NULL_TREE, narg0,
6778                                    build_tree_list (NULL_TREE, narg1));
6779               return build_function_call_expr (fndecl, arglist);
6780             }
6781
6782           /* Optimize pow(pow(x,y),z) = pow(x,y*z).  */
6783           if (flag_unsafe_math_optimizations
6784               && (fcode == BUILT_IN_POW
6785                   || fcode == BUILT_IN_POWF
6786                   || fcode == BUILT_IN_POWL))
6787             {
6788               tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
6789               tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
6790               tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
6791               arglist = tree_cons (NULL_TREE, arg00,
6792                                    build_tree_list (NULL_TREE, narg1));
6793               return build_function_call_expr (fndecl, arglist);
6794             }
6795         }
6796       break;
6797
6798     case BUILT_IN_INF:
6799     case BUILT_IN_INFF:
6800     case BUILT_IN_INFL:
6801       return fold_builtin_inf (type, true);
6802
6803     case BUILT_IN_HUGE_VAL:
6804     case BUILT_IN_HUGE_VALF:
6805     case BUILT_IN_HUGE_VALL:
6806       return fold_builtin_inf (type, false);
6807
6808     case BUILT_IN_NAN:
6809     case BUILT_IN_NANF:
6810     case BUILT_IN_NANL:
6811       return fold_builtin_nan (arglist, type, true);
6812
6813     case BUILT_IN_NANS:
6814     case BUILT_IN_NANSF:
6815     case BUILT_IN_NANSL:
6816       return fold_builtin_nan (arglist, type, false);
6817
6818     case BUILT_IN_FLOOR:
6819     case BUILT_IN_FLOORF:
6820     case BUILT_IN_FLOORL:
6821       return fold_builtin_floor (exp);
6822
6823     case BUILT_IN_CEIL:
6824     case BUILT_IN_CEILF:
6825     case BUILT_IN_CEILL:
6826       return fold_builtin_ceil (exp);
6827
6828     case BUILT_IN_TRUNC:
6829     case BUILT_IN_TRUNCF:
6830     case BUILT_IN_TRUNCL:
6831       return fold_builtin_trunc (exp);
6832
6833     case BUILT_IN_ROUND:
6834     case BUILT_IN_ROUNDF:
6835     case BUILT_IN_ROUNDL:
6836     case BUILT_IN_NEARBYINT:
6837     case BUILT_IN_NEARBYINTF:
6838     case BUILT_IN_NEARBYINTL:
6839       return fold_trunc_transparent_mathfn (exp);
6840
6841     case BUILT_IN_FFS:
6842     case BUILT_IN_FFSL:
6843     case BUILT_IN_FFSLL:
6844     case BUILT_IN_CLZ:
6845     case BUILT_IN_CLZL:
6846     case BUILT_IN_CLZLL:
6847     case BUILT_IN_CTZ:
6848     case BUILT_IN_CTZL:
6849     case BUILT_IN_CTZLL:
6850     case BUILT_IN_POPCOUNT:
6851     case BUILT_IN_POPCOUNTL:
6852     case BUILT_IN_POPCOUNTLL:
6853     case BUILT_IN_PARITY:
6854     case BUILT_IN_PARITYL:
6855     case BUILT_IN_PARITYLL:
6856       return fold_builtin_bitop (exp);
6857
6858     case BUILT_IN_MEMCPY:
6859       return fold_builtin_memcpy (exp);
6860
6861     case BUILT_IN_MEMPCPY:
6862       return fold_builtin_mempcpy (exp);
6863
6864     case BUILT_IN_MEMMOVE:
6865       return fold_builtin_memmove (exp);
6866
6867     case BUILT_IN_STRCPY:
6868       return fold_builtin_strcpy (exp);
6869
6870     case BUILT_IN_STRNCPY:
6871       return fold_builtin_strncpy (exp);
6872
6873     case BUILT_IN_MEMCMP:
6874       return fold_builtin_memcmp (exp);
6875
6876     case BUILT_IN_STRCMP:
6877       return fold_builtin_strcmp (exp);
6878
6879     case BUILT_IN_STRNCMP:
6880       return fold_builtin_strncmp (exp);
6881
6882     default:
6883       break;
6884     }
6885
6886   return 0;
6887 }
6888
6889 /* Conveniently construct a function call expression.  */
6890
6891 tree
6892 build_function_call_expr (tree fn, tree arglist)
6893 {
6894   tree call_expr;
6895
6896   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
6897   call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
6898                      call_expr, arglist);
6899   return fold (call_expr);
6900 }
6901
6902 /* This function validates the types of a function call argument list
6903    represented as a tree chain of parameters against a specified list
6904    of tree_codes.  If the last specifier is a 0, that represents an
6905    ellipses, otherwise the last specifier must be a VOID_TYPE.  */
6906
6907 static int
6908 validate_arglist (tree arglist, ...)
6909 {
6910   enum tree_code code;
6911   int res = 0;
6912   va_list ap;
6913
6914   va_start (ap, arglist);
6915
6916   do
6917     {
6918       code = va_arg (ap, enum tree_code);
6919       switch (code)
6920         {
6921         case 0:
6922           /* This signifies an ellipses, any further arguments are all ok.  */
6923           res = 1;
6924           goto end;
6925         case VOID_TYPE:
6926           /* This signifies an endlink, if no arguments remain, return
6927              true, otherwise return false.  */
6928           res = arglist == 0;
6929           goto end;
6930         default:
6931           /* If no parameters remain or the parameter's code does not
6932              match the specified code, return false.  Otherwise continue
6933              checking any remaining arguments.  */
6934           if (arglist == 0
6935               || code != TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))))
6936             goto end;
6937           break;
6938         }
6939       arglist = TREE_CHAIN (arglist);
6940     }
6941   while (1);
6942
6943   /* We need gotos here since we can only have one VA_CLOSE in a
6944      function.  */
6945  end: ;
6946   va_end (ap);
6947
6948   return res;
6949 }
6950
6951 /* Default target-specific builtin expander that does nothing.  */
6952
6953 rtx
6954 default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
6955                         rtx target ATTRIBUTE_UNUSED,
6956                         rtx subtarget ATTRIBUTE_UNUSED,
6957                         enum machine_mode mode ATTRIBUTE_UNUSED,
6958                         int ignore ATTRIBUTE_UNUSED)
6959 {
6960   return NULL_RTX;
6961 }
6962
6963 /* Instantiate all remaining CONSTANT_P_RTX nodes.  */
6964
6965 void
6966 purge_builtin_constant_p (void)
6967 {
6968   rtx insn, set, arg, new, note;
6969
6970   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6971     if (INSN_P (insn)
6972         && (set = single_set (insn)) != NULL_RTX
6973         && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
6974             || (GET_CODE (arg) == SUBREG
6975                 && (GET_CODE (arg = SUBREG_REG (arg))
6976                     == CONSTANT_P_RTX))))
6977       {
6978         arg = XEXP (arg, 0);
6979         new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
6980         validate_change (insn, &SET_SRC (set), new, 0);
6981
6982         /* Remove the REG_EQUAL note from the insn.  */
6983         if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
6984           remove_note (insn, note);
6985       }
6986 }
6987
6988 /* Returns true is EXP represents data that would potentially reside
6989    in a readonly section.  */
6990
6991 static bool
6992 readonly_data_expr (tree exp)
6993 {
6994   STRIP_NOPS (exp);
6995
6996   if (TREE_CODE (exp) == ADDR_EXPR)
6997     return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
6998   else
6999     return false;
7000 }