OSDN Git Service

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