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