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