OSDN Git Service

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